@liveblocks/prosemirror 0.0.0 → 3.21.0-exp10
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/LICENSE +16 -0
- package/README.md +3 -0
- package/dist/cursors.cjs +217 -0
- package/dist/cursors.cjs.map +1 -0
- package/dist/cursors.js +211 -0
- package/dist/cursors.js.map +1 -0
- package/dist/index.cjs +24 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +109 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mapping.cjs +218 -0
- package/dist/mapping.cjs.map +1 -0
- package/dist/mapping.js +207 -0
- package/dist/mapping.js.map +1 -0
- package/dist/plugin.cjs +240 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.js +236 -0
- package/dist/plugin.js.map +1 -0
- package/dist/remote.cjs +273 -0
- package/dist/remote.cjs.map +1 -0
- package/dist/remote.js +270 -0
- package/dist/remote.js.map +1 -0
- package/dist/schema.cjs +149 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.js +135 -0
- package/dist/schema.js.map +1 -0
- package/dist/steps.cjs +359 -0
- package/dist/steps.cjs.map +1 -0
- package/dist/steps.js +356 -0
- package/dist/steps.js.map +1 -0
- package/dist/version.cjs +10 -0
- package/dist/version.cjs.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +55 -3
- package/index.js +0 -1
package/dist/schema.cjs
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var client = require('@liveblocks/client');
|
|
4
|
+
|
|
5
|
+
const TEXT_MARKS_ATTRIBUTE = "__liveblocks_tiptap_marks";
|
|
6
|
+
function isJsonObject(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function marksToAttributes(marks) {
|
|
10
|
+
if (marks === void 0 || marks.length === 0) {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
[TEXT_MARKS_ATTRIBUTE]: marks.map((mark) => ({
|
|
15
|
+
type: mark.type,
|
|
16
|
+
...mark.attrs !== void 0 ? { attrs: mark.attrs } : {}
|
|
17
|
+
}))
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function attributesToMarks(attributes) {
|
|
21
|
+
const rawMarks = attributes?.[TEXT_MARKS_ATTRIBUTE];
|
|
22
|
+
if (!Array.isArray(rawMarks)) {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
const marks = [];
|
|
26
|
+
for (const rawMark of rawMarks) {
|
|
27
|
+
if (!isJsonObject(rawMark) || typeof rawMark.type !== "string") {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
marks.push({
|
|
31
|
+
type: rawMark.type,
|
|
32
|
+
...isJsonObject(rawMark.attrs) ? { attrs: rawMark.attrs } : {}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return marks.length > 0 ? marks : void 0;
|
|
36
|
+
}
|
|
37
|
+
function marksToAttributesPatch(marks) {
|
|
38
|
+
const attributes = marksToAttributes(marks);
|
|
39
|
+
return {
|
|
40
|
+
[TEXT_MARKS_ATTRIBUTE]: attributes?.[TEXT_MARKS_ATTRIBUTE] === void 0 ? null : attributes[TEXT_MARKS_ATTRIBUTE]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function createLiveblocksProsemirrorNode(node) {
|
|
44
|
+
if (node.type === "text") {
|
|
45
|
+
const text = new client.LiveText();
|
|
46
|
+
text.insert(0, node.text ?? "", marksToAttributes(node.marks));
|
|
47
|
+
return new client.LiveObject({
|
|
48
|
+
id: client.nanoid(),
|
|
49
|
+
type: node.type,
|
|
50
|
+
text
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return new client.LiveObject({
|
|
54
|
+
id: client.nanoid(),
|
|
55
|
+
type: node.type,
|
|
56
|
+
...node.attrs !== void 0 ? { attrs: node.attrs } : {},
|
|
57
|
+
content: new client.LiveList(
|
|
58
|
+
(node.content ?? []).map((child) => createLiveblocksProsemirrorNode(child))
|
|
59
|
+
)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function getLiveblocksNodeId(node) {
|
|
63
|
+
return node.get("id");
|
|
64
|
+
}
|
|
65
|
+
function getLiveblocksNodeType(node) {
|
|
66
|
+
return node.get("type");
|
|
67
|
+
}
|
|
68
|
+
function getLiveblocksNodeContent(node) {
|
|
69
|
+
const content = node.get("content");
|
|
70
|
+
return content instanceof client.LiveList ? content : void 0;
|
|
71
|
+
}
|
|
72
|
+
function getLiveblocksNodeText(node) {
|
|
73
|
+
const text = node.get("text");
|
|
74
|
+
return text instanceof client.LiveText ? text : void 0;
|
|
75
|
+
}
|
|
76
|
+
function updateLiveblocksNodeAttrs(node, attrs) {
|
|
77
|
+
if (attrs === void 0) {
|
|
78
|
+
node.delete("attrs");
|
|
79
|
+
} else {
|
|
80
|
+
node.set("attrs", attrs);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function liveTextToTextNodes(text) {
|
|
84
|
+
const nodes = [];
|
|
85
|
+
for (const [segmentText, segmentAttributes] of text.toJSON()) {
|
|
86
|
+
if (segmentText.length === 0) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
nodes.push({
|
|
90
|
+
type: "text",
|
|
91
|
+
text: segmentText,
|
|
92
|
+
...segmentAttributes !== void 0 ? { marks: attributesToMarks(segmentAttributes) } : {}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return nodes;
|
|
96
|
+
}
|
|
97
|
+
function liveblocksProsemirrorNodeToJsonNodes(node) {
|
|
98
|
+
const type = node.get("type");
|
|
99
|
+
if (type === "text") {
|
|
100
|
+
const text = node.get("text");
|
|
101
|
+
return text instanceof client.LiveText ? liveTextToTextNodes(text) : [];
|
|
102
|
+
}
|
|
103
|
+
const content = node.get("content");
|
|
104
|
+
const jsonNode = {
|
|
105
|
+
type,
|
|
106
|
+
...node.get("attrs") !== void 0 ? { attrs: node.get("attrs") } : {}
|
|
107
|
+
};
|
|
108
|
+
if (content instanceof client.LiveList && content.length > 0) {
|
|
109
|
+
const children = [];
|
|
110
|
+
for (let index = 0; index < content.length; index++) {
|
|
111
|
+
const child = content.get(index);
|
|
112
|
+
if (child !== void 0) {
|
|
113
|
+
children.push(...liveblocksProsemirrorNodeToJsonNodes(child));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (children.length > 0) {
|
|
117
|
+
jsonNode.content = children;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return [jsonNode];
|
|
121
|
+
}
|
|
122
|
+
function liveblocksProsemirrorNodeToJson(node, fallbackDocument) {
|
|
123
|
+
const [jsonNode] = liveblocksProsemirrorNodeToJsonNodes(node);
|
|
124
|
+
if (jsonNode === void 0 || jsonNode.type === "doc" && (!Array.isArray(jsonNode.content) || jsonNode.content.length === 0)) {
|
|
125
|
+
const fallback = fallbackDocument?.();
|
|
126
|
+
if (fallback !== void 0) {
|
|
127
|
+
return fallback;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return jsonNode ?? { type: node.get("type") };
|
|
131
|
+
}
|
|
132
|
+
function stringifyDocument(node) {
|
|
133
|
+
return JSON.stringify(node);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
exports.TEXT_MARKS_ATTRIBUTE = TEXT_MARKS_ATTRIBUTE;
|
|
137
|
+
exports.attributesToMarks = attributesToMarks;
|
|
138
|
+
exports.createLiveblocksProsemirrorNode = createLiveblocksProsemirrorNode;
|
|
139
|
+
exports.getLiveblocksNodeContent = getLiveblocksNodeContent;
|
|
140
|
+
exports.getLiveblocksNodeId = getLiveblocksNodeId;
|
|
141
|
+
exports.getLiveblocksNodeText = getLiveblocksNodeText;
|
|
142
|
+
exports.getLiveblocksNodeType = getLiveblocksNodeType;
|
|
143
|
+
exports.liveblocksProsemirrorNodeToJson = liveblocksProsemirrorNodeToJson;
|
|
144
|
+
exports.liveblocksProsemirrorNodeToJsonNodes = liveblocksProsemirrorNodeToJsonNodes;
|
|
145
|
+
exports.marksToAttributes = marksToAttributes;
|
|
146
|
+
exports.marksToAttributesPatch = marksToAttributesPatch;
|
|
147
|
+
exports.stringifyDocument = stringifyDocument;
|
|
148
|
+
exports.updateLiveblocksNodeAttrs = updateLiveblocksNodeAttrs;
|
|
149
|
+
//# sourceMappingURL=schema.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.cjs","sources":["../src/schema.ts"],"sourcesContent":["import {\n type Json,\n type JsonObject,\n LiveList,\n LiveObject,\n LiveText,\n type LiveTextAttributes,\n type LiveTextAttributesPatch,\n nanoid,\n} from \"@liveblocks/client\";\n\nexport const TEXT_MARKS_ATTRIBUTE = \"__liveblocks_tiptap_marks\";\n\nexport type ProseMirrorJsonNode = {\n type: string;\n attrs?: JsonObject;\n content?: ProseMirrorJsonNode[];\n text?: string;\n marks?: ProseMirrorJsonMark[];\n};\n\nexport type ProseMirrorJsonMark = {\n type: string;\n attrs?: JsonObject;\n};\n\ntype LiveblocksProsemirrorNodeData = {\n id: string;\n type: string;\n attrs?: JsonObject;\n content?: LiveList<LiveblocksProsemirrorNode>;\n text?: LiveText;\n};\n\nexport type LiveblocksProsemirrorNode = LiveObject<LiveblocksProsemirrorNodeData>;\n\nfunction isJsonObject(value: Json | undefined): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function marksToAttributes(\n marks: ProseMirrorJsonMark[] | undefined\n): LiveTextAttributes | undefined {\n if (marks === undefined || marks.length === 0) {\n return undefined;\n }\n\n return {\n [TEXT_MARKS_ATTRIBUTE]: marks.map((mark) => ({\n type: mark.type,\n ...(mark.attrs !== undefined ? { attrs: mark.attrs } : {}),\n })),\n };\n}\n\nexport function attributesToMarks(\n attributes: JsonObject | undefined\n): ProseMirrorJsonMark[] | undefined {\n const rawMarks = attributes?.[TEXT_MARKS_ATTRIBUTE];\n\n if (!Array.isArray(rawMarks)) {\n return undefined;\n }\n\n const marks: ProseMirrorJsonMark[] = [];\n for (const rawMark of rawMarks) {\n if (!isJsonObject(rawMark) || typeof rawMark.type !== \"string\") {\n continue;\n }\n\n marks.push({\n type: rawMark.type,\n ...(isJsonObject(rawMark.attrs) ? { attrs: rawMark.attrs } : {}),\n });\n }\n\n return marks.length > 0 ? marks : undefined;\n}\n\nexport function marksToAttributesPatch(\n marks: ProseMirrorJsonMark[] | undefined\n): LiveTextAttributesPatch {\n const attributes = marksToAttributes(marks);\n return {\n [TEXT_MARKS_ATTRIBUTE]:\n attributes?.[TEXT_MARKS_ATTRIBUTE] === undefined\n ? null\n : attributes[TEXT_MARKS_ATTRIBUTE],\n };\n}\n\nexport function createLiveblocksProsemirrorNode(\n node: ProseMirrorJsonNode\n): LiveblocksProsemirrorNode {\n if (node.type === \"text\") {\n const text = new LiveText();\n text.insert(0, node.text ?? \"\", marksToAttributes(node.marks));\n\n return new LiveObject({\n id: nanoid(),\n type: node.type,\n text,\n });\n }\n\n return new LiveObject({\n id: nanoid(),\n type: node.type,\n ...(node.attrs !== undefined ? { attrs: node.attrs } : {}),\n content: new LiveList(\n (node.content ?? []).map((child) => createLiveblocksProsemirrorNode(child))\n ),\n });\n}\n\nexport function getLiveblocksNodeId(node: LiveblocksProsemirrorNode): string {\n return node.get(\"id\");\n}\n\nexport function getLiveblocksNodeType(node: LiveblocksProsemirrorNode): string {\n return node.get(\"type\");\n}\n\nexport function getLiveblocksNodeContent(\n node: LiveblocksProsemirrorNode\n): LiveList<LiveblocksProsemirrorNode> | undefined {\n const content = node.get(\"content\");\n return content instanceof LiveList ? content : undefined;\n}\n\nexport function getLiveblocksNodeText(\n node: LiveblocksProsemirrorNode\n): LiveText | undefined {\n const text = node.get(\"text\");\n return text instanceof LiveText ? text : undefined;\n}\n\nexport function updateLiveblocksNodeAttrs(\n node: LiveblocksProsemirrorNode,\n attrs: JsonObject | undefined\n): void {\n if (attrs === undefined) {\n node.delete(\"attrs\");\n } else {\n node.set(\"attrs\", attrs);\n }\n}\n\nfunction liveTextToTextNodes(text: LiveText): ProseMirrorJsonNode[] {\n const nodes: ProseMirrorJsonNode[] = [];\n\n for (const [segmentText, segmentAttributes] of text.toJSON()) {\n if (segmentText.length === 0) {\n continue;\n }\n\n nodes.push({\n type: \"text\",\n text: segmentText,\n ...(segmentAttributes !== undefined\n ? { marks: attributesToMarks(segmentAttributes) }\n : {}),\n });\n }\n\n return nodes;\n}\n\nexport function liveblocksProsemirrorNodeToJsonNodes(\n node: LiveblocksProsemirrorNode\n): ProseMirrorJsonNode[] {\n const type = node.get(\"type\");\n\n if (type === \"text\") {\n const text = node.get(\"text\");\n return text instanceof LiveText ? liveTextToTextNodes(text) : [];\n }\n\n const content = node.get(\"content\");\n const jsonNode: ProseMirrorJsonNode = {\n type,\n ...(node.get(\"attrs\") !== undefined ? { attrs: node.get(\"attrs\") } : {}),\n };\n\n if (content instanceof LiveList && content.length > 0) {\n const children: ProseMirrorJsonNode[] = [];\n\n for (let index = 0; index < content.length; index++) {\n const child = content.get(index);\n if (child !== undefined) {\n children.push(...liveblocksProsemirrorNodeToJsonNodes(child));\n }\n }\n\n if (children.length > 0) {\n jsonNode.content = children;\n }\n }\n\n return [jsonNode];\n}\n\nexport function liveblocksProsemirrorNodeToJson(\n node: LiveblocksProsemirrorNode,\n fallbackDocument?: () => ProseMirrorJsonNode\n): ProseMirrorJsonNode {\n const [jsonNode] = liveblocksProsemirrorNodeToJsonNodes(node);\n\n if (\n jsonNode === undefined ||\n (jsonNode.type === \"doc\" &&\n (!Array.isArray(jsonNode.content) || jsonNode.content.length === 0))\n ) {\n const fallback = fallbackDocument?.();\n if (fallback !== undefined) {\n return fallback;\n }\n }\n\n return jsonNode ?? { type: node.get(\"type\") };\n}\n\nexport function stringifyDocument(node: ProseMirrorJsonNode): string {\n return JSON.stringify(node);\n}\n"],"names":["LiveText","LiveObject","nanoid","LiveList"],"mappings":"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"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { LiveText, LiveObject, nanoid, LiveList } from '@liveblocks/client';
|
|
2
|
+
|
|
3
|
+
const TEXT_MARKS_ATTRIBUTE = "__liveblocks_tiptap_marks";
|
|
4
|
+
function isJsonObject(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function marksToAttributes(marks) {
|
|
8
|
+
if (marks === void 0 || marks.length === 0) {
|
|
9
|
+
return void 0;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
[TEXT_MARKS_ATTRIBUTE]: marks.map((mark) => ({
|
|
13
|
+
type: mark.type,
|
|
14
|
+
...mark.attrs !== void 0 ? { attrs: mark.attrs } : {}
|
|
15
|
+
}))
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function attributesToMarks(attributes) {
|
|
19
|
+
const rawMarks = attributes?.[TEXT_MARKS_ATTRIBUTE];
|
|
20
|
+
if (!Array.isArray(rawMarks)) {
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
23
|
+
const marks = [];
|
|
24
|
+
for (const rawMark of rawMarks) {
|
|
25
|
+
if (!isJsonObject(rawMark) || typeof rawMark.type !== "string") {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
marks.push({
|
|
29
|
+
type: rawMark.type,
|
|
30
|
+
...isJsonObject(rawMark.attrs) ? { attrs: rawMark.attrs } : {}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return marks.length > 0 ? marks : void 0;
|
|
34
|
+
}
|
|
35
|
+
function marksToAttributesPatch(marks) {
|
|
36
|
+
const attributes = marksToAttributes(marks);
|
|
37
|
+
return {
|
|
38
|
+
[TEXT_MARKS_ATTRIBUTE]: attributes?.[TEXT_MARKS_ATTRIBUTE] === void 0 ? null : attributes[TEXT_MARKS_ATTRIBUTE]
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function createLiveblocksProsemirrorNode(node) {
|
|
42
|
+
if (node.type === "text") {
|
|
43
|
+
const text = new LiveText();
|
|
44
|
+
text.insert(0, node.text ?? "", marksToAttributes(node.marks));
|
|
45
|
+
return new LiveObject({
|
|
46
|
+
id: nanoid(),
|
|
47
|
+
type: node.type,
|
|
48
|
+
text
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return new LiveObject({
|
|
52
|
+
id: nanoid(),
|
|
53
|
+
type: node.type,
|
|
54
|
+
...node.attrs !== void 0 ? { attrs: node.attrs } : {},
|
|
55
|
+
content: new LiveList(
|
|
56
|
+
(node.content ?? []).map((child) => createLiveblocksProsemirrorNode(child))
|
|
57
|
+
)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function getLiveblocksNodeId(node) {
|
|
61
|
+
return node.get("id");
|
|
62
|
+
}
|
|
63
|
+
function getLiveblocksNodeType(node) {
|
|
64
|
+
return node.get("type");
|
|
65
|
+
}
|
|
66
|
+
function getLiveblocksNodeContent(node) {
|
|
67
|
+
const content = node.get("content");
|
|
68
|
+
return content instanceof LiveList ? content : void 0;
|
|
69
|
+
}
|
|
70
|
+
function getLiveblocksNodeText(node) {
|
|
71
|
+
const text = node.get("text");
|
|
72
|
+
return text instanceof LiveText ? text : void 0;
|
|
73
|
+
}
|
|
74
|
+
function updateLiveblocksNodeAttrs(node, attrs) {
|
|
75
|
+
if (attrs === void 0) {
|
|
76
|
+
node.delete("attrs");
|
|
77
|
+
} else {
|
|
78
|
+
node.set("attrs", attrs);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function liveTextToTextNodes(text) {
|
|
82
|
+
const nodes = [];
|
|
83
|
+
for (const [segmentText, segmentAttributes] of text.toJSON()) {
|
|
84
|
+
if (segmentText.length === 0) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
nodes.push({
|
|
88
|
+
type: "text",
|
|
89
|
+
text: segmentText,
|
|
90
|
+
...segmentAttributes !== void 0 ? { marks: attributesToMarks(segmentAttributes) } : {}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return nodes;
|
|
94
|
+
}
|
|
95
|
+
function liveblocksProsemirrorNodeToJsonNodes(node) {
|
|
96
|
+
const type = node.get("type");
|
|
97
|
+
if (type === "text") {
|
|
98
|
+
const text = node.get("text");
|
|
99
|
+
return text instanceof LiveText ? liveTextToTextNodes(text) : [];
|
|
100
|
+
}
|
|
101
|
+
const content = node.get("content");
|
|
102
|
+
const jsonNode = {
|
|
103
|
+
type,
|
|
104
|
+
...node.get("attrs") !== void 0 ? { attrs: node.get("attrs") } : {}
|
|
105
|
+
};
|
|
106
|
+
if (content instanceof LiveList && content.length > 0) {
|
|
107
|
+
const children = [];
|
|
108
|
+
for (let index = 0; index < content.length; index++) {
|
|
109
|
+
const child = content.get(index);
|
|
110
|
+
if (child !== void 0) {
|
|
111
|
+
children.push(...liveblocksProsemirrorNodeToJsonNodes(child));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (children.length > 0) {
|
|
115
|
+
jsonNode.content = children;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return [jsonNode];
|
|
119
|
+
}
|
|
120
|
+
function liveblocksProsemirrorNodeToJson(node, fallbackDocument) {
|
|
121
|
+
const [jsonNode] = liveblocksProsemirrorNodeToJsonNodes(node);
|
|
122
|
+
if (jsonNode === void 0 || jsonNode.type === "doc" && (!Array.isArray(jsonNode.content) || jsonNode.content.length === 0)) {
|
|
123
|
+
const fallback = fallbackDocument?.();
|
|
124
|
+
if (fallback !== void 0) {
|
|
125
|
+
return fallback;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return jsonNode ?? { type: node.get("type") };
|
|
129
|
+
}
|
|
130
|
+
function stringifyDocument(node) {
|
|
131
|
+
return JSON.stringify(node);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { TEXT_MARKS_ATTRIBUTE, attributesToMarks, createLiveblocksProsemirrorNode, getLiveblocksNodeContent, getLiveblocksNodeId, getLiveblocksNodeText, getLiveblocksNodeType, liveblocksProsemirrorNodeToJson, liveblocksProsemirrorNodeToJsonNodes, marksToAttributes, marksToAttributesPatch, stringifyDocument, updateLiveblocksNodeAttrs };
|
|
135
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../src/schema.ts"],"sourcesContent":["import {\n type Json,\n type JsonObject,\n LiveList,\n LiveObject,\n LiveText,\n type LiveTextAttributes,\n type LiveTextAttributesPatch,\n nanoid,\n} from \"@liveblocks/client\";\n\nexport const TEXT_MARKS_ATTRIBUTE = \"__liveblocks_tiptap_marks\";\n\nexport type ProseMirrorJsonNode = {\n type: string;\n attrs?: JsonObject;\n content?: ProseMirrorJsonNode[];\n text?: string;\n marks?: ProseMirrorJsonMark[];\n};\n\nexport type ProseMirrorJsonMark = {\n type: string;\n attrs?: JsonObject;\n};\n\ntype LiveblocksProsemirrorNodeData = {\n id: string;\n type: string;\n attrs?: JsonObject;\n content?: LiveList<LiveblocksProsemirrorNode>;\n text?: LiveText;\n};\n\nexport type LiveblocksProsemirrorNode = LiveObject<LiveblocksProsemirrorNodeData>;\n\nfunction isJsonObject(value: Json | undefined): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function marksToAttributes(\n marks: ProseMirrorJsonMark[] | undefined\n): LiveTextAttributes | undefined {\n if (marks === undefined || marks.length === 0) {\n return undefined;\n }\n\n return {\n [TEXT_MARKS_ATTRIBUTE]: marks.map((mark) => ({\n type: mark.type,\n ...(mark.attrs !== undefined ? { attrs: mark.attrs } : {}),\n })),\n };\n}\n\nexport function attributesToMarks(\n attributes: JsonObject | undefined\n): ProseMirrorJsonMark[] | undefined {\n const rawMarks = attributes?.[TEXT_MARKS_ATTRIBUTE];\n\n if (!Array.isArray(rawMarks)) {\n return undefined;\n }\n\n const marks: ProseMirrorJsonMark[] = [];\n for (const rawMark of rawMarks) {\n if (!isJsonObject(rawMark) || typeof rawMark.type !== \"string\") {\n continue;\n }\n\n marks.push({\n type: rawMark.type,\n ...(isJsonObject(rawMark.attrs) ? { attrs: rawMark.attrs } : {}),\n });\n }\n\n return marks.length > 0 ? marks : undefined;\n}\n\nexport function marksToAttributesPatch(\n marks: ProseMirrorJsonMark[] | undefined\n): LiveTextAttributesPatch {\n const attributes = marksToAttributes(marks);\n return {\n [TEXT_MARKS_ATTRIBUTE]:\n attributes?.[TEXT_MARKS_ATTRIBUTE] === undefined\n ? null\n : attributes[TEXT_MARKS_ATTRIBUTE],\n };\n}\n\nexport function createLiveblocksProsemirrorNode(\n node: ProseMirrorJsonNode\n): LiveblocksProsemirrorNode {\n if (node.type === \"text\") {\n const text = new LiveText();\n text.insert(0, node.text ?? \"\", marksToAttributes(node.marks));\n\n return new LiveObject({\n id: nanoid(),\n type: node.type,\n text,\n });\n }\n\n return new LiveObject({\n id: nanoid(),\n type: node.type,\n ...(node.attrs !== undefined ? { attrs: node.attrs } : {}),\n content: new LiveList(\n (node.content ?? []).map((child) => createLiveblocksProsemirrorNode(child))\n ),\n });\n}\n\nexport function getLiveblocksNodeId(node: LiveblocksProsemirrorNode): string {\n return node.get(\"id\");\n}\n\nexport function getLiveblocksNodeType(node: LiveblocksProsemirrorNode): string {\n return node.get(\"type\");\n}\n\nexport function getLiveblocksNodeContent(\n node: LiveblocksProsemirrorNode\n): LiveList<LiveblocksProsemirrorNode> | undefined {\n const content = node.get(\"content\");\n return content instanceof LiveList ? content : undefined;\n}\n\nexport function getLiveblocksNodeText(\n node: LiveblocksProsemirrorNode\n): LiveText | undefined {\n const text = node.get(\"text\");\n return text instanceof LiveText ? text : undefined;\n}\n\nexport function updateLiveblocksNodeAttrs(\n node: LiveblocksProsemirrorNode,\n attrs: JsonObject | undefined\n): void {\n if (attrs === undefined) {\n node.delete(\"attrs\");\n } else {\n node.set(\"attrs\", attrs);\n }\n}\n\nfunction liveTextToTextNodes(text: LiveText): ProseMirrorJsonNode[] {\n const nodes: ProseMirrorJsonNode[] = [];\n\n for (const [segmentText, segmentAttributes] of text.toJSON()) {\n if (segmentText.length === 0) {\n continue;\n }\n\n nodes.push({\n type: \"text\",\n text: segmentText,\n ...(segmentAttributes !== undefined\n ? { marks: attributesToMarks(segmentAttributes) }\n : {}),\n });\n }\n\n return nodes;\n}\n\nexport function liveblocksProsemirrorNodeToJsonNodes(\n node: LiveblocksProsemirrorNode\n): ProseMirrorJsonNode[] {\n const type = node.get(\"type\");\n\n if (type === \"text\") {\n const text = node.get(\"text\");\n return text instanceof LiveText ? liveTextToTextNodes(text) : [];\n }\n\n const content = node.get(\"content\");\n const jsonNode: ProseMirrorJsonNode = {\n type,\n ...(node.get(\"attrs\") !== undefined ? { attrs: node.get(\"attrs\") } : {}),\n };\n\n if (content instanceof LiveList && content.length > 0) {\n const children: ProseMirrorJsonNode[] = [];\n\n for (let index = 0; index < content.length; index++) {\n const child = content.get(index);\n if (child !== undefined) {\n children.push(...liveblocksProsemirrorNodeToJsonNodes(child));\n }\n }\n\n if (children.length > 0) {\n jsonNode.content = children;\n }\n }\n\n return [jsonNode];\n}\n\nexport function liveblocksProsemirrorNodeToJson(\n node: LiveblocksProsemirrorNode,\n fallbackDocument?: () => ProseMirrorJsonNode\n): ProseMirrorJsonNode {\n const [jsonNode] = liveblocksProsemirrorNodeToJsonNodes(node);\n\n if (\n jsonNode === undefined ||\n (jsonNode.type === \"doc\" &&\n (!Array.isArray(jsonNode.content) || jsonNode.content.length === 0))\n ) {\n const fallback = fallbackDocument?.();\n if (fallback !== undefined) {\n return fallback;\n }\n }\n\n return jsonNode ?? { type: node.get(\"type\") };\n}\n\nexport function stringifyDocument(node: ProseMirrorJsonNode): string {\n return JSON.stringify(node);\n}\n"],"names":[],"mappings":"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"}
|
package/dist/steps.cjs
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var client = require('@liveblocks/client');
|
|
4
|
+
var mapping = require('./mapping.cjs');
|
|
5
|
+
var schema = require('./schema.cjs');
|
|
6
|
+
|
|
7
|
+
function isObject(value) {
|
|
8
|
+
return typeof value === "object" && value !== null;
|
|
9
|
+
}
|
|
10
|
+
function isJsonObject(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function parseMarks(value) {
|
|
14
|
+
if (!Array.isArray(value)) {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
const marks = [];
|
|
18
|
+
for (const mark of value) {
|
|
19
|
+
if (!isObject(mark) || typeof mark.type !== "string") {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
marks.push({
|
|
23
|
+
type: mark.type,
|
|
24
|
+
...isJsonObject(mark.attrs) ? { attrs: mark.attrs } : {}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return marks.length > 0 ? marks : void 0;
|
|
28
|
+
}
|
|
29
|
+
function parseProseMirrorJsonNode(value) {
|
|
30
|
+
if (!isObject(value) || typeof value.type !== "string") {
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
const node = { type: value.type };
|
|
34
|
+
if (isJsonObject(value.attrs)) {
|
|
35
|
+
node.attrs = value.attrs;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value.text === "string") {
|
|
38
|
+
node.text = value.text;
|
|
39
|
+
}
|
|
40
|
+
const marks = parseMarks(value.marks);
|
|
41
|
+
if (marks !== void 0) {
|
|
42
|
+
node.marks = marks;
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(value.content)) {
|
|
45
|
+
const content = [];
|
|
46
|
+
for (const child of value.content) {
|
|
47
|
+
const parsedChild = parseProseMirrorJsonNode(child);
|
|
48
|
+
if (parsedChild === void 0) {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
content.push(parsedChild);
|
|
52
|
+
}
|
|
53
|
+
node.content = content;
|
|
54
|
+
}
|
|
55
|
+
return node;
|
|
56
|
+
}
|
|
57
|
+
function prosemirrorNodeToJson(node) {
|
|
58
|
+
return parseProseMirrorJsonNode(node.toJSON());
|
|
59
|
+
}
|
|
60
|
+
function getNodeAttrs(node) {
|
|
61
|
+
return prosemirrorNodeToJson(node)?.attrs;
|
|
62
|
+
}
|
|
63
|
+
function isReplaceStepJson(value) {
|
|
64
|
+
return isObject(value) && value.stepType === "replace" && typeof value.from === "number" && typeof value.to === "number";
|
|
65
|
+
}
|
|
66
|
+
function isMarkStepJson(value) {
|
|
67
|
+
return isObject(value) && (value.stepType === "addMark" || value.stepType === "removeMark") && typeof value.from === "number" && typeof value.to === "number";
|
|
68
|
+
}
|
|
69
|
+
function getTextContentFromSlice(slice) {
|
|
70
|
+
const content = slice?.content;
|
|
71
|
+
if (content === void 0 || content.length === 0) {
|
|
72
|
+
return { text: "" };
|
|
73
|
+
}
|
|
74
|
+
let text = "";
|
|
75
|
+
let marks;
|
|
76
|
+
for (const node of content) {
|
|
77
|
+
if (!isObject(node) || node.type !== "text") {
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
80
|
+
const nodeText = node.text;
|
|
81
|
+
if (typeof nodeText !== "string") {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
const nodeMarks = parseMarks(node.marks);
|
|
85
|
+
if (text.length === 0) {
|
|
86
|
+
marks = nodeMarks;
|
|
87
|
+
} else if (JSON.stringify(marks ?? []) !== JSON.stringify(nodeMarks ?? [])) {
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
text += nodeText;
|
|
91
|
+
}
|
|
92
|
+
return { text, marks };
|
|
93
|
+
}
|
|
94
|
+
function classifyReplaceStep(step, oldDoc, liveRoot) {
|
|
95
|
+
const inserted = getTextContentFromSlice(step.slice);
|
|
96
|
+
if (inserted === void 0) {
|
|
97
|
+
return void 0;
|
|
98
|
+
}
|
|
99
|
+
const operations = [];
|
|
100
|
+
if (step.from !== step.to) {
|
|
101
|
+
const fromRange = mapping.findTextRangeAtPositionInDocument(
|
|
102
|
+
oldDoc,
|
|
103
|
+
liveRoot,
|
|
104
|
+
step.from
|
|
105
|
+
);
|
|
106
|
+
const toRange = mapping.findTextRangeAtPositionInDocument(
|
|
107
|
+
oldDoc,
|
|
108
|
+
liveRoot,
|
|
109
|
+
step.to
|
|
110
|
+
);
|
|
111
|
+
if (fromRange === void 0 || toRange === void 0 || fromRange.nodeId !== toRange.nodeId) {
|
|
112
|
+
return void 0;
|
|
113
|
+
}
|
|
114
|
+
operations.push({
|
|
115
|
+
type: "delete",
|
|
116
|
+
node: fromRange.node,
|
|
117
|
+
index: fromRange.liveOffset + step.from - fromRange.from,
|
|
118
|
+
length: step.to - step.from
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (inserted.text.length > 0) {
|
|
122
|
+
const range = mapping.findTextRangeAtPositionInDocument(
|
|
123
|
+
oldDoc,
|
|
124
|
+
liveRoot,
|
|
125
|
+
step.from
|
|
126
|
+
);
|
|
127
|
+
if (range === void 0) {
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
operations.push({
|
|
131
|
+
type: "insert",
|
|
132
|
+
node: range.node,
|
|
133
|
+
index: range.liveOffset + step.from - range.from,
|
|
134
|
+
text: inserted.text,
|
|
135
|
+
attributes: schema.marksToAttributes(inserted.marks)
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return operations.length > 0 ? operations : void 0;
|
|
139
|
+
}
|
|
140
|
+
function marksFromNode(node) {
|
|
141
|
+
const marks = node.marks.map((mark) => {
|
|
142
|
+
const json = mark.toJSON();
|
|
143
|
+
if (!isObject(json) || typeof json.type !== "string") {
|
|
144
|
+
return void 0;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
type: json.type,
|
|
148
|
+
...isJsonObject(json.attrs) ? { attrs: json.attrs } : {}
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
const parsedMarks = marks.filter((mark) => mark !== void 0);
|
|
152
|
+
return parsedMarks.length > 0 ? parsedMarks : void 0;
|
|
153
|
+
}
|
|
154
|
+
function classifyMarkStep(step, oldIndex, newDoc) {
|
|
155
|
+
const operations = [];
|
|
156
|
+
newDoc.nodesBetween(step.from, step.to, (node, pos) => {
|
|
157
|
+
if (!node.isText || node.nodeSize === 0) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
const from = Math.max(step.from, pos);
|
|
161
|
+
const to = Math.min(step.to, pos + node.nodeSize);
|
|
162
|
+
const range = mapping.findTextRangeAtPosition(oldIndex, from);
|
|
163
|
+
if (range === void 0 || to <= from) {
|
|
164
|
+
operations.length = 0;
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
operations.push({
|
|
168
|
+
type: "format",
|
|
169
|
+
node: range.node,
|
|
170
|
+
index: range.liveOffset + from - range.from,
|
|
171
|
+
length: to - from,
|
|
172
|
+
attributes: schema.marksToAttributesPatch(marksFromNode(node))
|
|
173
|
+
});
|
|
174
|
+
return true;
|
|
175
|
+
});
|
|
176
|
+
return operations.length > 0 ? operations : void 0;
|
|
177
|
+
}
|
|
178
|
+
function createNodeOperation(type, content, index, node) {
|
|
179
|
+
const jsonNode = prosemirrorNodeToJson(node);
|
|
180
|
+
if (jsonNode === void 0) {
|
|
181
|
+
return void 0;
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
type,
|
|
185
|
+
content,
|
|
186
|
+
index,
|
|
187
|
+
node: schema.createLiveblocksProsemirrorNode(jsonNode)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function classifyAttrsChange(oldNode, newNode, liveNode) {
|
|
191
|
+
if (oldNode.isText || oldNode.type !== newNode.type || !oldNode.content.eq(newNode.content) || oldNode.sameMarkup(newNode)) {
|
|
192
|
+
return void 0;
|
|
193
|
+
}
|
|
194
|
+
return [
|
|
195
|
+
{ type: "updateAttrs", node: liveNode, attrs: getNodeAttrs(newNode) }
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
function findCommonPrefix(oldParent, newParent) {
|
|
199
|
+
const max = Math.min(oldParent.childCount, newParent.childCount);
|
|
200
|
+
let prefix = 0;
|
|
201
|
+
while (prefix < max && oldParent.child(prefix).eq(newParent.child(prefix))) {
|
|
202
|
+
prefix++;
|
|
203
|
+
}
|
|
204
|
+
return prefix;
|
|
205
|
+
}
|
|
206
|
+
function findCommonSuffix(oldParent, newParent, prefix) {
|
|
207
|
+
const max = Math.min(
|
|
208
|
+
oldParent.childCount - prefix,
|
|
209
|
+
newParent.childCount - prefix
|
|
210
|
+
);
|
|
211
|
+
let suffix = 0;
|
|
212
|
+
while (suffix < max && oldParent.child(oldParent.childCount - suffix - 1).eq(newParent.child(newParent.childCount - suffix - 1))) {
|
|
213
|
+
suffix++;
|
|
214
|
+
}
|
|
215
|
+
return suffix;
|
|
216
|
+
}
|
|
217
|
+
function classifyChildrenChange(oldParent, newParent, liveParent) {
|
|
218
|
+
const content = schema.getLiveblocksNodeContent(liveParent);
|
|
219
|
+
if (content === void 0) {
|
|
220
|
+
return void 0;
|
|
221
|
+
}
|
|
222
|
+
if (oldParent.childCount === newParent.childCount) {
|
|
223
|
+
const operations = [];
|
|
224
|
+
for (let index = 0; index < oldParent.childCount; index++) {
|
|
225
|
+
const oldChild = oldParent.child(index);
|
|
226
|
+
const newChild = newParent.child(index);
|
|
227
|
+
if (oldChild.eq(newChild)) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const liveChild = content.get(index);
|
|
231
|
+
if (liveChild === void 0) {
|
|
232
|
+
return void 0;
|
|
233
|
+
}
|
|
234
|
+
const childOperations = classifyAttrsChange(oldChild, newChild, liveChild) ?? classifyNodeChange(oldChild, newChild, liveChild);
|
|
235
|
+
if (childOperations !== void 0) {
|
|
236
|
+
operations.push(...childOperations);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const operation = createNodeOperation(
|
|
240
|
+
"setNode",
|
|
241
|
+
content,
|
|
242
|
+
index,
|
|
243
|
+
newChild
|
|
244
|
+
);
|
|
245
|
+
if (operation === void 0) {
|
|
246
|
+
return void 0;
|
|
247
|
+
}
|
|
248
|
+
operations.push(operation);
|
|
249
|
+
}
|
|
250
|
+
return operations.length > 0 ? operations : void 0;
|
|
251
|
+
}
|
|
252
|
+
const prefix = findCommonPrefix(oldParent, newParent);
|
|
253
|
+
const suffix = findCommonSuffix(oldParent, newParent, prefix);
|
|
254
|
+
if (oldParent.childCount + 1 === newParent.childCount && prefix + suffix === oldParent.childCount) {
|
|
255
|
+
const operation = createNodeOperation(
|
|
256
|
+
"insertNode",
|
|
257
|
+
content,
|
|
258
|
+
prefix,
|
|
259
|
+
newParent.child(prefix)
|
|
260
|
+
);
|
|
261
|
+
return operation === void 0 ? void 0 : [operation];
|
|
262
|
+
}
|
|
263
|
+
if (oldParent.childCount + 1 === newParent.childCount && prefix + suffix + 1 === oldParent.childCount) {
|
|
264
|
+
const setOperation = createNodeOperation(
|
|
265
|
+
"setNode",
|
|
266
|
+
content,
|
|
267
|
+
prefix,
|
|
268
|
+
newParent.child(prefix)
|
|
269
|
+
);
|
|
270
|
+
const insertOperation = createNodeOperation(
|
|
271
|
+
"insertNode",
|
|
272
|
+
content,
|
|
273
|
+
prefix + 1,
|
|
274
|
+
newParent.child(prefix + 1)
|
|
275
|
+
);
|
|
276
|
+
return setOperation === void 0 || insertOperation === void 0 ? void 0 : [setOperation, insertOperation];
|
|
277
|
+
}
|
|
278
|
+
if (oldParent.childCount - 1 === newParent.childCount && prefix + suffix === newParent.childCount) {
|
|
279
|
+
return [{ type: "deleteNode", content, index: prefix }];
|
|
280
|
+
}
|
|
281
|
+
if (oldParent.childCount - 1 === newParent.childCount && prefix + suffix + 1 === newParent.childCount) {
|
|
282
|
+
const operation = createNodeOperation(
|
|
283
|
+
"setNode",
|
|
284
|
+
content,
|
|
285
|
+
prefix,
|
|
286
|
+
newParent.child(prefix)
|
|
287
|
+
);
|
|
288
|
+
return operation === void 0 ? void 0 : [operation, { type: "deleteNode", content, index: prefix + 1 }];
|
|
289
|
+
}
|
|
290
|
+
return void 0;
|
|
291
|
+
}
|
|
292
|
+
function classifyNodeChange(oldNode, newNode, liveNode) {
|
|
293
|
+
const attrOperations = classifyAttrsChange(oldNode, newNode, liveNode) ?? [];
|
|
294
|
+
const childOperations = oldNode.type === newNode.type ? classifyChildrenChange(oldNode, newNode, liveNode) : void 0;
|
|
295
|
+
const operations = [...attrOperations, ...childOperations ?? []];
|
|
296
|
+
return operations.length > 0 ? operations : void 0;
|
|
297
|
+
}
|
|
298
|
+
function classifyStructuralChange(oldDoc, newDoc, liveRoot) {
|
|
299
|
+
return classifyNodeChange(oldDoc, newDoc, liveRoot);
|
|
300
|
+
}
|
|
301
|
+
function classifyTransaction(transactions, oldDoc, newDoc, liveRoot) {
|
|
302
|
+
const changedTransactions = transactions.filter(
|
|
303
|
+
(transaction2) => transaction2.docChanged
|
|
304
|
+
);
|
|
305
|
+
if (changedTransactions.length !== 1) {
|
|
306
|
+
return { type: "unsupported" };
|
|
307
|
+
}
|
|
308
|
+
const [transaction] = changedTransactions;
|
|
309
|
+
if (transaction === void 0 || transaction.steps.length !== 1) {
|
|
310
|
+
return { type: "unsupported" };
|
|
311
|
+
}
|
|
312
|
+
const [step] = transaction.steps;
|
|
313
|
+
const stepJson = step?.toJSON();
|
|
314
|
+
const operations = isReplaceStepJson(stepJson) ? classifyReplaceStep(stepJson, oldDoc, liveRoot) : isMarkStepJson(stepJson) ? classifyMarkStep(
|
|
315
|
+
stepJson,
|
|
316
|
+
mapping.buildLiveblocksTreeIndex(oldDoc, liveRoot),
|
|
317
|
+
newDoc
|
|
318
|
+
) : void 0;
|
|
319
|
+
const structuralOperations = operations ?? classifyStructuralChange(oldDoc, newDoc, liveRoot);
|
|
320
|
+
if (structuralOperations === void 0) {
|
|
321
|
+
return { type: "unsupported" };
|
|
322
|
+
}
|
|
323
|
+
return { type: "incremental", operations: structuralOperations };
|
|
324
|
+
}
|
|
325
|
+
function applyIncrementalOperations(operations) {
|
|
326
|
+
for (const operation of operations) {
|
|
327
|
+
if (operation.type === "insert") {
|
|
328
|
+
const text = operation.node.get("text");
|
|
329
|
+
if (!(text instanceof client.LiveText)) {
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
text.insert(operation.index, operation.text, operation.attributes);
|
|
333
|
+
} else if (operation.type === "delete") {
|
|
334
|
+
const text = operation.node.get("text");
|
|
335
|
+
if (!(text instanceof client.LiveText)) {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
text.delete(operation.index, operation.length);
|
|
339
|
+
} else if (operation.type === "format") {
|
|
340
|
+
const text = operation.node.get("text");
|
|
341
|
+
if (!(text instanceof client.LiveText)) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
text.format(operation.index, operation.length, operation.attributes);
|
|
345
|
+
} else if (operation.type === "insertNode") {
|
|
346
|
+
operation.content.insert(operation.node, operation.index);
|
|
347
|
+
} else if (operation.type === "deleteNode") {
|
|
348
|
+
operation.content.delete(operation.index);
|
|
349
|
+
} else if (operation.type === "setNode") {
|
|
350
|
+
operation.content.set(operation.index, operation.node);
|
|
351
|
+
} else {
|
|
352
|
+
schema.updateLiveblocksNodeAttrs(operation.node, operation.attrs);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
exports.applyIncrementalOperations = applyIncrementalOperations;
|
|
358
|
+
exports.classifyTransaction = classifyTransaction;
|
|
359
|
+
//# sourceMappingURL=steps.cjs.map
|