@liveblocks/react-tiptap 3.19.2 → 3.19.4-test1

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.
Files changed (52) hide show
  1. package/dist/LiveblocksExtension.cjs +51 -5
  2. package/dist/LiveblocksExtension.cjs.map +1 -1
  3. package/dist/LiveblocksExtension.js +51 -5
  4. package/dist/LiveblocksExtension.js.map +1 -1
  5. package/dist/ai/AiExtension.cjs +2 -1
  6. package/dist/ai/AiExtension.cjs.map +1 -1
  7. package/dist/ai/AiExtension.js +2 -1
  8. package/dist/ai/AiExtension.js.map +1 -1
  9. package/dist/collaboration-liveblocks/cursors.cjs +267 -0
  10. package/dist/collaboration-liveblocks/cursors.cjs.map +1 -0
  11. package/dist/collaboration-liveblocks/cursors.js +264 -0
  12. package/dist/collaboration-liveblocks/cursors.js.map +1 -0
  13. package/dist/collaboration-liveblocks/mapping.cjs +218 -0
  14. package/dist/collaboration-liveblocks/mapping.cjs.map +1 -0
  15. package/dist/collaboration-liveblocks/mapping.js +207 -0
  16. package/dist/collaboration-liveblocks/mapping.js.map +1 -0
  17. package/dist/collaboration-liveblocks/plugin.cjs +250 -0
  18. package/dist/collaboration-liveblocks/plugin.cjs.map +1 -0
  19. package/dist/collaboration-liveblocks/plugin.js +247 -0
  20. package/dist/collaboration-liveblocks/plugin.js.map +1 -0
  21. package/dist/collaboration-liveblocks/remote.cjs +196 -0
  22. package/dist/collaboration-liveblocks/remote.cjs.map +1 -0
  23. package/dist/collaboration-liveblocks/remote.js +193 -0
  24. package/dist/collaboration-liveblocks/remote.js.map +1 -0
  25. package/dist/collaboration-liveblocks/schema.cjs +150 -0
  26. package/dist/collaboration-liveblocks/schema.cjs.map +1 -0
  27. package/dist/collaboration-liveblocks/schema.js +135 -0
  28. package/dist/collaboration-liveblocks/schema.js.map +1 -0
  29. package/dist/collaboration-liveblocks/steps.cjs +359 -0
  30. package/dist/collaboration-liveblocks/steps.cjs.map +1 -0
  31. package/dist/collaboration-liveblocks/steps.js +356 -0
  32. package/dist/collaboration-liveblocks/steps.js.map +1 -0
  33. package/dist/comments/CommentsExtension.cjs +7 -1
  34. package/dist/comments/CommentsExtension.cjs.map +1 -1
  35. package/dist/comments/CommentsExtension.js +7 -1
  36. package/dist/comments/CommentsExtension.js.map +1 -1
  37. package/dist/index.d.cts +5 -0
  38. package/dist/index.d.ts +5 -0
  39. package/dist/mentions/MentionExtension.cjs +4 -1
  40. package/dist/mentions/MentionExtension.cjs.map +1 -1
  41. package/dist/mentions/MentionExtension.js +4 -1
  42. package/dist/mentions/MentionExtension.js.map +1 -1
  43. package/dist/types.cjs.map +1 -1
  44. package/dist/types.js.map +1 -1
  45. package/dist/version.cjs +1 -1
  46. package/dist/version.cjs.map +1 -1
  47. package/dist/version.js +1 -1
  48. package/dist/version.js.map +1 -1
  49. package/package.json +6 -6
  50. package/src/styles/index.css +12 -4
  51. package/styles.css +1 -1
  52. package/styles.css.map +1 -1
