@liveblocks/node-lexical 1.12.0-lexical6 → 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 CHANGED
@@ -1,10 +1,21 @@
1
1
  import { Liveblocks } from '@liveblocks/node';
2
- import { Klass, LexicalNode, LexicalNodeReplacement, LexicalEditor, EditorState } from 'lexical';
2
+ import { Klass, LexicalNode, LexicalNodeReplacement, EditorState, LexicalEditor, SerializedEditorState, SerializedLexicalNode } from 'lexical';
3
3
  export { $createParagraphNode, $createTextNode, $getRoot } from 'lexical';
4
4
 
5
- declare function getEditor(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>): Promise<LexicalEditor>;
6
- declare function getTextContent(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>): Promise<string>;
7
- declare function getEditorState(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>): Promise<EditorState>;
8
- declare function modifyDocument(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>, modifyFn: (editor: LexicalEditor) => void): Promise<void>;
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>;
9
20
 
10
- export { getEditor, getEditorState, getTextContent, modifyDocument };
21
+ export { type LiveblocksDocumentApi, type LiveblocksLexicalOptions, withLexicalDocument };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,21 @@
1
1
  import { Liveblocks } from '@liveblocks/node';
2
- import { Klass, LexicalNode, LexicalNodeReplacement, LexicalEditor, EditorState } from 'lexical';
2
+ import { Klass, LexicalNode, LexicalNodeReplacement, EditorState, LexicalEditor, SerializedEditorState, SerializedLexicalNode } from 'lexical';
3
3
  export { $createParagraphNode, $createTextNode, $getRoot } from 'lexical';
4
4
 
5
- declare function getEditor(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>): Promise<LexicalEditor>;
6
- declare function getTextContent(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>): Promise<string>;
7
- declare function getEditorState(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>): Promise<EditorState>;
8
- declare function modifyDocument(client: Liveblocks, roomId: string, nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>, modifyFn: (editor: LexicalEditor) => void): Promise<void>;
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>;
9
20
 
10
- export { getEditor, getEditorState, getTextContent, modifyDocument };
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});// src/index.ts
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
 
16
- var _yjs3 = require('@lexical/yjs');
17
-
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
- _yjs3.syncLexicalUpdateToYjs.call(void 0,
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
- _yjs3.syncYjsChangesToLexical.call(void 0, binding, provider, events, false);
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,84 +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 = "1.12.0-lexical6";
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 getEditor(client, roomId, nodes) {
192
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
193
- const update = new Uint8Array(doc);
194
- return withHeadlessCollaborationEditor(
195
- [...LIVEBLOCKS_NODES, ...nodes],
196
- (editor, binding) => {
197
- _yjs.applyUpdate.call(void 0, binding.doc, update);
198
- editor.update(() => {
199
- }, { discrete: true });
200
- return editor;
201
- }
202
- );
203
- }
204
- async function getTextContent(client, roomId, nodes) {
205
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
206
- const update = new Uint8Array(doc);
207
- return withHeadlessCollaborationEditor(
208
- [...LIVEBLOCKS_NODES, ...nodes],
209
- (editor, binding) => {
210
- _yjs.applyUpdate.call(void 0, binding.doc, update);
211
- editor.update(() => {
212
- }, { discrete: true });
213
- let content = "";
214
- editor.getEditorState().read(() => {
215
- content = _lexical.$getRoot.call(void 0, ).getTextContent();
216
- });
217
- return content;
218
- }
176
+ async function withLexicalDocument({ roomId, nodes, client }, callback) {
177
+ const update = new Uint8Array(
178
+ await client.getYjsDocumentAsBinaryUpdate(roomId)
219
179
  );
220
- }
221
- async function getEditorState(client, roomId, nodes) {
222
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
223
- const update = new Uint8Array(doc);
224
- return withHeadlessCollaborationEditor(
225
- [...LIVEBLOCKS_NODES, ...nodes],
226
- (editor, binding) => {
227
- _yjs.applyUpdate.call(void 0, binding.doc, update);
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);
228
198
  editor.update(() => {
229
199
  }, { discrete: true });
230
- return editor.getEditorState();
231
- }
232
- );
233
- }
234
- async function modifyDocument(client, roomId, nodes, modifyFn) {
235
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
236
- const update = new Uint8Array(doc);
237
- await withHeadlessCollaborationEditor(
238
- [...LIVEBLOCKS_NODES, ...nodes],
239
- (editor, binding) => {
240
- _yjs.applyUpdate.call(void 0, binding.doc, update);
200
+ },
201
+ update: async (modifyFn) => {
241
202
  editor.update(() => {
242
203
  }, { discrete: true });
243
- const beforeVector = _yjs.encodeStateVectorFromUpdate.call(void 0, update);
204
+ const beforeVector = _yjs3.encodeStateVector.call(void 0, binding.doc);
244
205
  editor.update(
245
206
  () => {
246
- modifyFn(editor);
207
+ modifyFn();
247
208
  },
248
209
  { discrete: true }
249
210
  );
250
- const afterUpdate = _yjs.encodeStateAsUpdate.call(void 0, binding.doc, beforeVector);
251
- return client.sendYjsBinaryUpdate(roomId, afterUpdate);
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;
252
236
  }
253
- );
237
+ });
238
+ unsubscribe();
239
+ return val;
254
240
  }
255
241
 
256
242
 
257
243
 
258
244
 
259
245
 
