@liveblocks/node-lexical 1.12.0-lexical4 → 2.0.0-alpha2
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.d.mts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +68 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { Liveblocks } from '@liveblocks/node';
|
|
2
|
-
import { Klass, LexicalNode, LexicalNodeReplacement, EditorState,
|
|
2
|
+
import { Klass, LexicalNode, LexicalNodeReplacement, EditorState, LexicalEditor, SerializedEditorState, SerializedLexicalNode } from 'lexical';
|
|
3
3
|
export { $createParagraphNode, $createTextNode, $getRoot } from 'lexical';
|
|
4
4
|
|
|
5
|
-
declare
|
|
6
|
-
|
|
5
|
+
declare type LiveblocksLexicalOptions = {
|
|
6
|
+
roomId: string;
|
|
7
|
+
nodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;
|
|
8
|
+
client: Liveblocks;
|
|
9
|
+
};
|
|
10
|
+
declare type LiveblocksDocumentApi = {
|
|
11
|
+
refresh: () => Promise<void>;
|
|
12
|
+
update: (modifyFn: () => void) => Promise<void>;
|
|
13
|
+
getTextContent: () => string;
|
|
14
|
+
getEditorState: () => EditorState;
|
|
15
|
+
getLexicalEditor: () => LexicalEditor;
|
|
16
|
+
toJSON: () => SerializedEditorState<SerializedLexicalNode>;
|
|
17
|
+
toMarkdown: () => string;
|
|
18
|
+
};
|
|
19
|
+
declare function withLexicalDocument<T>({ roomId, nodes, client }: LiveblocksLexicalOptions, callback: (api: LiveblocksDocumentApi) => Promise<T> | T): Promise<T>;
|
|
7
20
|
|
|
8
|
-
export {
|
|
21
|
+
export { type LiveblocksDocumentApi, type LiveblocksLexicalOptions, withLexicalDocument };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { Liveblocks } from '@liveblocks/node';
|
|
2
|
-
import { Klass, LexicalNode, LexicalNodeReplacement, EditorState,
|
|
2
|
+
import { Klass, LexicalNode, LexicalNodeReplacement, EditorState, LexicalEditor, SerializedEditorState, SerializedLexicalNode } from 'lexical';
|
|
3
3
|
export { $createParagraphNode, $createTextNode, $getRoot } from 'lexical';
|
|
4
4
|
|
|
5
|
-
declare
|
|
6
|
-
|
|
5
|
+
declare type LiveblocksLexicalOptions = {
|
|
6
|
+
roomId: string;
|
|
7
|
+
nodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;
|
|
8
|
+
client: Liveblocks;
|
|
9
|
+
};
|
|
10
|
+
declare type LiveblocksDocumentApi = {
|
|
11
|
+
refresh: () => Promise<void>;
|
|
12
|
+
update: (modifyFn: () => void) => Promise<void>;
|
|
13
|
+
getTextContent: () => string;
|
|
14
|
+
getEditorState: () => EditorState;
|
|
15
|
+
getLexicalEditor: () => LexicalEditor;
|
|
16
|
+
toJSON: () => SerializedEditorState<SerializedLexicalNode>;
|
|
17
|
+
toMarkdown: () => string;
|
|
18
|
+
};
|
|
19
|
+
declare function withLexicalDocument<T>({ roomId, nodes, client }: LiveblocksLexicalOptions, callback: (api: LiveblocksDocumentApi) => Promise<T> | T): Promise<T>;
|
|
7
20
|
|
|
8
|
-
export {
|
|
21
|
+
export { type LiveblocksDocumentApi, type LiveblocksLexicalOptions, withLexicalDocument };
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,19 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true})
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/index.ts
|
|
2
|
+
var _headless = require('@lexical/headless');
|
|
3
|
+
var _markdown = require('@lexical/markdown');
|
|
4
|
+
var _yjs = require('@lexical/yjs');
|
|
2
5
|
var _core = require('@liveblocks/core');
|
|
3
6
|
var _lexical = require('lexical');
|
|
7
|
+
var _yjs3 = require('yjs');
|
|
4
8
|
|
|
9
|
+
// src/collab.ts
|
|
5
10
|
|
|
6
11
|
|
|
7
12
|
|
|
8
|
-
var _yjs = require('yjs');
|
|
9
|
-
|
|
10
|
-
// src/headless.ts
|
|
11
|
-
var _headless = require('@lexical/headless');
|
|
12
|
-
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
var _yjs3 = require('@lexical/yjs');
|
|
17
16
|
|
|
18
|
-
function withHeadlessCollaborationEditor(nodes, callback) {
|
|
19
|
-
const editor = _headless.createHeadlessEditor.call(void 0, {
|
|
20
|
-
nodes
|
|
21
|
-
});
|
|
22
|
-
const id = "root";
|
|
23
|
-
const doc = new (0, _yjs.Doc)();
|
|
24
|
-
const docMap = /* @__PURE__ */ new Map([[id, doc]]);
|
|
25
|
-
const provider = createNoOpProvider();
|
|
26
|
-
const binding = _yjs3.createBinding.call(void 0, editor, provider, id, doc, docMap);
|
|
27
|
-
const unsubscribe = registerCollaborationListeners(editor, provider, binding);
|
|
28
|
-
const res = callback(editor, binding, provider);
|
|
29
|
-
unsubscribe();
|
|
30
|
-
return res;
|
|
31
|
-
}
|
|
32
17
|
function registerCollaborationListeners(editor, provider, binding) {
|
|
33
18
|
const unsubscribeUpdateListener = editor.registerUpdateListener(
|
|
34
19
|
({
|
|
@@ -40,7 +25,7 @@ function registerCollaborationListeners(editor, provider, binding) {
|
|
|
40
25
|
tags
|
|
41
26
|
}) => {
|
|
42
27
|
if (tags.has("skip-collab") === false) {
|
|
43
|
-
|
|
28
|
+
_yjs.syncLexicalUpdateToYjs.call(void 0,
|
|
44
29
|
binding,
|
|
45
30
|
provider,
|
|
46
31
|
prevEditorState,
|
|
@@ -55,7 +40,7 @@ function registerCollaborationListeners(editor, provider, binding) {
|
|
|
55
40
|
);
|
|
56
41
|
const observer = (events, transaction) => {
|
|
57
42
|
if (transaction.origin !== binding) {
|
|
58
|
-
|
|
43
|
+
_yjs.syncYjsChangesToLexical.call(void 0, binding, provider, events, false);
|
|
59
44
|
}
|
|
60
45
|
};
|
|
61
46
|
binding.root.getSharedType().observeDeep(observer);
|
|
@@ -118,10 +103,6 @@ var MentionNode = class _MentionNode extends _lexical.DecoratorNode {
|
|
|
118
103
|
// src/ThreadNodeLite.ts
|
|
119
104
|
|
|
120
105
|
var ThreadMarkNode = class _ThreadMarkNode extends _lexical.ElementNode {
|
|
121
|
-
constructor(ids, key) {
|
|
122
|
-
super(key);
|
|
123
|
-
this.__ids = ids || [];
|
|
124
|
-
}
|
|
125
106
|
// The ids of the threads that this mark is associated with
|
|
126
107
|
static getType() {
|
|
127
108
|
return "lb-thread-mark";
|
|
@@ -150,6 +131,10 @@ var ThreadMarkNode = class _ThreadMarkNode extends _lexical.ElementNode {
|
|
|
150
131
|
const self = this.getLatest();
|
|
151
132
|
return self instanceof _ThreadMarkNode ? self.__ids : [];
|
|
152
133
|
}
|
|
134
|
+
constructor(ids, key) {
|
|
135
|
+
super(key);
|
|
136
|
+
this.__ids = ids || [];
|
|
137
|
+
}
|
|
153
138
|
canInsertTextBefore() {
|
|
154
139
|
return false;
|
|
155
140
|
}
|
|
@@ -181,53 +166,82 @@ var ThreadMarkNode = class _ThreadMarkNode extends _lexical.ElementNode {
|
|
|
181
166
|
|
|
182
167
|
// src/version.ts
|
|
183
168
|
var PKG_NAME = "@liveblocks/node-lexical";
|
|
184
|
-
var PKG_VERSION = "
|
|
169
|
+
var PKG_VERSION = "2.0.0-alpha2";
|
|
185
170
|
var PKG_FORMAT = "cjs";
|
|
186
171
|
|
|
187
172
|
// src/index.ts
|
|
188
173
|
|
|
189
174
|
_core.detectDupes.call(void 0, PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
190
175
|
var LIVEBLOCKS_NODES = [ThreadMarkNode, MentionNode];
|
|
191
|
-
async function
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
(
|
|
197
|
-
|
|
176
|
+
async function withLexicalDocument({ roomId, nodes, client }, callback) {
|
|
177
|
+
const update = new Uint8Array(
|
|
178
|
+
await client.getYjsDocumentAsBinaryUpdate(roomId)
|
|
179
|
+
);
|
|
180
|
+
const editor = _headless.createHeadlessEditor.call(void 0, {
|
|
181
|
+
nodes: [...LIVEBLOCKS_NODES, ..._nullishCoalesce(nodes, () => ( []))]
|
|
182
|
+
});
|
|
183
|
+
const id = "root";
|
|
184
|
+
const doc = new (0, _yjs3.Doc)();
|
|
185
|
+
const docMap = /* @__PURE__ */ new Map([[id, doc]]);
|
|
186
|
+
const provider = createNoOpProvider();
|
|
187
|
+
const binding = _yjs.createBinding.call(void 0, editor, provider, id, doc, docMap);
|
|
188
|
+
const unsubscribe = registerCollaborationListeners(editor, provider, binding);
|
|
189
|
+
_yjs3.applyUpdate.call(void 0, binding.doc, update);
|
|
190
|
+
editor.update(() => {
|
|
191
|
+
}, { discrete: true });
|
|
192
|
+
const val = await callback({
|
|
193
|
+
refresh: async () => {
|
|
194
|
+
const latest = new Uint8Array(
|
|
195
|
+
await client.getYjsDocumentAsBinaryUpdate(roomId)
|
|
196
|
+
);
|
|
197
|
+
_yjs3.applyUpdate.call(void 0, binding.doc, latest);
|
|
198
198
|
editor.update(() => {
|
|
199
199
|
}, { discrete: true });
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
async function modifyDocument(client, roomId, nodes, modifyFn) {
|
|
205
|
-
const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
|
|
206
|
-
const update = new Uint8Array(doc);
|
|
207
|
-
await withHeadlessCollaborationEditor(
|
|
208
|
-
[...LIVEBLOCKS_NODES, ...nodes],
|
|
209
|
-
(editor, binding) => {
|
|
210
|
-
_yjs.applyUpdate.call(void 0, binding.doc, update);
|
|
200
|
+
},
|
|
201
|
+
update: async (modifyFn) => {
|
|
211
202
|
editor.update(() => {
|
|
212
203
|
}, { discrete: true });
|
|
213
|
-
const beforeVector =
|
|
204
|
+
const beforeVector = _yjs3.encodeStateVector.call(void 0, binding.doc);
|
|
214
205
|
editor.update(
|
|
215
206
|
() => {
|
|
216
|
-
|
|
217
|
-
modifyFn(root);
|
|
207
|
+
modifyFn();
|
|
218
208
|
},
|
|
219
209
|
{ discrete: true }
|
|
220
210
|
);
|
|
221
|
-
const
|
|
222
|
-
return client.sendYjsBinaryUpdate(roomId,
|
|
211
|
+
const diffUpdate = _yjs3.encodeStateAsUpdate.call(void 0, binding.doc, beforeVector);
|
|
212
|
+
return client.sendYjsBinaryUpdate(roomId, diffUpdate);
|
|
213
|
+
},
|
|
214
|
+
getTextContent: () => {
|
|
215
|
+
let content = "";
|
|
216
|
+
editor.getEditorState().read(() => {
|
|
217
|
+
content = _lexical.$getRoot.call(void 0, ).getTextContent();
|
|
218
|
+
});
|
|
219
|
+
return content;
|
|
220
|
+
},
|
|
221
|
+
toJSON: () => {
|
|
222
|
+
return editor.getEditorState().toJSON();
|
|
223
|
+
},
|
|
224
|
+
toMarkdown: () => {
|
|
225
|
+
let markdown = "";
|
|
226
|
+
editor.getEditorState().read(() => {
|
|
227
|
+
markdown = _markdown.$convertToMarkdownString.call(void 0, _markdown.TRANSFORMERS);
|
|
228
|
+
});
|
|
229
|
+
return markdown;
|
|
230
|
+
},
|
|
231
|
+
getEditorState: () => {
|
|
232
|
+
return editor.getEditorState();
|
|
233
|
+
},
|
|
234
|
+
getLexicalEditor: () => {
|
|
235
|
+
return editor;
|
|
223
236
|
}
|
|
224
|
-
);
|
|
237
|
+
});
|
|
238
|
+
unsubscribe();
|
|
239
|
+
return val;
|
|
225
240
|
}
|
|
226
241
|
|
|
227
242
|
|
|
228
243
|
|
|
229
244
|
|
|
230
245
|
|
|
231
|
-
|
|
232
|
-
exports.$createParagraphNode = _lexical.$createParagraphNode; exports.$createTextNode = _lexical.$createTextNode; exports.$getRoot = _lexical.$getRoot; exports.getEditorState = getEditorState; exports.modifyDocument = modifyDocument;
|
|
246
|
+
exports.$createParagraphNode = _lexical.$createParagraphNode; exports.$createTextNode = _lexical.$createTextNode; exports.$getRoot = _lexical.$getRoot; exports.withLexicalDocument = withLexicalDocument;
|
|
233
247
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/headless.ts","../src/MentionNodeLite.ts","../src/ThreadNodeLite.ts","../src/version.ts"],"names":["applyUpdate","$applyNodeReplacement","$getRoot"],"mappings":"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","sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\nimport type { Liveblocks } from \"@liveblocks/node\";\nimport type {\n EditorState,\n Klass,\n LexicalNode,\n LexicalNodeReplacement,\n RootNode,\n} from \"lexical\";\nimport { $getRoot } from \"lexical\";\nimport {\n applyUpdate,\n encodeStateAsUpdate,\n encodeStateVectorFromUpdate,\n} from \"yjs\";\n\nimport { withHeadlessCollaborationEditor } from \"./headless\";\nimport { MentionNode } from \"./MentionNodeLite\";\nimport { ThreadMarkNode } from \"./ThreadNodeLite\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nconst LIVEBLOCKS_NODES = [ThreadMarkNode, MentionNode];\n\nexport { $createParagraphNode, $createTextNode, $getRoot } from \"lexical\";\n\n// get editor state\nexport async function getEditorState(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>\n): Promise<EditorState> {\n const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);\n const update = new Uint8Array(doc);\n return withHeadlessCollaborationEditor(\n [...LIVEBLOCKS_NODES, ...nodes],\n (editor, binding) => {\n applyUpdate(binding.doc, update);\n editor.update(() => {}, { discrete: true });\n return editor.getEditorState();\n }\n );\n}\n\n// modify document\nexport async function modifyDocument(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n modifyFn: (root: RootNode) => void\n): Promise<void> {\n const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);\n const update = new Uint8Array(doc);\n await withHeadlessCollaborationEditor(\n [...LIVEBLOCKS_NODES, ...nodes],\n (editor, binding) => {\n applyUpdate(binding.doc, update);\n editor.update(() => {}, { discrete: true });\n const beforeVector = encodeStateVectorFromUpdate(update);\n editor.update(\n () => {\n const root = $getRoot();\n modifyFn(root);\n },\n { discrete: true }\n );\n const afterUpdate = encodeStateAsUpdate(binding.doc, beforeVector);\n return client.sendYjsBinaryUpdate(roomId, afterUpdate);\n }\n );\n}\n","import { createHeadlessEditor } from \"@lexical/headless\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type {\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n SerializedEditorState,\n SerializedLexicalNode,\n} from \"lexical\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nexport function headlessConvertYDocStateToLexicalJSON(\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n yDocState: Uint8Array\n): SerializedEditorState<SerializedLexicalNode> {\n return withHeadlessCollaborationEditor(nodes, (editor, binding) => {\n applyUpdate(binding.doc, yDocState, { isUpdateRemote: true });\n editor.update(() => {}, { discrete: true });\n\n return editor.getEditorState().toJSON();\n });\n}\nexport function withHeadlessCollaborationEditor<T>(\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n callback: (editor: LexicalEditor, binding: Binding, provider: Provider) => T\n): T {\n const editor = createHeadlessEditor({\n nodes,\n });\n\n const id = \"root\";\n const doc = new Doc();\n const docMap = new Map([[id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(editor, provider, id, doc, docMap);\n\n const unsubscribe = registerCollaborationListeners(editor, provider, binding);\n\n const res = callback(editor, binding, provider);\n\n unsubscribe();\n\n return res;\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n","import type { NodeKey, SerializedLexicalNode, Spread } from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\n\nexport type SerializedMentionNode = Spread<\n {\n value: string;\n },\n SerializedLexicalNode\n>;\n\nexport class MentionNode extends DecoratorNode<null> {\n __id: string;\n\n constructor(value: string, key?: NodeKey) {\n super(key);\n this.__id = value;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id);\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = new MentionNode(serializedNode.value);\n return $applyNodeReplacement(node);\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n value: this.getTextContent(),\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getTextContent(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): null {\n return null;\n }\n}\n","import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $applyNodeReplacement<ThreadMarkNode>(\n new ThreadMarkNode(serializedNode.ids)\n );\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return self instanceof ThreadMarkNode ? self.__ids : [];\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n","declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/node-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/collab.ts","../src/MentionNodeLite.ts","../src/ThreadNodeLite.ts","../src/version.ts"],"names":["createHeadlessEditor","createBinding","Doc","$applyNodeReplacement","$getRoot"],"mappings":"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","sourcesContent":["import { createHeadlessEditor } from \"@lexical/headless\";\nimport { $convertToMarkdownString, TRANSFORMERS } from \"@lexical/markdown\";\nimport { createBinding } from \"@lexical/yjs\";\nimport { detectDupes } from \"@liveblocks/core\";\nimport type { Liveblocks } from \"@liveblocks/node\";\nimport type {\n EditorState,\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n SerializedEditorState,\n SerializedLexicalNode,\n} from \"lexical\";\nimport { $getRoot } from \"lexical\";\nimport { applyUpdate, Doc, encodeStateAsUpdate, encodeStateVector } from \"yjs\";\n\nimport { createNoOpProvider, registerCollaborationListeners } from \"./collab\";\nimport { MentionNode } from \"./MentionNodeLite\";\nimport { ThreadMarkNode } from \"./ThreadNodeLite\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nconst LIVEBLOCKS_NODES = [ThreadMarkNode, MentionNode];\n\nexport { $createParagraphNode, $createTextNode, $getRoot } from \"lexical\";\n\nexport type LiveblocksLexicalOptions = {\n roomId: string;\n nodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;\n client: Liveblocks;\n};\n\nexport type LiveblocksDocumentApi = {\n refresh: () => Promise<void>;\n update: (modifyFn: () => void) => Promise<void>;\n getTextContent: () => string;\n getEditorState: () => EditorState;\n getLexicalEditor: () => LexicalEditor;\n toJSON: () => SerializedEditorState<SerializedLexicalNode>;\n toMarkdown: () => string;\n};\n\nexport async function withLexicalDocument<T>(\n { roomId, nodes, client }: LiveblocksLexicalOptions,\n callback: (api: LiveblocksDocumentApi) => Promise<T> | T\n): Promise<T> {\n const update = new Uint8Array(\n await client.getYjsDocumentAsBinaryUpdate(roomId)\n );\n const editor = createHeadlessEditor({\n nodes: [...LIVEBLOCKS_NODES, ...(nodes ?? [])],\n });\n const id = \"root\";\n const doc = new Doc();\n const docMap = new Map([[id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(editor, provider, id, doc, docMap);\n const unsubscribe = registerCollaborationListeners(editor, provider, binding);\n applyUpdate(binding.doc, update);\n editor.update(() => {}, { discrete: true });\n\n const val = await callback({\n refresh: async () => {\n const latest = new Uint8Array(\n await client.getYjsDocumentAsBinaryUpdate(roomId)\n );\n applyUpdate(binding.doc, latest);\n editor.update(() => {}, { discrete: true });\n },\n update: async (modifyFn) => {\n // Flush any pending updates (there really shouldn't be any?), this may be a NOOP\n editor.update(() => {}, { discrete: true });\n const beforeVector = encodeStateVector(binding.doc);\n editor.update(\n () => {\n modifyFn();\n },\n { discrete: true }\n );\n // grab update after diffing\n const diffUpdate = encodeStateAsUpdate(binding.doc, beforeVector);\n return client.sendYjsBinaryUpdate(roomId, diffUpdate);\n },\n getTextContent: () => {\n let content = \"\";\n editor.getEditorState().read(() => {\n content = $getRoot().getTextContent();\n });\n return content;\n },\n toJSON: () => {\n return editor.getEditorState().toJSON();\n },\n toMarkdown: () => {\n let markdown: string = \"\";\n editor.getEditorState().read(() => {\n markdown = $convertToMarkdownString(TRANSFORMERS);\n });\n return markdown;\n },\n getEditorState: () => {\n return editor.getEditorState();\n },\n getLexicalEditor: () => {\n return editor;\n },\n });\n unsubscribe();\n\n return val;\n}\n","import { createHeadlessEditor } from \"@lexical/headless\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type {\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n} from \"lexical\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { Doc } from \"yjs\";\n\nexport function withHeadlessCollaborationEditor<T>(\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n callback: (editor: LexicalEditor, binding: Binding, provider: Provider) => T\n): T {\n const editor = createHeadlessEditor({\n nodes,\n });\n\n const id = \"root\";\n const doc = new Doc();\n const docMap = new Map([[id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(editor, provider, id, doc, docMap);\n\n const unsubscribe = registerCollaborationListeners(editor, provider, binding);\n\n const res = callback(editor, binding, provider);\n\n unsubscribe();\n\n return res;\n}\n\nexport function registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\nexport function createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n","import type { NodeKey, SerializedLexicalNode, Spread } from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\n\nexport type SerializedMentionNode = Spread<\n {\n value: string;\n },\n SerializedLexicalNode\n>;\n\nexport class MentionNode extends DecoratorNode<null> {\n __id: string;\n\n constructor(value: string, key?: NodeKey) {\n super(key);\n this.__id = value;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id);\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = new MentionNode(serializedNode.value);\n return $applyNodeReplacement(node);\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n value: this.getTextContent(),\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getTextContent(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): null {\n return null;\n }\n}\n","import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $applyNodeReplacement<ThreadMarkNode>(\n new ThreadMarkNode(serializedNode.ids)\n );\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return self instanceof ThreadMarkNode ? self.__ids : [];\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n","declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/node-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,34 +1,19 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import { createHeadlessEditor as createHeadlessEditor2 } from "@lexical/headless";
|
|
3
|
+
import { $convertToMarkdownString, TRANSFORMERS } from "@lexical/markdown";
|
|
4
|
+
import { createBinding as createBinding2 } from "@lexical/yjs";
|
|
2
5
|
import { detectDupes } from "@liveblocks/core";
|
|
3
6
|
import { $getRoot } from "lexical";
|
|
4
|
-
import {
|
|
5
|
-
applyUpdate as applyUpdate2,
|
|
6
|
-
encodeStateAsUpdate,
|
|
7
|
-
encodeStateVectorFromUpdate
|
|
8
|
-
} from "yjs";
|
|
7
|
+
import { applyUpdate, Doc as Doc2, encodeStateAsUpdate, encodeStateVector } from "yjs";
|
|
9
8
|
|
|
10
|
-
// src/
|
|
9
|
+
// src/collab.ts
|
|
11
10
|
import { createHeadlessEditor } from "@lexical/headless";
|
|
12
11
|
import {
|
|
13
12
|
createBinding,
|
|
14
13
|
syncLexicalUpdateToYjs,
|
|
15
14
|
syncYjsChangesToLexical
|
|
16
15
|
} from "@lexical/yjs";
|
|
17
|
-
import {
|
|
18
|
-
function withHeadlessCollaborationEditor(nodes, callback) {
|
|
19
|
-
const editor = createHeadlessEditor({
|
|
20
|
-
nodes
|
|
21
|
-
});
|
|
22
|
-
const id = "root";
|
|
23
|
-
const doc = new Doc();
|
|
24
|
-
const docMap = /* @__PURE__ */ new Map([[id, doc]]);
|
|
25
|
-
const provider = createNoOpProvider();
|
|
26
|
-
const binding = createBinding(editor, provider, id, doc, docMap);
|
|
27
|
-
const unsubscribe = registerCollaborationListeners(editor, provider, binding);
|
|
28
|
-
const res = callback(editor, binding, provider);
|
|
29
|
-
unsubscribe();
|
|
30
|
-
return res;
|
|
31
|
-
}
|
|
16
|
+
import { Doc } from "yjs";
|
|
32
17
|
function registerCollaborationListeners(editor, provider, binding) {
|
|
33
18
|
const unsubscribeUpdateListener = editor.registerUpdateListener(
|
|
34
19
|
({
|
|
@@ -118,10 +103,6 @@ var MentionNode = class _MentionNode extends DecoratorNode {
|
|
|
118
103
|
// src/ThreadNodeLite.ts
|
|
119
104
|
import { $applyNodeReplacement as $applyNodeReplacement2, $isRangeSelection, ElementNode } from "lexical";
|
|
120
105
|
var ThreadMarkNode = class _ThreadMarkNode extends ElementNode {
|
|
121
|
-
constructor(ids, key) {
|
|
122
|
-
super(key);
|
|
123
|
-
this.__ids = ids || [];
|
|
124
|
-
}
|
|
125
106
|
// The ids of the threads that this mark is associated with
|
|
126
107
|
static getType() {
|
|
127
108
|
return "lb-thread-mark";
|
|
@@ -150,6 +131,10 @@ var ThreadMarkNode = class _ThreadMarkNode extends ElementNode {
|
|
|
150
131
|
const self = this.getLatest();
|
|
151
132
|
return self instanceof _ThreadMarkNode ? self.__ids : [];
|
|
152
133
|
}
|
|
134
|
+
constructor(ids, key) {
|
|
135
|
+
super(key);
|
|
136
|
+
this.__ids = ids || [];
|
|
137
|
+
}
|
|
153
138
|
canInsertTextBefore() {
|
|
154
139
|
return false;
|
|
155
140
|
}
|
|
@@ -181,53 +166,82 @@ var ThreadMarkNode = class _ThreadMarkNode extends ElementNode {
|
|
|
181
166
|
|
|
182
167
|
// src/version.ts
|
|
183
168
|
var PKG_NAME = "@liveblocks/node-lexical";
|
|
184
|
-
var PKG_VERSION = "
|
|
169
|
+
var PKG_VERSION = "2.0.0-alpha2";
|
|
185
170
|
var PKG_FORMAT = "esm";
|
|
186
171
|
|
|
187
172
|
// src/index.ts
|
|
188
173
|
import { $createParagraphNode, $createTextNode, $getRoot as $getRoot2 } from "lexical";
|
|
189
174
|
detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
190
175
|
var LIVEBLOCKS_NODES = [ThreadMarkNode, MentionNode];
|
|
191
|
-
async function
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
176
|
+
async function withLexicalDocument({ roomId, nodes, client }, callback) {
|
|
177
|
+
const update = new Uint8Array(
|
|
178
|
+
await client.getYjsDocumentAsBinaryUpdate(roomId)
|
|
179
|
+
);
|
|
180
|
+
const editor = createHeadlessEditor2({
|
|
181
|
+
nodes: [...LIVEBLOCKS_NODES, ...nodes ?? []]
|
|
182
|
+
});
|
|
183
|
+
const id = "root";
|
|
184
|
+
const doc = new Doc2();
|
|
185
|
+
const docMap = /* @__PURE__ */ new Map([[id, doc]]);
|
|
186
|
+
const provider = createNoOpProvider();
|
|
187
|
+
const binding = createBinding2(editor, provider, id, doc, docMap);
|
|
188
|
+
const unsubscribe = registerCollaborationListeners(editor, provider, binding);
|
|
189
|
+
applyUpdate(binding.doc, update);
|
|
190
|
+
editor.update(() => {
|
|
191
|
+
}, { discrete: true });
|
|
192
|
+
const val = await callback({
|
|
193
|
+
refresh: async () => {
|
|
194
|
+
const latest = new Uint8Array(
|
|
195
|
+
await client.getYjsDocumentAsBinaryUpdate(roomId)
|
|
196
|
+
);
|
|
197
|
+
applyUpdate(binding.doc, latest);
|
|
198
198
|
editor.update(() => {
|
|
199
199
|
}, { discrete: true });
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
async function modifyDocument(client, roomId, nodes, modifyFn) {
|
|
205
|
-
const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
|
|
206
|
-
const update = new Uint8Array(doc);
|
|
207
|
-
await withHeadlessCollaborationEditor(
|
|
208
|
-
[...LIVEBLOCKS_NODES, ...nodes],
|
|
209
|
-
(editor, binding) => {
|
|
210
|
-
applyUpdate2(binding.doc, update);
|
|
200
|
+
},
|
|
201
|
+
update: async (modifyFn) => {
|
|
211
202
|
editor.update(() => {
|
|
212
203
|
}, { discrete: true });
|
|
213
|
-
const beforeVector =
|
|
204
|
+
const beforeVector = encodeStateVector(binding.doc);
|
|
214
205
|
editor.update(
|
|
215
206
|
() => {
|
|
216
|
-
|
|
217
|
-
modifyFn(root);
|
|
207
|
+
modifyFn();
|
|
218
208
|
},
|
|
219
209
|
{ discrete: true }
|
|
220
210
|
);
|
|
221
|
-
const
|
|
222
|
-
return client.sendYjsBinaryUpdate(roomId,
|
|
211
|
+
const diffUpdate = encodeStateAsUpdate(binding.doc, beforeVector);
|
|
212
|
+
return client.sendYjsBinaryUpdate(roomId, diffUpdate);
|
|
213
|
+
},
|
|
214
|
+
getTextContent: () => {
|
|
215
|
+
let content = "";
|
|
216
|
+
editor.getEditorState().read(() => {
|
|
217
|
+
content = $getRoot().getTextContent();
|
|
218
|
+
});
|
|
219
|
+
return content;
|
|
220
|
+
},
|
|
221
|
+
toJSON: () => {
|
|
222
|
+
return editor.getEditorState().toJSON();
|
|
223
|
+
},
|
|
224
|
+
toMarkdown: () => {
|
|
225
|
+
let markdown = "";
|
|
226
|
+
editor.getEditorState().read(() => {
|
|
227
|
+
markdown = $convertToMarkdownString(TRANSFORMERS);
|
|
228
|
+
});
|
|
229
|
+
return markdown;
|
|
230
|
+
},
|
|
231
|
+
getEditorState: () => {
|
|
232
|
+
return editor.getEditorState();
|
|
233
|
+
},
|
|
234
|
+
getLexicalEditor: () => {
|
|
235
|
+
return editor;
|
|
223
236
|
}
|
|
224
|
-
);
|
|
237
|
+
});
|
|
238
|
+
unsubscribe();
|
|
239
|
+
return val;
|
|
225
240
|
}
|
|
226
241
|
export {
|
|
227
242
|
$createParagraphNode,
|
|
228
243
|
$createTextNode,
|
|
229
244
|
$getRoot2 as $getRoot,
|
|
230
|
-
|
|
231
|
-
modifyDocument
|
|
245
|
+
withLexicalDocument
|
|
232
246
|
};
|
|
233
247
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/headless.ts","../src/MentionNodeLite.ts","../src/ThreadNodeLite.ts","../src/version.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\nimport type { Liveblocks } from \"@liveblocks/node\";\nimport type {\n EditorState,\n Klass,\n LexicalNode,\n LexicalNodeReplacement,\n RootNode,\n} from \"lexical\";\nimport { $getRoot } from \"lexical\";\nimport {\n applyUpdate,\n encodeStateAsUpdate,\n encodeStateVectorFromUpdate,\n} from \"yjs\";\n\nimport { withHeadlessCollaborationEditor } from \"./headless\";\nimport { MentionNode } from \"./MentionNodeLite\";\nimport { ThreadMarkNode } from \"./ThreadNodeLite\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nconst LIVEBLOCKS_NODES = [ThreadMarkNode, MentionNode];\n\nexport { $createParagraphNode, $createTextNode, $getRoot } from \"lexical\";\n\n// get editor state\nexport async function getEditorState(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>\n): Promise<EditorState> {\n const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);\n const update = new Uint8Array(doc);\n return withHeadlessCollaborationEditor(\n [...LIVEBLOCKS_NODES, ...nodes],\n (editor, binding) => {\n applyUpdate(binding.doc, update);\n editor.update(() => {}, { discrete: true });\n return editor.getEditorState();\n }\n );\n}\n\n// modify document\nexport async function modifyDocument(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n modifyFn: (root: RootNode) => void\n): Promise<void> {\n const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);\n const update = new Uint8Array(doc);\n await withHeadlessCollaborationEditor(\n [...LIVEBLOCKS_NODES, ...nodes],\n (editor, binding) => {\n applyUpdate(binding.doc, update);\n editor.update(() => {}, { discrete: true });\n const beforeVector = encodeStateVectorFromUpdate(update);\n editor.update(\n () => {\n const root = $getRoot();\n modifyFn(root);\n },\n { discrete: true }\n );\n const afterUpdate = encodeStateAsUpdate(binding.doc, beforeVector);\n return client.sendYjsBinaryUpdate(roomId, afterUpdate);\n }\n );\n}\n","import { createHeadlessEditor } from \"@lexical/headless\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type {\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n SerializedEditorState,\n SerializedLexicalNode,\n} from \"lexical\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nexport function headlessConvertYDocStateToLexicalJSON(\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n yDocState: Uint8Array\n): SerializedEditorState<SerializedLexicalNode> {\n return withHeadlessCollaborationEditor(nodes, (editor, binding) => {\n applyUpdate(binding.doc, yDocState, { isUpdateRemote: true });\n editor.update(() => {}, { discrete: true });\n\n return editor.getEditorState().toJSON();\n });\n}\nexport function withHeadlessCollaborationEditor<T>(\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n callback: (editor: LexicalEditor, binding: Binding, provider: Provider) => T\n): T {\n const editor = createHeadlessEditor({\n nodes,\n });\n\n const id = \"root\";\n const doc = new Doc();\n const docMap = new Map([[id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(editor, provider, id, doc, docMap);\n\n const unsubscribe = registerCollaborationListeners(editor, provider, binding);\n\n const res = callback(editor, binding, provider);\n\n unsubscribe();\n\n return res;\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n","import type { NodeKey, SerializedLexicalNode, Spread } from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\n\nexport type SerializedMentionNode = Spread<\n {\n value: string;\n },\n SerializedLexicalNode\n>;\n\nexport class MentionNode extends DecoratorNode<null> {\n __id: string;\n\n constructor(value: string, key?: NodeKey) {\n super(key);\n this.__id = value;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id);\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = new MentionNode(serializedNode.value);\n return $applyNodeReplacement(node);\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n value: this.getTextContent(),\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getTextContent(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): null {\n return null;\n }\n}\n","import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $applyNodeReplacement<ThreadMarkNode>(\n new ThreadMarkNode(serializedNode.ids)\n );\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return self instanceof ThreadMarkNode ? self.__ids : [];\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n","declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/node-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n"],"mappings":"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","names":["applyUpdate","$applyNodeReplacement","$getRoot","applyUpdate"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/collab.ts","../src/MentionNodeLite.ts","../src/ThreadNodeLite.ts","../src/version.ts"],"sourcesContent":["import { createHeadlessEditor } from \"@lexical/headless\";\nimport { $convertToMarkdownString, TRANSFORMERS } from \"@lexical/markdown\";\nimport { createBinding } from \"@lexical/yjs\";\nimport { detectDupes } from \"@liveblocks/core\";\nimport type { Liveblocks } from \"@liveblocks/node\";\nimport type {\n EditorState,\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n SerializedEditorState,\n SerializedLexicalNode,\n} from \"lexical\";\nimport { $getRoot } from \"lexical\";\nimport { applyUpdate, Doc, encodeStateAsUpdate, encodeStateVector } from \"yjs\";\n\nimport { createNoOpProvider, registerCollaborationListeners } from \"./collab\";\nimport { MentionNode } from \"./MentionNodeLite\";\nimport { ThreadMarkNode } from \"./ThreadNodeLite\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nconst LIVEBLOCKS_NODES = [ThreadMarkNode, MentionNode];\n\nexport { $createParagraphNode, $createTextNode, $getRoot } from \"lexical\";\n\nexport type LiveblocksLexicalOptions = {\n roomId: string;\n nodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;\n client: Liveblocks;\n};\n\nexport type LiveblocksDocumentApi = {\n refresh: () => Promise<void>;\n update: (modifyFn: () => void) => Promise<void>;\n getTextContent: () => string;\n getEditorState: () => EditorState;\n getLexicalEditor: () => LexicalEditor;\n toJSON: () => SerializedEditorState<SerializedLexicalNode>;\n toMarkdown: () => string;\n};\n\nexport async function withLexicalDocument<T>(\n { roomId, nodes, client }: LiveblocksLexicalOptions,\n callback: (api: LiveblocksDocumentApi) => Promise<T> | T\n): Promise<T> {\n const update = new Uint8Array(\n await client.getYjsDocumentAsBinaryUpdate(roomId)\n );\n const editor = createHeadlessEditor({\n nodes: [...LIVEBLOCKS_NODES, ...(nodes ?? [])],\n });\n const id = \"root\";\n const doc = new Doc();\n const docMap = new Map([[id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(editor, provider, id, doc, docMap);\n const unsubscribe = registerCollaborationListeners(editor, provider, binding);\n applyUpdate(binding.doc, update);\n editor.update(() => {}, { discrete: true });\n\n const val = await callback({\n refresh: async () => {\n const latest = new Uint8Array(\n await client.getYjsDocumentAsBinaryUpdate(roomId)\n );\n applyUpdate(binding.doc, latest);\n editor.update(() => {}, { discrete: true });\n },\n update: async (modifyFn) => {\n // Flush any pending updates (there really shouldn't be any?), this may be a NOOP\n editor.update(() => {}, { discrete: true });\n const beforeVector = encodeStateVector(binding.doc);\n editor.update(\n () => {\n modifyFn();\n },\n { discrete: true }\n );\n // grab update after diffing\n const diffUpdate = encodeStateAsUpdate(binding.doc, beforeVector);\n return client.sendYjsBinaryUpdate(roomId, diffUpdate);\n },\n getTextContent: () => {\n let content = \"\";\n editor.getEditorState().read(() => {\n content = $getRoot().getTextContent();\n });\n return content;\n },\n toJSON: () => {\n return editor.getEditorState().toJSON();\n },\n toMarkdown: () => {\n let markdown: string = \"\";\n editor.getEditorState().read(() => {\n markdown = $convertToMarkdownString(TRANSFORMERS);\n });\n return markdown;\n },\n getEditorState: () => {\n return editor.getEditorState();\n },\n getLexicalEditor: () => {\n return editor;\n },\n });\n unsubscribe();\n\n return val;\n}\n","import { createHeadlessEditor } from \"@lexical/headless\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type {\n Klass,\n LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\n} from \"lexical\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { Doc } from \"yjs\";\n\nexport function withHeadlessCollaborationEditor<T>(\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>,\n callback: (editor: LexicalEditor, binding: Binding, provider: Provider) => T\n): T {\n const editor = createHeadlessEditor({\n nodes,\n });\n\n const id = \"root\";\n const doc = new Doc();\n const docMap = new Map([[id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(editor, provider, id, doc, docMap);\n\n const unsubscribe = registerCollaborationListeners(editor, provider, binding);\n\n const res = callback(editor, binding, provider);\n\n unsubscribe();\n\n return res;\n}\n\nexport function registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\nexport function createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n","import type { NodeKey, SerializedLexicalNode, Spread } from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\n\nexport type SerializedMentionNode = Spread<\n {\n value: string;\n },\n SerializedLexicalNode\n>;\n\nexport class MentionNode extends DecoratorNode<null> {\n __id: string;\n\n constructor(value: string, key?: NodeKey) {\n super(key);\n this.__id = value;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id);\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = new MentionNode(serializedNode.value);\n return $applyNodeReplacement(node);\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n value: this.getTextContent(),\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getTextContent(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): null {\n return null;\n }\n}\n","import type {\n BaseSelection,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, $isRangeSelection, ElementNode } from \"lexical\";\n\nexport type SerializedThreadMarkNode = Spread<\n {\n ids: Array<string>;\n },\n SerializedElementNode\n>;\n\nexport class ThreadMarkNode extends ElementNode {\n /** @internal */\n __ids: Array<string>; // The ids of the threads that this mark is associated with\n\n static getType(): string {\n return \"lb-thread-mark\";\n }\n\n static clone(node: ThreadMarkNode): ThreadMarkNode {\n return new ThreadMarkNode(Array.from(node.__ids), node.__key);\n }\n\n static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode {\n const node = $applyNodeReplacement<ThreadMarkNode>(\n new ThreadMarkNode(serializedNode.ids)\n );\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n exportJSON(): SerializedThreadMarkNode {\n return {\n ...super.exportJSON(),\n ids: this.getIDs(),\n type: \"lb-thread-mark\",\n version: 1,\n };\n }\n\n getIDs(): Array<string> {\n const self = this.getLatest();\n return self instanceof ThreadMarkNode ? self.__ids : [];\n }\n\n constructor(ids: Array<string>, key?: NodeKey) {\n super(key);\n this.__ids = ids || [];\n }\n\n canInsertTextBefore(): false {\n return false;\n }\n\n canInsertTextAfter(): false {\n return false;\n }\n\n canBeEmpty(): false {\n return false;\n }\n\n isInline(): true {\n return true;\n }\n\n extractWithChild(\n _: LexicalNode,\n selection: BaseSelection,\n destination: \"clone\" | \"html\"\n ): boolean {\n if (!$isRangeSelection(selection) || destination === \"html\") {\n return false;\n }\n const anchor = selection.anchor;\n const focus = selection.focus;\n const anchorNode = anchor.getNode();\n const focusNode = focus.getNode();\n const isBackward = selection.isBackward();\n const selectionLength = isBackward\n ? anchor.offset - focus.offset\n : focus.offset - anchor.offset;\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n this.getTextContent().length === selectionLength\n );\n }\n\n excludeFromCopy(destination: \"clone\" | \"html\"): boolean {\n return destination !== \"clone\";\n }\n}\n","declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/node-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n"],"mappings":"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","names":["createHeadlessEditor","createBinding","Doc","$applyNodeReplacement","$getRoot","createHeadlessEditor","Doc","createBinding"]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/node-lexical",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha2",
|
|
4
4
|
"description": "A server-side utility that lets you modify lexical documents hosted in Liveblocks.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
|
+
"type": "commonjs",
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
@@ -33,14 +34,16 @@
|
|
|
33
34
|
"test:watch": "jest --silent --verbose --color=always --watch"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@liveblocks/core": "
|
|
37
|
-
"@liveblocks/node": "
|
|
37
|
+
"@liveblocks/core": "2.0.0-alpha2",
|
|
38
|
+
"@liveblocks/node": "2.0.0-alpha2",
|
|
38
39
|
"yjs": "^13.6.15"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {
|
|
41
|
-
"@lexical/headless": "0.
|
|
42
|
-
"@lexical/
|
|
43
|
-
"lexical": "0.
|
|
42
|
+
"@lexical/headless": "0.16.0",
|
|
43
|
+
"@lexical/selection": "0.16.0",
|
|
44
|
+
"@lexical/yjs": "0.16.0",
|
|
45
|
+
"@lexical/markdown": "0.16.0",
|
|
46
|
+
"lexical": "0.16.0"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|
|
46
49
|
"@liveblocks/eslint-config": "*",
|