@@ -0,0 +1,207 @@
1
+ import { getLiveblocksNodeContent, getLiveblocksNodeId, getLiveblocksNodeType, getLiveblocksNodeText } from './schema.js';
2
+
3
+ function selectionToLiveblocksPosition(selection) {
4
+ return {
5
+ anchor: selection.anchor,
6
+ head: selection.head
7
+ };
8
+ }
9
+ function clampLiveblocksPosition(position, max) {
10
+ return {
11
+ anchor: Math.max(0, Math.min(position.anchor, max)),
12
+ head: Math.max(0, Math.min(position.head, max))
13
+ };
14
+ }
15
+ function childStart(parent, parentPos) {
16
+ return parent.type.name === "doc" ? parentPos : parentPos + 1;
17
+ }
18
+ function indexChildren(nodeRanges, listRanges, textRanges, pmParent, liveParent, parentPos) {
19
+ const liveContent = getLiveblocksNodeContent(liveParent);
20
+ if (liveContent === void 0) {
21
+ return;
22
+ }
23
+ listRanges.push({
24
+ content: liveContent,
25
+ from: parentPos,
26
+ node: liveParent,
27
+ nodeId: getLiveblocksNodeId(liveParent),
28
+ pmNode: pmParent,
29
+ to: parentPos + pmParent.nodeSize
30
+ });
31
+ let pmChildIndex = 0;
32
+ let pmOffset = 0;
33
+ const start = childStart(pmParent, parentPos);
34
+ for (let liveIndex = 0; liveIndex < liveContent.length; liveIndex++) {
35
+ const liveChild = liveContent.get(liveIndex);
36
+ const pmChild = pmParent.maybeChild(pmChildIndex);
37
+ if (liveChild === void 0 || pmChild === null) {
38
+ return;
39
+ }
40
+ const from = start + pmOffset;
41
+ const to = from + pmChild.nodeSize;
42
+ nodeRanges.push({
43
+ childIndex: liveIndex,
44
+ content: liveContent,
45
+ from,
46
+ node: liveChild,
47
+ nodeId: getLiveblocksNodeId(liveChild),
48
+ parent: liveParent,
49
+ pmNode: pmChild,
50
+ to
51
+ });
52
+ if (getLiveblocksNodeType(liveChild) === "text") {
53
+ const text = getLiveblocksNodeText(liveChild);
54
+ if (text === void 0) {
55
+ return;
56
+ }
57
+ let liveOffset = 0;
58
+ let remaining = text.length;
59
+ while (remaining > 0) {
60
+ const textChild = pmParent.maybeChild(pmChildIndex);
61
+ if (textChild === null || !textChild.isText) {
62
+ return;
63
+ }
64
+ const length = Math.min(remaining, textChild.nodeSize);
65
+ const textFrom = start + pmOffset;
66
+ textRanges.push({
67
+ from: textFrom,
68
+ to: textFrom + length,
69
+ liveOffset,
70
+ node: liveChild,
71
+ nodeId: getLiveblocksNodeId(liveChild),
72
+ text
73
+ });
74
+ liveOffset += length;
75
+ remaining -= length;
76
+ pmOffset += textChild.nodeSize;
77
+ pmChildIndex++;
78
+ }
79
+ } else {
80
+ indexChildren(
81
+ nodeRanges,
82
+ listRanges,
83
+ textRanges,
84
+ pmChild,
85
+ liveChild,
86
+ from
87
+ );
88
+ pmOffset += pmChild.nodeSize;
89
+ pmChildIndex++;
90
+ }
91
+ }
92
+ }
93
+ function buildLiveblocksTreeIndex(pmDoc, liveRoot) {
94
+ const nodeRanges = [
95
+ {
96
+ from: 0,
97
+ node: liveRoot,
98
+ nodeId: getLiveblocksNodeId(liveRoot),
99
+ pmNode: pmDoc,
100
+ to: pmDoc.content.size
101
+ }
102
+ ];
103
+ const listRanges = [];
104
+ const textRanges = [];
105
+ indexChildren(nodeRanges, listRanges, textRanges, pmDoc, liveRoot, 0);
106
+ return { listRanges, nodeRanges, textRanges };
107
+ }
108
+ function findTextRangeAtPosition(index, position) {
109
+ return index.textRanges.find(
110
+ (range) => position >= range.from && position <= range.to
111
+ );
112
+ }
113
+ function findTextRangeAtPositionInChildren(pmParent, liveParent, parentPos, position) {
114
+ const liveContent = getLiveblocksNodeContent(liveParent);
115
+ if (liveContent === void 0) {
116
+ return void 0;
117
+ }
118
+ let pmChildIndex = 0;
119
+ let pmOffset = 0;
120
+ const start = childStart(pmParent, parentPos);
121
+ for (let liveIndex = 0; liveIndex < liveContent.length; liveIndex++) {
122
+ const liveChild = liveContent.get(liveIndex);
123
+ const pmChild = pmParent.maybeChild(pmChildIndex);
124
+ if (liveChild === void 0 || pmChild === null) {
125
+ return void 0;
126
+ }
127
+ if (getLiveblocksNodeType(liveChild) === "text") {
128
+ const text = getLiveblocksNodeText(liveChild);
129
+ if (text === void 0) {
130
+ return void 0;
131
+ }
132
+ let liveOffset = 0;
133
+ let remaining = text.length;
134
+ while (remaining > 0) {
135
+ const textChild = pmParent.maybeChild(pmChildIndex);
136
+ if (textChild === null || !textChild.isText) {
137
+ return void 0;
138
+ }
139
+ const length = Math.min(remaining, textChild.nodeSize);
140
+ const from = start + pmOffset;
141
+ const to = from + length;
142
+ if (position >= from && position <= to) {
143
+ return {
144
+ from,
145
+ to,
146
+ liveOffset,
147
+ node: liveChild,
148
+ nodeId: getLiveblocksNodeId(liveChild),
149
+ text
150
+ };
151
+ }
152
+ liveOffset += length;
153
+ remaining -= length;
154
+ pmOffset += textChild.nodeSize;
155
+ pmChildIndex++;
156
+ }
157
+ } else {
158
+ const from = start + pmOffset;
159
+ const to = from + pmChild.nodeSize;
160
+ if (position >= from && position <= to) {
161
+ return findTextRangeAtPositionInChildren(
162
+ pmChild,
163
+ liveChild,
164
+ from,
165
+ position
166
+ );
167
+ }
168
+ pmOffset += pmChild.nodeSize;
169
+ pmChildIndex++;
170
+ }
171
+ }
172
+ return void 0;
173
+ }
174
+ function findTextRangeAtPositionInDocument(pmDoc, liveRoot, position) {
175
+ return findTextRangeAtPositionInChildren(pmDoc, liveRoot, 0, position);
176
+ }
177
+ function findTextRangesInRange(index, from, to) {
178
+ return index.textRanges.filter(
179
+ (range) => Math.max(range.from, from) < Math.min(range.to, to)
180
+ );
181
+ }
182
+ function findTextRangeByLiveText(index, text) {
183
+ return index.textRanges.find((range) => range.text === text);
184
+ }
185
+ function findNodeRangeByLiveNode(index, node) {
186
+ return index.nodeRanges.find((range) => range.node === node);
187
+ }
188
+ function findListRangeByLiveList(index, content) {
189
+ return index.listRanges.find((range) => range.content === content);
190
+ }
191
+ function getChildPosition(parent, parentPos, index) {
192
+ if (index < 0 || index > parent.childCount) {
193
+ return void 0;
194
+ }
195
+ let offset = 0;
196
+ for (let childIndex = 0; childIndex < index; childIndex++) {
197
+ const child = parent.maybeChild(childIndex);
198
+ if (child === null) {
199
+ return void 0;
200
+ }
201
+ offset += child.nodeSize;
202
+ }
203
+ return childStart(parent, parentPos) + offset;
204
+ }
205
+
206
+ export { buildLiveblocksTreeIndex, clampLiveblocksPosition, findListRangeByLiveList, findNodeRangeByLiveNode, findTextRangeAtPosition, findTextRangeAtPositionInDocument, findTextRangeByLiveText, findTextRangesInRange, getChildPosition, selectionToLiveblocksPosition };
207
+ //# sourceMappingURL=mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapping.js","sources":["../../src/collaboration-liveblocks/mapping.ts"],"sourcesContent":["import type { LiveList, LiveText } from \"@liveblocks/client\";\nimport type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport type { Selection } from \"@tiptap/pm/state\";\n\nimport {\n getLiveblocksNodeContent,\n getLiveblocksNodeId,\n getLiveblocksNodeText,\n getLiveblocksNodeType,\n type LiveblocksTiptapNode,\n} from \"./schema\";\n\nexport type LiveblocksTiptapPosition = {\n anchor: number;\n head: number;\n};\n\nexport function selectionToLiveblocksPosition(\n selection: Selection\n): LiveblocksTiptapPosition {\n return {\n anchor: selection.anchor,\n head: selection.head,\n };\n}\n\nexport function clampLiveblocksPosition(\n position: LiveblocksTiptapPosition,\n max: number\n): LiveblocksTiptapPosition {\n return {\n anchor: Math.max(0, Math.min(position.anchor, max)),\n head: Math.max(0, Math.min(position.head, max)),\n };\n}\n\nexport type LiveblocksTextRange = {\n from: number;\n to: number;\n liveOffset: number;\n node: LiveblocksTiptapNode;\n nodeId: string;\n text: LiveText;\n};\n\nexport type LiveblocksNodeRange = {\n childIndex?: number;\n content?: LiveList<LiveblocksTiptapNode>;\n from: number;\n node: LiveblocksTiptapNode;\n nodeId: string;\n parent?: LiveblocksTiptapNode;\n pmNode: ProseMirrorNode;\n to: number;\n};\n\nexport type LiveblocksListRange = {\n content: LiveList<LiveblocksTiptapNode>;\n from: number;\n node: LiveblocksTiptapNode;\n nodeId: string;\n pmNode: ProseMirrorNode;\n to: number;\n};\n\nexport type LiveblocksTreeIndex = {\n listRanges: LiveblocksListRange[];\n nodeRanges: LiveblocksNodeRange[];\n textRanges: LiveblocksTextRange[];\n};\n\nfunction childStart(parent: ProseMirrorNode, parentPos: number): number {\n return parent.type.name === \"doc\" ? parentPos : parentPos + 1;\n}\n\nfunction indexChildren(\n nodeRanges: LiveblocksNodeRange[],\n listRanges: LiveblocksListRange[],\n textRanges: LiveblocksTextRange[],\n pmParent: ProseMirrorNode,\n liveParent: LiveblocksTiptapNode,\n parentPos: number\n): void {\n const liveContent = getLiveblocksNodeContent(liveParent);\n if (liveContent === undefined) {\n return;\n }\n\n listRanges.push({\n content: liveContent,\n from: parentPos,\n node: liveParent,\n nodeId: getLiveblocksNodeId(liveParent),\n pmNode: pmParent,\n to: parentPos + pmParent.nodeSize,\n });\n\n let pmChildIndex = 0;\n let pmOffset = 0;\n const start = childStart(pmParent, parentPos);\n\n for (let liveIndex = 0; liveIndex < liveContent.length; liveIndex++) {\n const liveChild = liveContent.get(liveIndex);\n const pmChild = pmParent.maybeChild(pmChildIndex);\n if (liveChild === undefined || pmChild === null) {\n return;\n }\n\n const from = start + pmOffset;\n const to = from + pmChild.nodeSize;\n\n nodeRanges.push({\n childIndex: liveIndex,\n content: liveContent,\n from,\n node: liveChild,\n nodeId: getLiveblocksNodeId(liveChild),\n parent: liveParent,\n pmNode: pmChild,\n to,\n });\n\n if (getLiveblocksNodeType(liveChild) === \"text\") {\n const text = getLiveblocksNodeText(liveChild);\n if (text === undefined) {\n return;\n }\n\n let liveOffset = 0;\n let remaining = text.length;\n\n while (remaining > 0) {\n const textChild = pmParent.maybeChild(pmChildIndex);\n if (textChild === null || !textChild.isText) {\n return;\n }\n\n const length = Math.min(remaining, textChild.nodeSize);\n const textFrom = start + pmOffset;\n\n textRanges.push({\n from: textFrom,\n to: textFrom + length,\n liveOffset,\n node: liveChild,\n nodeId: getLiveblocksNodeId(liveChild),\n text,\n });\n\n liveOffset += length;\n remaining -= length;\n pmOffset += textChild.nodeSize;\n pmChildIndex++;\n }\n } else {\n indexChildren(\n nodeRanges,\n listRanges,\n textRanges,\n pmChild,\n liveChild,\n from\n );\n pmOffset += pmChild.nodeSize;\n pmChildIndex++;\n }\n }\n}\n\nexport function buildLiveblocksTreeIndex(\n pmDoc: ProseMirrorNode,\n liveRoot: LiveblocksTiptapNode\n): LiveblocksTreeIndex {\n const nodeRanges: LiveblocksNodeRange[] = [\n {\n from: 0,\n node: liveRoot,\n nodeId: getLiveblocksNodeId(liveRoot),\n pmNode: pmDoc,\n to: pmDoc.content.size,\n },\n ];\n const listRanges: LiveblocksListRange[] = [];\n const textRanges: LiveblocksTextRange[] = [];\n indexChildren(nodeRanges, listRanges, textRanges, pmDoc, liveRoot, 0);\n return { listRanges, nodeRanges, textRanges };\n}\n\nexport function findTextRangeAtPosition(\n index: LiveblocksTreeIndex,\n position: number\n): LiveblocksTextRange | undefined {\n return index.textRanges.find(\n (range) => position >= range.from && position <= range.to\n );\n}\n\nfunction findTextRangeAtPositionInChildren(\n pmParent: ProseMirrorNode,\n liveParent: LiveblocksTiptapNode,\n parentPos: number,\n position: number\n): LiveblocksTextRange | undefined {\n const liveContent = getLiveblocksNodeContent(liveParent);\n if (liveContent === undefined) {\n return undefined;\n }\n\n let pmChildIndex = 0;\n let pmOffset = 0;\n const start = childStart(pmParent, parentPos);\n\n for (let liveIndex = 0; liveIndex < liveContent.length; liveIndex++) {\n const liveChild = liveContent.get(liveIndex);\n const pmChild = pmParent.maybeChild(pmChildIndex);\n if (liveChild === undefined || pmChild === null) {\n return undefined;\n }\n\n if (getLiveblocksNodeType(liveChild) === \"text\") {\n const text = getLiveblocksNodeText(liveChild);\n if (text === undefined) {\n return undefined;\n }\n\n let liveOffset = 0;\n let remaining = text.length;\n\n while (remaining > 0) {\n const textChild = pmParent.maybeChild(pmChildIndex);\n if (textChild === null || !textChild.isText) {\n return undefined;\n }\n\n const length = Math.min(remaining, textChild.nodeSize);\n const from = start + pmOffset;\n const to = from + length;\n\n if (position >= from && position <= to) {\n return {\n from,\n to,\n liveOffset,\n node: liveChild,\n nodeId: getLiveblocksNodeId(liveChild),\n text,\n };\n }\n\n liveOffset += length;\n remaining -= length;\n pmOffset += textChild.nodeSize;\n pmChildIndex++;\n }\n } else {\n const from = start + pmOffset;\n const to = from + pmChild.nodeSize;\n\n if (position >= from && position <= to) {\n return findTextRangeAtPositionInChildren(\n pmChild,\n liveChild,\n from,\n position\n );\n }\n\n pmOffset += pmChild.nodeSize;\n pmChildIndex++;\n }\n }\n\n return undefined;\n}\n\nexport function findTextRangeAtPositionInDocument(\n pmDoc: ProseMirrorNode,\n liveRoot: LiveblocksTiptapNode,\n position: number\n): LiveblocksTextRange | undefined {\n return findTextRangeAtPositionInChildren(pmDoc, liveRoot, 0, position);\n}\n\nexport function findTextRangesInRange(\n index: LiveblocksTreeIndex,\n from: number,\n to: number\n): LiveblocksTextRange[] {\n return index.textRanges.filter(\n (range) => Math.max(range.from, from) < Math.min(range.to, to)\n );\n}\n\nexport function findTextRangeByLiveText(\n index: LiveblocksTreeIndex,\n text: LiveText\n): LiveblocksTextRange | undefined {\n return index.textRanges.find((range) => range.text === text);\n}\n\nexport function findNodeRangeByLiveNode(\n index: LiveblocksTreeIndex,\n node: LiveblocksTiptapNode\n): LiveblocksNodeRange | undefined {\n return index.nodeRanges.find((range) => range.node === node);\n}\n\nexport function findListRangeByLiveList(\n index: LiveblocksTreeIndex,\n content: unknown\n): LiveblocksListRange | undefined {\n return index.listRanges.find((range) => range.content === content);\n}\n\nexport function getChildPosition(\n parent: ProseMirrorNode,\n parentPos: number,\n index: number\n): number | undefined {\n if (index < 0 || index > parent.childCount) {\n return undefined;\n }\n\n let offset = 0;\n for (let childIndex = 0; childIndex < index; childIndex++) {\n const child = parent.maybeChild(childIndex);\n if (child === null) {\n return undefined;\n }\n\n offset += child.nodeSize;\n }\n\n return childStart(parent, parentPos) + offset;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,250 @@
1
+ 'use strict';
2
+
3
+ var client = require('@liveblocks/client');
4
+ var core = require('@tiptap/core');
5
+ var model = require('@tiptap/pm/model');
6
+ var state = require('@tiptap/pm/state');
7
+ var remote = require('./remote.cjs');
8
+ var schema = require('./schema.cjs');
9
+ var steps = require('./steps.cjs');
10
+
11
+ const LIVEBLOCKS_COLLABORATION_PLUGIN_KEY = new state.PluginKey("liveblocks-collaboration");
12
+ function isProseMirrorJsonNode(value) {
13
+ return typeof value === "object" && value !== null && typeof value.type === "string";
14
+ }
15
+ function getInitialDocument(initialContent, view) {
16
+ if (isProseMirrorJsonNode(initialContent)) {
17
+ return initialContent;
18
+ }
19
+ const currentDocument = view.state.doc.toJSON();
20
+ if (isProseMirrorJsonNode(currentDocument)) {
21
+ return currentDocument;
22
+ }
23
+ return schema.createDefaultDocument();
24
+ }
25
+ function replaceEditorDocument(view, document) {
26
+ const nextDocument = view.state.schema.nodeFromJSON(document);
27
+ const diffStart = view.state.doc.content.findDiffStart(nextDocument.content);
28
+ if (diffStart === null || !view.state.tr) {
29
+ return;
30
+ }
31
+ const diffEnd = view.state.doc.content.findDiffEnd(nextDocument.content);
32
+ const tr = diffEnd === null ? view.state.tr.replace(
33
+ 0,
34
+ view.state.doc.content.size,
35
+ new model.Slice(nextDocument.content, 0, 0)
36
+ ) : view.state.tr.replace(
37
+ diffStart,
38
+ diffEnd.a,
39
+ nextDocument.slice(diffStart, diffEnd.b)
40
+ );
41
+ tr.setMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY, { isRemote: true }).setMeta(
42
+ "addToHistory",
43
+ false
44
+ );
45
+ view.dispatch(tr);
46
+ }
47
+ function getDocumentRoot(root, field) {
48
+ const documentRoot = root.get(field);
49
+ if (!(documentRoot instanceof client.LiveObject)) {
50
+ return void 0;
51
+ }
52
+ return documentRoot;
53
+ }
54
+ function setDocumentRoot(root, field, document) {
55
+ root.set(field, schema.createLiveblocksTiptapNode(document));
56
+ }
57
+ function createLiveblocksCollaborationPlugin(options) {
58
+ const room = options.room;
59
+ if (room === void 0) {
60
+ throw new Error(
61
+ "[Liveblocks] The Liveblocks collaboration plugin requires a room."
62
+ );
63
+ }
64
+ let view;
65
+ let root;
66
+ let unsubscribe;
67
+ let destroyed = false;
68
+ let isApplyingRemoteUpdate = false;
69
+ let isApplyingLocalUpdate = false;
70
+ let lastDocument = "";
71
+ const applyStorageToEditor = (updates) => {
72
+ if (view === void 0 || root === void 0) {
73
+ return;
74
+ }
75
+ const documentRoot = getDocumentRoot(root, options.field);
76
+ if (documentRoot === void 0) {
77
+ return;
78
+ }
79
+ if (isApplyingLocalUpdate) {
80
+ return;
81
+ }
82
+ const document = schema.liveblocksTiptapNodeToJson(documentRoot);
83
+ const serializedDocument = schema.stringifyDocument(document);
84
+ if (serializedDocument === lastDocument) {
85
+ return;
86
+ }
87
+ if (updates !== void 0) {
88
+ const result = remote.applyRemoteStorageUpdates(view, documentRoot, updates);
89
+ if (result.type === "applied") {
90
+ lastDocument = serializedDocument;
91
+ isApplyingRemoteUpdate = true;
92
+ try {
93
+ view.dispatch(
94
+ result.tr.setMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY, { isRemote: true }).setMeta("addToHistory", false)
95
+ );
96
+ } finally {
97
+ isApplyingRemoteUpdate = false;
98
+ }
99
+ return;
100
+ }
101
+ }
102
+ lastDocument = serializedDocument;
103
+ isApplyingRemoteUpdate = true;
104
+ try {
105
+ replaceEditorDocument(view, document);
106
+ } finally {
107
+ isApplyingRemoteUpdate = false;
108
+ }
109
+ };
110
+ return new state.Plugin({
111
+ key: LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,
112
+ state: {
113
+ init: () => ({ isReady: false }),
114
+ apply(tr, state) {
115
+ const meta = tr.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY);
116
+ return meta?.isReady !== void 0 ? { ...state, isReady: meta.isReady } : state;
117
+ }
118
+ },
119
+ appendTransaction(transactions, oldState, newState) {
120
+ if (root === void 0 || isApplyingRemoteUpdate || !transactions.some((transaction) => transaction.docChanged) || transactions.some(
121
+ (transaction) => Boolean(transaction.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY))
122
+ )) {
123
+ return null;
124
+ }
125
+ const currentRoot = root;
126
+ const documentRoot = getDocumentRoot(currentRoot, options.field);
127
+ const classified = documentRoot !== void 0 ? steps.classifyTransaction(
128
+ transactions,
129
+ oldState.doc,
130
+ newState.doc,
131
+ documentRoot
132
+ ) : { type: "unsupported" };
133
+ room.batch(() => {
134
+ if (classified.type === "incremental") {
135
+ isApplyingLocalUpdate = true;
136
+ try {
137
+ steps.applyIncrementalOperations(classified.operations);
138
+ } finally {
139
+ isApplyingLocalUpdate = false;
140
+ }
141
+ } else {
142
+ const document = newState.doc.toJSON();
143
+ if (!isProseMirrorJsonNode(document)) {
144
+ return;
145
+ }
146
+ const serializedDocument = schema.stringifyDocument(document);
147
+ if (serializedDocument === lastDocument) {
148
+ return;
149
+ }
150
+ lastDocument = serializedDocument;
151
+ setDocumentRoot(currentRoot, options.field, document);
152
+ }
153
+ });
154
+ return null;
155
+ },
156
+ view(editorView) {
157
+ view = editorView;
158
+ room.getStorage().then(({ root: storageRoot }) => {
159
+ if (destroyed) {
160
+ return;
161
+ }
162
+ root = storageRoot;
163
+ if (getDocumentRoot(storageRoot, options.field) === void 0) {
164
+ const initialDocument = getInitialDocument(
165
+ options.initialContent,
166
+ editorView
167
+ );
168
+ room.history.disable(() => {
169
+ setDocumentRoot(storageRoot, options.field, initialDocument);
170
+ });
171
+ }
172
+ applyStorageToEditor();
173
+ const tr = editorView.state.tr.setMeta(
174
+ LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,
175
+ { isReady: true }
176
+ );
177
+ editorView.dispatch(tr);
178
+ unsubscribe = room.subscribe(storageRoot, applyStorageToEditor, {
179
+ isDeep: true
180
+ });
181
+ });
182
+ return {
183
+ update(nextView) {
184
+ view = nextView;
185
+ },
186
+ destroy() {
187
+ destroyed = true;
188
+ unsubscribe?.();
189
+ unsubscribe = void 0;
190
+ view = void 0;
191
+ root = void 0;
192
+ }
193
+ };
194
+ }
195
+ });
196
+ }
197
+ const LiveblocksCollaboration = core.Extension.create({
198
+ name: "collaboration",
199
+ priority: 1e3,
200
+ addOptions() {
201
+ return {
202
+ room: void 0,
203
+ field: "default",
204
+ initialContent: void 0
205
+ };
206
+ },
207
+ addStorage() {
208
+ return {
209
+ isDisabled: false
210
+ };
211
+ },
212
+ addCommands() {
213
+ return {
214
+ undo: () => ({ dispatch, tr }) => {
215
+ tr.setMeta("preventDispatch", true);
216
+ if (this.options.room === void 0 || !this.options.room.history.canUndo()) {
217
+ return false;
218
+ }
219
+ if (dispatch) {
220
+ this.options.room.history.undo();
221
+ }
222
+ return true;
223
+ },
224
+ redo: () => ({ dispatch, tr }) => {
225
+ tr.setMeta("preventDispatch", true);
226
+ if (this.options.room === void 0 || !this.options.room.history.canRedo()) {
227
+ return false;
228
+ }
229
+ if (dispatch) {
230
+ this.options.room.history.redo();
231
+ }
232
+ return true;
233
+ }
234
+ };
235
+ },
236
+ addKeyboardShortcuts() {
237
+ return {
238
+ "Mod-z": () => this.editor.commands.undo(),
239
+ "Mod-y": () => this.editor.commands.redo(),
240
+ "Shift-Mod-z": () => this.editor.commands.redo()
241
+ };
242
+ },
243
+ addProseMirrorPlugins() {
244
+ return [createLiveblocksCollaborationPlugin(this.options)];
245
+ }
246
+ });
247
+
248
+ exports.LIVEBLOCKS_COLLABORATION_PLUGIN_KEY = LIVEBLOCKS_COLLABORATION_PLUGIN_KEY;
249
+ exports.LiveblocksCollaboration = LiveblocksCollaboration;
250
+ //# sourceMappingURL=plugin.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs","sources":["../../src/collaboration-liveblocks/plugin.ts"],"sourcesContent":["import type { LsonObject, StorageUpdate } from \"@liveblocks/client\";\nimport { LiveObject } from \"@liveblocks/client\";\nimport type { Content } from \"@tiptap/core\";\nimport { Extension } from \"@tiptap/core\";\nimport { Slice } from \"@tiptap/pm/model\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\n\nimport { applyRemoteStorageUpdates } from \"./remote\";\nimport {\n createDefaultDocument,\n createLiveblocksTiptapNode,\n type LiveblocksTiptapNode,\n liveblocksTiptapNodeToJson,\n type ProseMirrorJsonNode,\n stringifyDocument,\n} from \"./schema\";\nimport { applyIncrementalOperations, classifyTransaction } from \"./steps\";\nimport type { LiveblocksTiptapRoom } from \"./types\";\n\nexport const LIVEBLOCKS_COLLABORATION_PLUGIN_KEY = new PluginKey<{\n isReady: boolean;\n}>(\"liveblocks-collaboration\");\n\ntype LiveblocksCollaborationOptions = {\n room?: LiveblocksTiptapRoom;\n field: string;\n initialContent?: Content;\n};\n\ntype LiveblocksCollaborationStorage = {\n isDisabled: boolean;\n};\n\nfunction isProseMirrorJsonNode(value: unknown): value is ProseMirrorJsonNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n );\n}\n\nfunction getInitialDocument(\n initialContent: Content | undefined,\n view: EditorView\n): ProseMirrorJsonNode {\n if (isProseMirrorJsonNode(initialContent)) {\n return initialContent;\n }\n\n const currentDocument: unknown = view.state.doc.toJSON();\n if (isProseMirrorJsonNode(currentDocument)) {\n return currentDocument;\n }\n\n return createDefaultDocument();\n}\n\nfunction replaceEditorDocument(\n view: EditorView,\n document: ProseMirrorJsonNode\n): void {\n const nextDocument = view.state.schema.nodeFromJSON(document);\n const diffStart = view.state.doc.content.findDiffStart(nextDocument.content);\n\n if (diffStart === null || !view.state.tr) {\n return;\n }\n\n const diffEnd = view.state.doc.content.findDiffEnd(nextDocument.content);\n const tr =\n diffEnd === null\n ? view.state.tr.replace(\n 0,\n view.state.doc.content.size,\n new Slice(nextDocument.content, 0, 0)\n )\n : view.state.tr.replace(\n diffStart,\n diffEnd.a,\n nextDocument.slice(diffStart, diffEnd.b)\n );\n\n tr.setMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY, { isRemote: true }).setMeta(\n \"addToHistory\",\n false\n );\n\n view.dispatch(tr);\n}\n\nfunction getDocumentRoot(\n root: LiveObject<LsonObject>,\n field: string\n): LiveblocksTiptapNode | undefined {\n const documentRoot = root.get(field);\n if (!(documentRoot instanceof LiveObject)) {\n return undefined;\n }\n\n return documentRoot as LiveblocksTiptapNode;\n}\n\nfunction setDocumentRoot(\n root: LiveObject<LsonObject>,\n field: string,\n document: ProseMirrorJsonNode\n): void {\n root.set(field, createLiveblocksTiptapNode(document));\n}\n\nfunction createLiveblocksCollaborationPlugin(\n options: LiveblocksCollaborationOptions\n): Plugin {\n const room = options.room;\n if (room === undefined) {\n throw new Error(\n \"[Liveblocks] The Liveblocks collaboration plugin requires a room.\"\n );\n }\n\n let view: EditorView | undefined;\n let root: LiveObject<LsonObject> | undefined;\n let unsubscribe: (() => void) | undefined;\n let destroyed = false;\n let isApplyingRemoteUpdate = false;\n let isApplyingLocalUpdate = false;\n let lastDocument = \"\";\n\n const applyStorageToEditor = (updates?: StorageUpdate[]) => {\n if (view === undefined || root === undefined) {\n return;\n }\n\n const documentRoot = getDocumentRoot(root, options.field);\n if (documentRoot === undefined) {\n return;\n }\n\n if (isApplyingLocalUpdate) {\n return;\n }\n\n const document = liveblocksTiptapNodeToJson(documentRoot);\n const serializedDocument = stringifyDocument(document);\n\n if (serializedDocument === lastDocument) {\n return;\n }\n\n if (updates !== undefined) {\n const result = applyRemoteStorageUpdates(view, documentRoot, updates);\n if (result.type === \"applied\") {\n lastDocument = serializedDocument;\n isApplyingRemoteUpdate = true;\n try {\n view.dispatch(\n result.tr\n .setMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY, { isRemote: true })\n .setMeta(\"addToHistory\", false)\n );\n } finally {\n isApplyingRemoteUpdate = false;\n }\n return;\n }\n }\n\n lastDocument = serializedDocument;\n isApplyingRemoteUpdate = true;\n try {\n replaceEditorDocument(view, document);\n } finally {\n isApplyingRemoteUpdate = false;\n }\n };\n\n return new Plugin({\n key: LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,\n state: {\n init: () => ({ isReady: false }),\n apply(tr, state) {\n const meta = tr.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY) as\n | { isReady?: boolean }\n | undefined;\n\n return meta?.isReady !== undefined\n ? { ...state, isReady: meta.isReady }\n : state;\n },\n },\n appendTransaction(transactions, oldState, newState) {\n if (\n root === undefined ||\n isApplyingRemoteUpdate ||\n !transactions.some((transaction) => transaction.docChanged) ||\n transactions.some((transaction) =>\n Boolean(transaction.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY))\n )\n ) {\n return null;\n }\n\n const currentRoot = root;\n\n const documentRoot = getDocumentRoot(currentRoot, options.field);\n const classified =\n documentRoot !== undefined\n ? classifyTransaction(\n transactions,\n oldState.doc,\n newState.doc,\n documentRoot\n )\n : { type: \"unsupported\" as const };\n\n room.batch(() => {\n if (classified.type === \"incremental\") {\n isApplyingLocalUpdate = true;\n try {\n applyIncrementalOperations(classified.operations);\n } finally {\n isApplyingLocalUpdate = false;\n }\n } else {\n const document: unknown = newState.doc.toJSON();\n if (!isProseMirrorJsonNode(document)) {\n return;\n }\n\n const serializedDocument = stringifyDocument(document);\n if (serializedDocument === lastDocument) {\n return;\n }\n\n lastDocument = serializedDocument;\n setDocumentRoot(currentRoot, options.field, document);\n }\n });\n\n return null;\n },\n view(editorView) {\n view = editorView;\n\n room.getStorage().then(({ root: storageRoot }) => {\n if (destroyed) {\n return;\n }\n\n root = storageRoot;\n\n if (getDocumentRoot(storageRoot, options.field) === undefined) {\n const initialDocument = getInitialDocument(\n options.initialContent,\n editorView\n );\n room.history.disable(() => {\n setDocumentRoot(storageRoot, options.field, initialDocument);\n });\n }\n\n applyStorageToEditor();\n\n const tr = editorView.state.tr.setMeta(\n LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,\n { isReady: true }\n );\n editorView.dispatch(tr);\n\n unsubscribe = room.subscribe(storageRoot, applyStorageToEditor, {\n isDeep: true,\n });\n });\n\n return {\n update(nextView) {\n view = nextView;\n },\n destroy() {\n destroyed = true;\n unsubscribe?.();\n unsubscribe = undefined;\n view = undefined;\n root = undefined;\n },\n };\n },\n });\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaboration: {\n undo: () => ReturnType;\n redo: () => ReturnType;\n };\n }\n}\n\nexport const LiveblocksCollaboration = Extension.create<\n LiveblocksCollaborationOptions,\n LiveblocksCollaborationStorage\n>({\n name: \"collaboration\",\n priority: 1000,\n\n addOptions() {\n return {\n room: undefined,\n field: \"default\",\n initialContent: undefined,\n };\n },\n\n addStorage() {\n return {\n isDisabled: false,\n };\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ dispatch, tr }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n if (\n this.options.room === undefined ||\n !this.options.room.history.canUndo()\n ) {\n return false;\n }\n\n if (dispatch) {\n this.options.room.history.undo();\n }\n\n return true;\n },\n redo:\n () =>\n ({ dispatch, tr }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n if (\n this.options.room === undefined ||\n !this.options.room.history.canRedo()\n ) {\n return false;\n }\n\n if (dispatch) {\n this.options.room.history.redo();\n }\n\n return true;\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n };\n },\n\n addProseMirrorPlugins() {\n return [createLiveblocksCollaborationPlugin(this.options)];\n },\n});\n"],"names":["PluginKey","createDefaultDocument","Slice","LiveObject","createLiveblocksTiptapNode","liveblocksTiptapNodeToJson","stringifyDocument","applyRemoteStorageUpdates","Plugin","classifyTransaction","applyIncrementalOperations","Extension"],"mappings":"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"}