260
-
261
-
262
-
263
- exports.$createParagraphNode = _lexical.$createParagraphNode; exports.$createTextNode = _lexical.$createTextNode; exports.$getRoot = _lexical.$getRoot; exports.getEditor = getEditor; exports.getEditorState = getEditorState; exports.getTextContent = getTextContent; exports.modifyDocument = modifyDocument;
246
+ exports.$createParagraphNode = _lexical.$createParagraphNode; exports.$createTextNode = _lexical.$createTextNode; exports.$getRoot = _lexical.$getRoot; exports.withLexicalDocument = withLexicalDocument;
264
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 LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\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// gets a sync'd headless editor\nexport async function getEditor(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>\n): Promise<LexicalEditor> {\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;\n }\n );\n}\n\n// gets text content\nexport async function getTextContent(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>\n): Promise<string> {\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 let content: string = \"\";\n editor.getEditorState().read(() => {\n content = $getRoot().getTextContent();\n });\n return content;\n }\n );\n}\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: (editor: LexicalEditor) => 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 modifyFn(editor);\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/headless.ts
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 { applyUpdate, Doc } from "yjs";
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,84 +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 = "1.12.0-lexical6";
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 getEditor(client, roomId, nodes) {
192
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
193
- const update = new Uint8Array(doc);
194
- return withHeadlessCollaborationEditor(
195
- [...LIVEBLOCKS_NODES, ...nodes],
196
- (editor, binding) => {
197
- applyUpdate2(binding.doc, update);
198
- editor.update(() => {
199
- }, { discrete: true });
200
- return editor;
201
- }
202
- );
203
- }
204
- async function getTextContent(client, roomId, nodes) {
205
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
206
- const update = new Uint8Array(doc);
207
- return withHeadlessCollaborationEditor(
208
- [...LIVEBLOCKS_NODES, ...nodes],
209
- (editor, binding) => {
210
- applyUpdate2(binding.doc, update);
211
- editor.update(() => {
212
- }, { discrete: true });
213
- let content = "";
214
- editor.getEditorState().read(() => {
215
- content = $getRoot().getTextContent();
216
- });
217
- return content;
218
- }
176
+ async function withLexicalDocument({ roomId, nodes, client }, callback) {
177
+ const update = new Uint8Array(
178
+ await client.getYjsDocumentAsBinaryUpdate(roomId)
219
179
  );
220
- }
221
- async function getEditorState(client, roomId, nodes) {
222
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
223
- const update = new Uint8Array(doc);
224
- return withHeadlessCollaborationEditor(
225
- [...LIVEBLOCKS_NODES, ...nodes],
226
- (editor, binding) => {
227
- applyUpdate2(binding.doc, update);
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);
228
198
  editor.update(() => {
229
199
  }, { discrete: true });
230
- return editor.getEditorState();
231
- }
232
- );
233
- }
234
- async function modifyDocument(client, roomId, nodes, modifyFn) {
235
- const doc = await client.getYjsDocumentAsBinaryUpdate(roomId);
236
- const update = new Uint8Array(doc);
237
- await withHeadlessCollaborationEditor(
238
- [...LIVEBLOCKS_NODES, ...nodes],
239
- (editor, binding) => {
240
- applyUpdate2(binding.doc, update);
200
+ },
201
+ update: async (modifyFn) => {
241
202
  editor.update(() => {
242
203
  }, { discrete: true });
243
- const beforeVector = encodeStateVectorFromUpdate(update);
204
+ const beforeVector = encodeStateVector(binding.doc);
244
205
  editor.update(
245
206
  () => {
246
- modifyFn(editor);
207
+ modifyFn();
247
208
  },
248
209
  { discrete: true }
249
210
  );
250
- const afterUpdate = encodeStateAsUpdate(binding.doc, beforeVector);
251
- return client.sendYjsBinaryUpdate(roomId, afterUpdate);
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;
252
236
  }
253
- );
237
+ });
238
+ unsubscribe();
239
+ return val;
254
240
  }
255
241
  export {
256
242
  $createParagraphNode,
257
243
  $createTextNode,
258
244
  $getRoot2 as $getRoot,
259
- getEditor,
260
- getEditorState,
261
- getTextContent,
262
- modifyDocument
245
+ withLexicalDocument
263
246
  };
264
247
  //# sourceMappingURL=index.mjs.map
@@ -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 LexicalEditor,\n LexicalNode,\n LexicalNodeReplacement,\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// gets a sync'd headless editor\nexport async function getEditor(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>\n): Promise<LexicalEditor> {\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;\n }\n );\n}\n\n// gets text content\nexport async function getTextContent(\n client: Liveblocks,\n roomId: string,\n nodes: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>\n): Promise<string> {\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 let content: string = \"\";\n editor.getEditorState().read(() => {\n content = $getRoot().getTextContent();\n });\n return content;\n }\n );\n}\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: (editor: LexicalEditor) => 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 modifyFn(editor);\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": "1.12.0-lexical6",
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,15 +34,16 @@
33
34
  "test:watch": "jest --silent --verbose --color=always --watch"
34
35
  },
35
36
  "dependencies": {
36
- "@liveblocks/core": "1.12.0-lexical6",
37
- "@liveblocks/node": "1.12.0-lexical6",
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.14.5",
42
- "@lexical/selection": "0.14.3",
43
- "@lexical/yjs": "0.14.5",
44
- "lexical": "0.14.5"
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"
45
47
  },
46
48
  "devDependencies": {
47
49
  "@liveblocks/eslint-config": "*",