@liveblocks/react-tiptap 3.21.0-exp1 → 3.21.0-exp11

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 (45) hide show
  1. package/dist/LiveblocksExtension.cjs +3 -2
  2. package/dist/LiveblocksExtension.cjs.map +1 -1
  3. package/dist/LiveblocksExtension.js +3 -2
  4. package/dist/LiveblocksExtension.js.map +1 -1
  5. package/dist/collaboration-liveblocks/cursors.cjs +10 -211
  6. package/dist/collaboration-liveblocks/cursors.cjs.map +1 -1
  7. package/dist/collaboration-liveblocks/cursors.js +6 -209
  8. package/dist/collaboration-liveblocks/cursors.js.map +1 -1
  9. package/dist/collaboration-liveblocks/plugin.cjs +13 -189
  10. package/dist/collaboration-liveblocks/plugin.cjs.map +1 -1
  11. package/dist/collaboration-liveblocks/plugin.js +12 -190
  12. package/dist/collaboration-liveblocks/plugin.js.map +1 -1
  13. package/dist/collaboration-liveblocks/schema.cjs +23 -139
  14. package/dist/collaboration-liveblocks/schema.cjs.map +1 -1
  15. package/dist/collaboration-liveblocks/schema.js +5 -128
  16. package/dist/collaboration-liveblocks/schema.js.map +1 -1
  17. package/dist/comments/CommentsExtension.cjs +3 -2
  18. package/dist/comments/CommentsExtension.cjs.map +1 -1
  19. package/dist/comments/CommentsExtension.js +2 -1
  20. package/dist/comments/CommentsExtension.js.map +1 -1
  21. package/dist/index.d.cts +1 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/mentions/MentionExtension.cjs +6 -4
  24. package/dist/mentions/MentionExtension.cjs.map +1 -1
  25. package/dist/mentions/MentionExtension.js +5 -3
  26. package/dist/mentions/MentionExtension.js.map +1 -1
  27. package/dist/types.cjs.map +1 -1
  28. package/dist/types.js.map +1 -1
  29. package/dist/version.cjs +1 -1
  30. package/dist/version.cjs.map +1 -1
  31. package/dist/version.js +1 -1
  32. package/dist/version.js.map +1 -1
  33. package/package.json +7 -6
  34. package/dist/collaboration-liveblocks/mapping.cjs +0 -218
  35. package/dist/collaboration-liveblocks/mapping.cjs.map +0 -1
  36. package/dist/collaboration-liveblocks/mapping.js +0 -207
  37. package/dist/collaboration-liveblocks/mapping.js.map +0 -1
  38. package/dist/collaboration-liveblocks/remote.cjs +0 -210
  39. package/dist/collaboration-liveblocks/remote.cjs.map +0 -1
  40. package/dist/collaboration-liveblocks/remote.js +0 -207
  41. package/dist/collaboration-liveblocks/remote.js.map +0 -1
  42. package/dist/collaboration-liveblocks/steps.cjs +0 -359
  43. package/dist/collaboration-liveblocks/steps.cjs.map +0 -1
  44. package/dist/collaboration-liveblocks/steps.js +0 -356
  45. package/dist/collaboration-liveblocks/steps.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cursors.cjs","sources":["../../src/collaboration-liveblocks/cursors.ts"],"sourcesContent":["import type { JsonObject } from \"@liveblocks/client\";\nimport { Extension } from \"@tiptap/core\";\nimport type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { Plugin, PluginKey, Selection } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\n\nimport { LIVEBLOCKS_COLLABORATION_PLUGIN_KEY } from \"./plugin\";\nimport type { LiveblocksTiptapRoom } from \"./types\";\n\nconst PRESENCE_KEY = \"liveblocksTiptap\";\n\ntype CursorUser = {\n name?: string;\n color?: string;\n};\n\ntype CursorPresence = {\n field: string;\n anchor: number;\n head: number;\n user?: CursorUser;\n};\n\ntype CollaborationCaretStorage = {\n users: { clientId: number; [key: string]: unknown }[];\n};\n\ntype RemoteCursor = {\n anchor: number;\n connectionId: number;\n head: number;\n rawAnchor: number;\n rawHead: number;\n user?: CursorUser;\n};\n\ntype CollaborationCaretPluginState = {\n cursors: RemoteCursor[];\n decorations: DecorationSet;\n};\n\ntype CollaborationCaretOptions = {\n room?: LiveblocksTiptapRoom;\n field: string;\n user: CursorUser;\n};\n\nexport const LIVEBLOCKS_CARET_PLUGIN_KEY =\n new PluginKey<CollaborationCaretPluginState>(\"liveblocks-collaboration-caret\");\n\nfunction isCursorPresence(value: unknown): value is CursorPresence {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { field?: unknown }).field === \"string\" &&\n typeof (value as { anchor?: unknown }).anchor === \"number\" &&\n typeof (value as { head?: unknown }).head === \"number\"\n );\n}\n\nfunction getCursorUser(value: unknown): CursorUser | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n\n const user = value as { name?: unknown; color?: unknown };\n const name = typeof user.name === \"string\" ? user.name : undefined;\n const color = typeof user.color === \"string\" ? user.color : undefined;\n\n return name !== undefined || color !== undefined ? { name, color } : undefined;\n}\n\nfunction presencePatch(presence: CursorPresence): JsonObject {\n const user = getCursorUser(presence.user);\n\n return {\n [PRESENCE_KEY]: {\n field: presence.field,\n anchor: presence.anchor,\n head: presence.head,\n ...(user !== undefined ? { user } : {}),\n },\n };\n}\n\nfunction createCursorElement(user: CursorUser | undefined): HTMLElement {\n const color = user?.color ?? \"#0f83ff\";\n const name = user?.name ?? \"Anonymous\";\n const cursor = document.createElement(\"span\");\n\n cursor.classList.add(\"collaboration-carets__caret\");\n cursor.setAttribute(\"style\", `border-color: ${color}`);\n\n const label = document.createElement(\"div\");\n label.classList.add(\"collaboration-carets__label\");\n label.setAttribute(\"style\", `background-color: ${color}`);\n label.insertBefore(document.createTextNode(name), null);\n cursor.insertBefore(label, null);\n\n return cursor;\n}\n\nfunction clampPosition(position: number, doc: ProseMirrorNode): number {\n return Math.max(0, Math.min(position, doc.content.size));\n}\n\nfunction normalizeCaretPosition(position: number, doc: ProseMirrorNode): number {\n const clampedPosition = clampPosition(position, doc);\n const $position = doc.resolve(clampedPosition);\n\n if ($position.parent.isTextblock) {\n return clampedPosition;\n }\n\n return Selection.near($position, -1).anchor;\n}\n\nfunction getRemoteCursors(\n room: LiveblocksTiptapRoom,\n field: string,\n previousCursors: readonly RemoteCursor[] = []\n): RemoteCursor[] {\n const cursors: RemoteCursor[] = [];\n\n for (const other of room.getOthers()) {\n const rawPresence: unknown = other.presence[PRESENCE_KEY];\n if (!isCursorPresence(rawPresence) || rawPresence.field !== field) {\n continue;\n }\n\n const user = getCursorUser(rawPresence.user) ?? getCursorUser(other.info);\n const previousCursor = previousCursors.find(\n (cursor) => cursor.connectionId === other.connectionId\n );\n const hasPresencePositionChanged =\n previousCursor === undefined ||\n previousCursor.rawAnchor !== rawPresence.anchor ||\n previousCursor.rawHead !== rawPresence.head;\n\n cursors.push({\n anchor: hasPresencePositionChanged\n ? rawPresence.anchor\n : previousCursor.anchor,\n connectionId: other.connectionId,\n head: hasPresencePositionChanged ? rawPresence.head : previousCursor.head,\n rawAnchor: rawPresence.anchor,\n rawHead: rawPresence.head,\n user,\n });\n }\n\n return cursors;\n}\n\nfunction buildDecorationsFromCursors(\n cursors: readonly RemoteCursor[],\n doc: ProseMirrorNode\n): DecorationSet {\n const decorations: Decoration[] = [];\n\n for (const cursor of cursors) {\n const anchor = clampPosition(cursor.anchor, doc);\n const head = clampPosition(cursor.head, doc);\n const from = Math.min(anchor, head);\n const to = Math.max(anchor, head);\n const user = cursor.user;\n const color = user?.color ?? \"#0f83ff\";\n\n if (from !== to) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"collaboration-carets__selection\",\n style: `background-color: ${color}33`,\n })\n );\n }\n\n decorations.push(\n Decoration.widget(\n normalizeCaretPosition(head, doc),\n () => createCursorElement(user),\n {\n key: `liveblocks-caret-${cursor.connectionId}`,\n side: -1,\n }\n )\n );\n }\n\n return DecorationSet.create(doc, decorations);\n}\n\nfunction createLiveblocksCaretPlugin(\n options: CollaborationCaretOptions,\n storage: CollaborationCaretStorage\n): Plugin {\n const room = options.room;\n if (room === undefined) {\n throw new Error(\"[Liveblocks] The Liveblocks caret plugin requires a room.\");\n }\n\n let view: EditorView | undefined;\n let unsubscribe: (() => void) | undefined;\n\n const updatePresence = (nextView: EditorView) => {\n const { anchor, head } = nextView.state.selection;\n room.updatePresence(\n presencePatch({\n field: options.field,\n anchor,\n head,\n user: options.user,\n })\n );\n };\n\n const updateDecorations = () => {\n if (view === undefined) {\n return;\n }\n\n storage.users = room.getOthers().map((other) => {\n const rawPresence: unknown = other.presence[PRESENCE_KEY];\n const cursorPresence = isCursorPresence(rawPresence)\n ? rawPresence\n : undefined;\n\n return {\n clientId: other.connectionId,\n ...(getCursorUser(cursorPresence?.user) ?? getCursorUser(other.info)),\n };\n });\n\n const previousCursors =\n LIVEBLOCKS_CARET_PLUGIN_KEY.getState(view.state)?.cursors ?? [];\n const cursors = getRemoteCursors(room, options.field, previousCursors);\n\n view.dispatch(\n view.state.tr.setMeta(LIVEBLOCKS_CARET_PLUGIN_KEY, {\n cursors,\n })\n );\n };\n\n return new Plugin({\n key: LIVEBLOCKS_CARET_PLUGIN_KEY,\n state: {\n init(_, state): CollaborationCaretPluginState {\n return {\n cursors: [],\n decorations: DecorationSet.create(state.doc, []),\n };\n },\n apply(tr, state): CollaborationCaretPluginState {\n const meta = tr.getMeta(LIVEBLOCKS_CARET_PLUGIN_KEY) as\n | { cursors: RemoteCursor[] }\n | undefined;\n\n if (meta !== undefined) {\n return {\n cursors: meta.cursors,\n decorations: buildDecorationsFromCursors(meta.cursors, tr.doc),\n };\n }\n\n if (!tr.docChanged) {\n return state;\n }\n\n if (!tr.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY)) {\n const cursors = state.cursors.map((cursor) => ({\n ...cursor,\n anchor: tr.mapping.map(cursor.anchor, -1),\n head: tr.mapping.map(cursor.head, -1),\n }));\n\n return {\n cursors,\n decorations: buildDecorationsFromCursors(cursors, tr.doc),\n };\n }\n\n // Remote presence can arrive before the matching remote document\n // update. Keep the stored cursor positions and rebuild them against\n // the new document so pre-arrived presence is no longer clamped to the\n // old document size.\n return {\n cursors: state.cursors,\n decorations: buildDecorationsFromCursors(state.cursors, tr.doc),\n };\n },\n },\n props: {\n decorations(state) {\n return (\n LIVEBLOCKS_CARET_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n },\n view(editorView) {\n view = editorView;\n updatePresence(editorView);\n updateDecorations();\n unsubscribe = room.events.others.subscribe(updateDecorations);\n\n return {\n update(nextView, prevState) {\n view = nextView;\n\n if (!nextView.state.selection.eq(prevState.selection)) {\n updatePresence(nextView);\n }\n\n },\n destroy() {\n unsubscribe?.();\n unsubscribe = undefined;\n view = undefined;\n room.updatePresence({ [PRESENCE_KEY]: null });\n },\n };\n },\n });\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaborationCaret: {\n updateUser: (attributes: Record<string, any>) => ReturnType;\n user: (attributes: Record<string, any>) => ReturnType;\n };\n }\n}\n\nexport const LiveblocksCollaborationCaret = Extension.create<\n CollaborationCaretOptions,\n CollaborationCaretStorage\n>({\n name: \"collaborationCaret\",\n priority: 999,\n\n addOptions() {\n return {\n room: undefined,\n field: \"default\",\n user: {\n name: undefined,\n color: undefined,\n },\n };\n },\n\n addStorage() {\n return {\n users: [],\n };\n },\n\n addCommands() {\n return {\n updateUser:\n (attributes) =>\n ({ editor }) => {\n const nextUser = getCursorUser({\n ...this.options.user,\n name:\n typeof attributes.name === \"string\"\n ? attributes.name\n : this.options.user.name,\n color:\n typeof attributes.color === \"string\"\n ? attributes.color\n : this.options.user.color,\n }) ?? {};\n\n if (\n nextUser.name === this.options.user.name &&\n nextUser.color === this.options.user.color\n ) {\n return true;\n }\n\n this.options.user = nextUser;\n\n if (this.options.room !== undefined) {\n const { anchor, head } = editor.state.selection;\n this.options.room.updatePresence(\n presencePatch({\n field: this.options.field,\n anchor,\n head,\n user: this.options.user,\n })\n );\n }\n return true;\n },\n user:\n (attributes) =>\n ({ editor }) => {\n return editor.commands.updateUser(attributes);\n },\n };\n },\n\n addProseMirrorPlugins() {\n return [createLiveblocksCaretPlugin(this.options, this.storage)];\n },\n});\n"],"names":["PluginKey","Selection","Decoration","DecorationSet","view","Plugin","LIVEBLOCKS_COLLABORATION_PLUGIN_KEY","Extension"],"mappings":"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"}
1
+ {"version":3,"file":"cursors.cjs","sources":["../../src/collaboration-liveblocks/cursors.ts"],"sourcesContent":["import {\n type CollaborationCaretOptions,\n type CollaborationCaretStorage,\n createLiveblocksCollaborationCaretPlugin,\n getCursorUser,\n LIVEBLOCKS_CARET_PLUGIN_KEY,\n presencePatch,\n} from \"@liveblocks/prosemirror\";\nimport { Extension } from \"@tiptap/core\";\n\nexport { LIVEBLOCKS_CARET_PLUGIN_KEY };\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaborationCaret: {\n updateUser: (attributes: Record<string, any>) => ReturnType;\n user: (attributes: Record<string, any>) => ReturnType;\n };\n }\n}\n\nexport const LiveblocksCollaborationCaret = Extension.create<\n CollaborationCaretOptions,\n CollaborationCaretStorage\n>({\n name: \"collaborationCaret\",\n priority: 999,\n\n addOptions() {\n return {\n room: undefined,\n field: \"default\",\n user: {\n name: undefined,\n color: undefined,\n },\n };\n },\n\n addStorage() {\n return {\n users: [],\n };\n },\n\n addCommands() {\n return {\n updateUser:\n (attributes) =>\n ({ editor }) => {\n const nextUser =\n getCursorUser({\n ...this.options.user,\n name:\n typeof attributes.name === \"string\"\n ? attributes.name\n : this.options.user.name,\n color:\n typeof attributes.color === \"string\"\n ? attributes.color\n : this.options.user.color,\n }) ?? {};\n\n if (\n nextUser.name === this.options.user.name &&\n nextUser.color === this.options.user.color\n ) {\n return true;\n }\n\n this.options.user = nextUser;\n\n if (this.options.room !== undefined) {\n const { anchor, head } = editor.state.selection;\n this.options.room.updatePresence(\n presencePatch({\n field: this.options.field,\n anchor,\n head,\n user: this.options.user,\n })\n );\n }\n return true;\n },\n user:\n (attributes) =>\n ({ editor }) => {\n return editor.commands.updateUser(attributes);\n },\n };\n },\n\n addProseMirrorPlugins() {\n return [\n createLiveblocksCollaborationCaretPlugin(this.options, this.storage),\n ];\n },\n});\n"],"names":["Extension","getCursorUser","presencePatch","createLiveblocksCollaborationCaretPlugin"],"mappings":";;;;;AAqBa,MAAA,4BAAA,GAA+BA,eAAU,MAGpD,CAAA;AAAA,EACA,IAAM,EAAA,oBAAA;AAAA,EACN,QAAU,EAAA,GAAA;AAAA,EAEV,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,IAAM,EAAA,KAAA,CAAA;AAAA,MACN,KAAO,EAAA,SAAA;AAAA,MACP,IAAM,EAAA;AAAA,QACJ,IAAM,EAAA,KAAA,CAAA;AAAA,QACN,KAAO,EAAA,KAAA,CAAA;AAAA,OACT;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,OAAO,EAAC;AAAA,KACV,CAAA;AAAA,GACF;AAAA,EAEA,WAAc,GAAA;AACZ,IAAO,OAAA;AAAA,MACL,YACE,CAAC,UAAA,KACD,CAAC,EAAE,QAAa,KAAA;AACd,QAAA,MAAM,WACJC,yBAAc,CAAA;AAAA,UACZ,GAAG,KAAK,OAAQ,CAAA,IAAA;AAAA,UAChB,IAAA,EACE,OAAO,UAAW,CAAA,IAAA,KAAS,WACvB,UAAW,CAAA,IAAA,GACX,IAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,IAAA;AAAA,UACxB,KAAA,EACE,OAAO,UAAW,CAAA,KAAA,KAAU,WACxB,UAAW,CAAA,KAAA,GACX,IAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,KAAA;AAAA,SACzB,KAAK,EAAC,CAAA;AAET,QACE,IAAA,QAAA,CAAS,IAAS,KAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,IACpC,IAAA,QAAA,CAAS,KAAU,KAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,KACrC,EAAA;AACA,UAAO,OAAA,IAAA,CAAA;AAAA,SACT;AAEA,QAAA,IAAA,CAAK,QAAQ,IAAO,GAAA,QAAA,CAAA;AAEpB,QAAI,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,KAAS,KAAW,CAAA,EAAA;AACnC,UAAA,MAAM,EAAE,MAAA,EAAQ,IAAK,EAAA,GAAI,OAAO,KAAM,CAAA,SAAA,CAAA;AACtC,UAAA,IAAA,CAAK,QAAQ,IAAK,CAAA,cAAA;AAAA,YAChBC,yBAAc,CAAA;AAAA,cACZ,KAAA,EAAO,KAAK,OAAQ,CAAA,KAAA;AAAA,cACpB,MAAA;AAAA,cACA,IAAA;AAAA,cACA,IAAA,EAAM,KAAK,OAAQ,CAAA,IAAA;AAAA,aACpB,CAAA;AAAA,WACH,CAAA;AAAA,SACF;AACA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MACF,MACE,CAAC,UAAA,KACD,CAAC,EAAE,QAAa,KAAA;AACd,QAAO,OAAA,MAAA,CAAO,QAAS,CAAA,UAAA,CAAW,UAAU,CAAA,CAAA;AAAA,OAC9C;AAAA,KACJ,CAAA;AAAA,GACF;AAAA,EAEA,qBAAwB,GAAA;AACtB,IAAO,OAAA;AAAA,MACLC,oDAAyC,CAAA,IAAA,CAAK,OAAS,EAAA,IAAA,CAAK,OAAO,CAAA;AAAA,KACrE,CAAA;AAAA,GACF;AACF,CAAC;;;;;;;;"}
@@ -1,212 +1,7 @@
1
+ import { getCursorUser, presencePatch, createLiveblocksCollaborationCaretPlugin } from '@liveblocks/prosemirror';
2
+ export { LIVEBLOCKS_CARET_PLUGIN_KEY } from '@liveblocks/prosemirror';
1
3
  import { Extension } from '@tiptap/core';
2
- import { PluginKey, Selection, Plugin } from '@tiptap/pm/state';
3
- import { Decoration, DecorationSet } from '@tiptap/pm/view';
4
- import { LIVEBLOCKS_COLLABORATION_PLUGIN_KEY } from './plugin.js';
5
4
 
6
- const PRESENCE_KEY = "liveblocksTiptap";
7
- const LIVEBLOCKS_CARET_PLUGIN_KEY = new PluginKey("liveblocks-collaboration-caret");
8
- function isCursorPresence(value) {
9
- return typeof value === "object" && value !== null && typeof value.field === "string" && typeof value.anchor === "number" && typeof value.head === "number";
10
- }
11
- function getCursorUser(value) {
12
- if (typeof value !== "object" || value === null) {
13
- return void 0;
14
- }
15
- const user = value;
16
- const name = typeof user.name === "string" ? user.name : void 0;
17
- const color = typeof user.color === "string" ? user.color : void 0;
18
- return name !== void 0 || color !== void 0 ? { name, color } : void 0;
19
- }
20
- function presencePatch(presence) {
21
- const user = getCursorUser(presence.user);
22
- return {
23
- [PRESENCE_KEY]: {
24
- field: presence.field,
25
- anchor: presence.anchor,
26
- head: presence.head,
27
- ...user !== void 0 ? { user } : {}
28
- }
29
- };
30
- }
31
- function createCursorElement(user) {
32
- const color = user?.color ?? "#0f83ff";
33
- const name = user?.name ?? "Anonymous";
34
- const cursor = document.createElement("span");
35
- cursor.classList.add("collaboration-carets__caret");
36
- cursor.setAttribute("style", `border-color: ${color}`);
37
- const label = document.createElement("div");
38
- label.classList.add("collaboration-carets__label");
39
- label.setAttribute("style", `background-color: ${color}`);
40
- label.insertBefore(document.createTextNode(name), null);
41
- cursor.insertBefore(label, null);
42
- return cursor;
43
- }
44
- function clampPosition(position, doc) {
45
- return Math.max(0, Math.min(position, doc.content.size));
46
- }
47
- function normalizeCaretPosition(position, doc) {
48
- const clampedPosition = clampPosition(position, doc);
49
- const $position = doc.resolve(clampedPosition);
50
- if ($position.parent.isTextblock) {
51
- return clampedPosition;
52
- }
53
- return Selection.near($position, -1).anchor;
54
- }
55
- function getRemoteCursors(room, field, previousCursors = []) {
56
- const cursors = [];
57
- for (const other of room.getOthers()) {
58
- const rawPresence = other.presence[PRESENCE_KEY];
59
- if (!isCursorPresence(rawPresence) || rawPresence.field !== field) {
60
- continue;
61
- }
62
- const user = getCursorUser(rawPresence.user) ?? getCursorUser(other.info);
63
- const previousCursor = previousCursors.find(
64
- (cursor) => cursor.connectionId === other.connectionId
65
- );
66
- const hasPresencePositionChanged = previousCursor === void 0 || previousCursor.rawAnchor !== rawPresence.anchor || previousCursor.rawHead !== rawPresence.head;
67
- cursors.push({
68
- anchor: hasPresencePositionChanged ? rawPresence.anchor : previousCursor.anchor,
69
- connectionId: other.connectionId,
70
- head: hasPresencePositionChanged ? rawPresence.head : previousCursor.head,
71
- rawAnchor: rawPresence.anchor,
72
- rawHead: rawPresence.head,
73
- user
74
- });
75
- }
76
- return cursors;
77
- }
78
- function buildDecorationsFromCursors(cursors, doc) {
79
- const decorations = [];
80
- for (const cursor of cursors) {
81
- const anchor = clampPosition(cursor.anchor, doc);
82
- const head = clampPosition(cursor.head, doc);
83
- const from = Math.min(anchor, head);
84
- const to = Math.max(anchor, head);
85
- const user = cursor.user;
86
- const color = user?.color ?? "#0f83ff";
87
- if (from !== to) {
88
- decorations.push(
89
- Decoration.inline(from, to, {
90
- class: "collaboration-carets__selection",
91
- style: `background-color: ${color}33`
92
- })
93
- );
94
- }
95
- decorations.push(
96
- Decoration.widget(
97
- normalizeCaretPosition(head, doc),
98
- () => createCursorElement(user),
99
- {
100
- key: `liveblocks-caret-${cursor.connectionId}`,
101
- side: -1
102
- }
103
- )
104
- );
105
- }
106
- return DecorationSet.create(doc, decorations);
107
- }
108
- function createLiveblocksCaretPlugin(options, storage) {
109
- const room = options.room;
110
- if (room === void 0) {
111
- throw new Error("[Liveblocks] The Liveblocks caret plugin requires a room.");
112
- }
113
- let view;
114
- let unsubscribe;
115
- const updatePresence = (nextView) => {
116
- const { anchor, head } = nextView.state.selection;
117
- room.updatePresence(
118
- presencePatch({
119
- field: options.field,
120
- anchor,
121
- head,
122
- user: options.user
123
- })
124
- );
125
- };
126
- const updateDecorations = () => {
127
- if (view === void 0) {
128
- return;
129
- }
130
- storage.users = room.getOthers().map((other) => {
131
- const rawPresence = other.presence[PRESENCE_KEY];
132
- const cursorPresence = isCursorPresence(rawPresence) ? rawPresence : void 0;
133
- return {
134
- clientId: other.connectionId,
135
- ...getCursorUser(cursorPresence?.user) ?? getCursorUser(other.info)
136
- };
137
- });
138
- const previousCursors = LIVEBLOCKS_CARET_PLUGIN_KEY.getState(view.state)?.cursors ?? [];
139
- const cursors = getRemoteCursors(room, options.field, previousCursors);
140
- view.dispatch(
141
- view.state.tr.setMeta(LIVEBLOCKS_CARET_PLUGIN_KEY, {
142
- cursors
143
- })
144
- );
145
- };
146
- return new Plugin({
147
- key: LIVEBLOCKS_CARET_PLUGIN_KEY,
148
- state: {
149
- init(_, state) {
150
- return {
151
- cursors: [],
152
- decorations: DecorationSet.create(state.doc, [])
153
- };
154
- },
155
- apply(tr, state) {
156
- const meta = tr.getMeta(LIVEBLOCKS_CARET_PLUGIN_KEY);
157
- if (meta !== void 0) {
158
- return {
159
- cursors: meta.cursors,
160
- decorations: buildDecorationsFromCursors(meta.cursors, tr.doc)
161
- };
162
- }
163
- if (!tr.docChanged) {
164
- return state;
165
- }
166
- if (!tr.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY)) {
167
- const cursors = state.cursors.map((cursor) => ({
168
- ...cursor,
169
- anchor: tr.mapping.map(cursor.anchor, -1),
170
- head: tr.mapping.map(cursor.head, -1)
171
- }));
172
- return {
173
- cursors,
174
- decorations: buildDecorationsFromCursors(cursors, tr.doc)
175
- };
176
- }
177
- return {
178
- cursors: state.cursors,
179
- decorations: buildDecorationsFromCursors(state.cursors, tr.doc)
180
- };
181
- }
182
- },
183
- props: {
184
- decorations(state) {
185
- return LIVEBLOCKS_CARET_PLUGIN_KEY.getState(state)?.decorations ?? DecorationSet.empty;
186
- }
187
- },
188
- view(editorView) {
189
- view = editorView;
190
- updatePresence(editorView);
191
- updateDecorations();
192
- unsubscribe = room.events.others.subscribe(updateDecorations);
193
- return {
194
- update(nextView, prevState) {
195
- view = nextView;
196
- if (!nextView.state.selection.eq(prevState.selection)) {
197
- updatePresence(nextView);
198
- }
199
- },
200
- destroy() {
201
- unsubscribe?.();
202
- unsubscribe = void 0;
203
- view = void 0;
204
- room.updatePresence({ [PRESENCE_KEY]: null });
205
- }
206
- };
207
- }
208
- });
209
- }
210
5
  const LiveblocksCollaborationCaret = Extension.create({
211
6
  name: "collaborationCaret",
212
7
  priority: 999,
@@ -256,9 +51,11 @@ const LiveblocksCollaborationCaret = Extension.create({
256
51
  };
257
52
  },
258
53
  addProseMirrorPlugins() {
259
- return [createLiveblocksCaretPlugin(this.options, this.storage)];
54
+ return [
55
+ createLiveblocksCollaborationCaretPlugin(this.options, this.storage)
56
+ ];
260
57
  }
261
58
  });
262
59
 
263
- export { LIVEBLOCKS_CARET_PLUGIN_KEY, LiveblocksCollaborationCaret };
60
+ export { LiveblocksCollaborationCaret };
264
61
  //# sourceMappingURL=cursors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursors.js","sources":["../../src/collaboration-liveblocks/cursors.ts"],"sourcesContent":["import type { JsonObject } from \"@liveblocks/client\";\nimport { Extension } from \"@tiptap/core\";\nimport type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { Plugin, PluginKey, Selection } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\n\nimport { LIVEBLOCKS_COLLABORATION_PLUGIN_KEY } from \"./plugin\";\nimport type { LiveblocksTiptapRoom } from \"./types\";\n\nconst PRESENCE_KEY = \"liveblocksTiptap\";\n\ntype CursorUser = {\n name?: string;\n color?: string;\n};\n\ntype CursorPresence = {\n field: string;\n anchor: number;\n head: number;\n user?: CursorUser;\n};\n\ntype CollaborationCaretStorage = {\n users: { clientId: number; [key: string]: unknown }[];\n};\n\ntype RemoteCursor = {\n anchor: number;\n connectionId: number;\n head: number;\n rawAnchor: number;\n rawHead: number;\n user?: CursorUser;\n};\n\ntype CollaborationCaretPluginState = {\n cursors: RemoteCursor[];\n decorations: DecorationSet;\n};\n\ntype CollaborationCaretOptions = {\n room?: LiveblocksTiptapRoom;\n field: string;\n user: CursorUser;\n};\n\nexport const LIVEBLOCKS_CARET_PLUGIN_KEY =\n new PluginKey<CollaborationCaretPluginState>(\"liveblocks-collaboration-caret\");\n\nfunction isCursorPresence(value: unknown): value is CursorPresence {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { field?: unknown }).field === \"string\" &&\n typeof (value as { anchor?: unknown }).anchor === \"number\" &&\n typeof (value as { head?: unknown }).head === \"number\"\n );\n}\n\nfunction getCursorUser(value: unknown): CursorUser | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n\n const user = value as { name?: unknown; color?: unknown };\n const name = typeof user.name === \"string\" ? user.name : undefined;\n const color = typeof user.color === \"string\" ? user.color : undefined;\n\n return name !== undefined || color !== undefined ? { name, color } : undefined;\n}\n\nfunction presencePatch(presence: CursorPresence): JsonObject {\n const user = getCursorUser(presence.user);\n\n return {\n [PRESENCE_KEY]: {\n field: presence.field,\n anchor: presence.anchor,\n head: presence.head,\n ...(user !== undefined ? { user } : {}),\n },\n };\n}\n\nfunction createCursorElement(user: CursorUser | undefined): HTMLElement {\n const color = user?.color ?? \"#0f83ff\";\n const name = user?.name ?? \"Anonymous\";\n const cursor = document.createElement(\"span\");\n\n cursor.classList.add(\"collaboration-carets__caret\");\n cursor.setAttribute(\"style\", `border-color: ${color}`);\n\n const label = document.createElement(\"div\");\n label.classList.add(\"collaboration-carets__label\");\n label.setAttribute(\"style\", `background-color: ${color}`);\n label.insertBefore(document.createTextNode(name), null);\n cursor.insertBefore(label, null);\n\n return cursor;\n}\n\nfunction clampPosition(position: number, doc: ProseMirrorNode): number {\n return Math.max(0, Math.min(position, doc.content.size));\n}\n\nfunction normalizeCaretPosition(position: number, doc: ProseMirrorNode): number {\n const clampedPosition = clampPosition(position, doc);\n const $position = doc.resolve(clampedPosition);\n\n if ($position.parent.isTextblock) {\n return clampedPosition;\n }\n\n return Selection.near($position, -1).anchor;\n}\n\nfunction getRemoteCursors(\n room: LiveblocksTiptapRoom,\n field: string,\n previousCursors: readonly RemoteCursor[] = []\n): RemoteCursor[] {\n const cursors: RemoteCursor[] = [];\n\n for (const other of room.getOthers()) {\n const rawPresence: unknown = other.presence[PRESENCE_KEY];\n if (!isCursorPresence(rawPresence) || rawPresence.field !== field) {\n continue;\n }\n\n const user = getCursorUser(rawPresence.user) ?? getCursorUser(other.info);\n const previousCursor = previousCursors.find(\n (cursor) => cursor.connectionId === other.connectionId\n );\n const hasPresencePositionChanged =\n previousCursor === undefined ||\n previousCursor.rawAnchor !== rawPresence.anchor ||\n previousCursor.rawHead !== rawPresence.head;\n\n cursors.push({\n anchor: hasPresencePositionChanged\n ? rawPresence.anchor\n : previousCursor.anchor,\n connectionId: other.connectionId,\n head: hasPresencePositionChanged ? rawPresence.head : previousCursor.head,\n rawAnchor: rawPresence.anchor,\n rawHead: rawPresence.head,\n user,\n });\n }\n\n return cursors;\n}\n\nfunction buildDecorationsFromCursors(\n cursors: readonly RemoteCursor[],\n doc: ProseMirrorNode\n): DecorationSet {\n const decorations: Decoration[] = [];\n\n for (const cursor of cursors) {\n const anchor = clampPosition(cursor.anchor, doc);\n const head = clampPosition(cursor.head, doc);\n const from = Math.min(anchor, head);\n const to = Math.max(anchor, head);\n const user = cursor.user;\n const color = user?.color ?? \"#0f83ff\";\n\n if (from !== to) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"collaboration-carets__selection\",\n style: `background-color: ${color}33`,\n })\n );\n }\n\n decorations.push(\n Decoration.widget(\n normalizeCaretPosition(head, doc),\n () => createCursorElement(user),\n {\n key: `liveblocks-caret-${cursor.connectionId}`,\n side: -1,\n }\n )\n );\n }\n\n return DecorationSet.create(doc, decorations);\n}\n\nfunction createLiveblocksCaretPlugin(\n options: CollaborationCaretOptions,\n storage: CollaborationCaretStorage\n): Plugin {\n const room = options.room;\n if (room === undefined) {\n throw new Error(\"[Liveblocks] The Liveblocks caret plugin requires a room.\");\n }\n\n let view: EditorView | undefined;\n let unsubscribe: (() => void) | undefined;\n\n const updatePresence = (nextView: EditorView) => {\n const { anchor, head } = nextView.state.selection;\n room.updatePresence(\n presencePatch({\n field: options.field,\n anchor,\n head,\n user: options.user,\n })\n );\n };\n\n const updateDecorations = () => {\n if (view === undefined) {\n return;\n }\n\n storage.users = room.getOthers().map((other) => {\n const rawPresence: unknown = other.presence[PRESENCE_KEY];\n const cursorPresence = isCursorPresence(rawPresence)\n ? rawPresence\n : undefined;\n\n return {\n clientId: other.connectionId,\n ...(getCursorUser(cursorPresence?.user) ?? getCursorUser(other.info)),\n };\n });\n\n const previousCursors =\n LIVEBLOCKS_CARET_PLUGIN_KEY.getState(view.state)?.cursors ?? [];\n const cursors = getRemoteCursors(room, options.field, previousCursors);\n\n view.dispatch(\n view.state.tr.setMeta(LIVEBLOCKS_CARET_PLUGIN_KEY, {\n cursors,\n })\n );\n };\n\n return new Plugin({\n key: LIVEBLOCKS_CARET_PLUGIN_KEY,\n state: {\n init(_, state): CollaborationCaretPluginState {\n return {\n cursors: [],\n decorations: DecorationSet.create(state.doc, []),\n };\n },\n apply(tr, state): CollaborationCaretPluginState {\n const meta = tr.getMeta(LIVEBLOCKS_CARET_PLUGIN_KEY) as\n | { cursors: RemoteCursor[] }\n | undefined;\n\n if (meta !== undefined) {\n return {\n cursors: meta.cursors,\n decorations: buildDecorationsFromCursors(meta.cursors, tr.doc),\n };\n }\n\n if (!tr.docChanged) {\n return state;\n }\n\n if (!tr.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY)) {\n const cursors = state.cursors.map((cursor) => ({\n ...cursor,\n anchor: tr.mapping.map(cursor.anchor, -1),\n head: tr.mapping.map(cursor.head, -1),\n }));\n\n return {\n cursors,\n decorations: buildDecorationsFromCursors(cursors, tr.doc),\n };\n }\n\n // Remote presence can arrive before the matching remote document\n // update. Keep the stored cursor positions and rebuild them against\n // the new document so pre-arrived presence is no longer clamped to the\n // old document size.\n return {\n cursors: state.cursors,\n decorations: buildDecorationsFromCursors(state.cursors, tr.doc),\n };\n },\n },\n props: {\n decorations(state) {\n return (\n LIVEBLOCKS_CARET_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n },\n view(editorView) {\n view = editorView;\n updatePresence(editorView);\n updateDecorations();\n unsubscribe = room.events.others.subscribe(updateDecorations);\n\n return {\n update(nextView, prevState) {\n view = nextView;\n\n if (!nextView.state.selection.eq(prevState.selection)) {\n updatePresence(nextView);\n }\n\n },\n destroy() {\n unsubscribe?.();\n unsubscribe = undefined;\n view = undefined;\n room.updatePresence({ [PRESENCE_KEY]: null });\n },\n };\n },\n });\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaborationCaret: {\n updateUser: (attributes: Record<string, any>) => ReturnType;\n user: (attributes: Record<string, any>) => ReturnType;\n };\n }\n}\n\nexport const LiveblocksCollaborationCaret = Extension.create<\n CollaborationCaretOptions,\n CollaborationCaretStorage\n>({\n name: \"collaborationCaret\",\n priority: 999,\n\n addOptions() {\n return {\n room: undefined,\n field: \"default\",\n user: {\n name: undefined,\n color: undefined,\n },\n };\n },\n\n addStorage() {\n return {\n users: [],\n };\n },\n\n addCommands() {\n return {\n updateUser:\n (attributes) =>\n ({ editor }) => {\n const nextUser = getCursorUser({\n ...this.options.user,\n name:\n typeof attributes.name === \"string\"\n ? attributes.name\n : this.options.user.name,\n color:\n typeof attributes.color === \"string\"\n ? attributes.color\n : this.options.user.color,\n }) ?? {};\n\n if (\n nextUser.name === this.options.user.name &&\n nextUser.color === this.options.user.color\n ) {\n return true;\n }\n\n this.options.user = nextUser;\n\n if (this.options.room !== undefined) {\n const { anchor, head } = editor.state.selection;\n this.options.room.updatePresence(\n presencePatch({\n field: this.options.field,\n anchor,\n head,\n user: this.options.user,\n })\n );\n }\n return true;\n },\n user:\n (attributes) =>\n ({ editor }) => {\n return editor.commands.updateUser(attributes);\n },\n };\n },\n\n addProseMirrorPlugins() {\n return [createLiveblocksCaretPlugin(this.options, this.storage)];\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cursors.js","sources":["../../src/collaboration-liveblocks/cursors.ts"],"sourcesContent":["import {\n type CollaborationCaretOptions,\n type CollaborationCaretStorage,\n createLiveblocksCollaborationCaretPlugin,\n getCursorUser,\n LIVEBLOCKS_CARET_PLUGIN_KEY,\n presencePatch,\n} from \"@liveblocks/prosemirror\";\nimport { Extension } from \"@tiptap/core\";\n\nexport { LIVEBLOCKS_CARET_PLUGIN_KEY };\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaborationCaret: {\n updateUser: (attributes: Record<string, any>) => ReturnType;\n user: (attributes: Record<string, any>) => ReturnType;\n };\n }\n}\n\nexport const LiveblocksCollaborationCaret = Extension.create<\n CollaborationCaretOptions,\n CollaborationCaretStorage\n>({\n name: \"collaborationCaret\",\n priority: 999,\n\n addOptions() {\n return {\n room: undefined,\n field: \"default\",\n user: {\n name: undefined,\n color: undefined,\n },\n };\n },\n\n addStorage() {\n return {\n users: [],\n };\n },\n\n addCommands() {\n return {\n updateUser:\n (attributes) =>\n ({ editor }) => {\n const nextUser =\n getCursorUser({\n ...this.options.user,\n name:\n typeof attributes.name === \"string\"\n ? attributes.name\n : this.options.user.name,\n color:\n typeof attributes.color === \"string\"\n ? attributes.color\n : this.options.user.color,\n }) ?? {};\n\n if (\n nextUser.name === this.options.user.name &&\n nextUser.color === this.options.user.color\n ) {\n return true;\n }\n\n this.options.user = nextUser;\n\n if (this.options.room !== undefined) {\n const { anchor, head } = editor.state.selection;\n this.options.room.updatePresence(\n presencePatch({\n field: this.options.field,\n anchor,\n head,\n user: this.options.user,\n })\n );\n }\n return true;\n },\n user:\n (attributes) =>\n ({ editor }) => {\n return editor.commands.updateUser(attributes);\n },\n };\n },\n\n addProseMirrorPlugins() {\n return [\n createLiveblocksCollaborationCaretPlugin(this.options, this.storage),\n ];\n },\n});\n"],"names":[],"mappings":";;;;AAqBa,MAAA,4BAAA,GAA+B,UAAU,MAGpD,CAAA;AAAA,EACA,IAAM,EAAA,oBAAA;AAAA,EACN,QAAU,EAAA,GAAA;AAAA,EAEV,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,IAAM,EAAA,KAAA,CAAA;AAAA,MACN,KAAO,EAAA,SAAA;AAAA,MACP,IAAM,EAAA;AAAA,QACJ,IAAM,EAAA,KAAA,CAAA;AAAA,QACN,KAAO,EAAA,KAAA,CAAA;AAAA,OACT;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,OAAO,EAAC;AAAA,KACV,CAAA;AAAA,GACF;AAAA,EAEA,WAAc,GAAA;AACZ,IAAO,OAAA;AAAA,MACL,YACE,CAAC,UAAA,KACD,CAAC,EAAE,QAAa,KAAA;AACd,QAAA,MAAM,WACJ,aAAc,CAAA;AAAA,UACZ,GAAG,KAAK,OAAQ,CAAA,IAAA;AAAA,UAChB,IAAA,EACE,OAAO,UAAW,CAAA,IAAA,KAAS,WACvB,UAAW,CAAA,IAAA,GACX,IAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,IAAA;AAAA,UACxB,KAAA,EACE,OAAO,UAAW,CAAA,KAAA,KAAU,WACxB,UAAW,CAAA,KAAA,GACX,IAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,KAAA;AAAA,SACzB,KAAK,EAAC,CAAA;AAET,QACE,IAAA,QAAA,CAAS,IAAS,KAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,IACpC,IAAA,QAAA,CAAS,KAAU,KAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,KACrC,EAAA;AACA,UAAO,OAAA,IAAA,CAAA;AAAA,SACT;AAEA,QAAA,IAAA,CAAK,QAAQ,IAAO,GAAA,QAAA,CAAA;AAEpB,QAAI,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,KAAS,KAAW,CAAA,EAAA;AACnC,UAAA,MAAM,EAAE,MAAA,EAAQ,IAAK,EAAA,GAAI,OAAO,KAAM,CAAA,SAAA,CAAA;AACtC,UAAA,IAAA,CAAK,QAAQ,IAAK,CAAA,cAAA;AAAA,YAChB,aAAc,CAAA;AAAA,cACZ,KAAA,EAAO,KAAK,OAAQ,CAAA,KAAA;AAAA,cACpB,MAAA;AAAA,cACA,IAAA;AAAA,cACA,IAAA,EAAM,KAAK,OAAQ,CAAA,IAAA;AAAA,aACpB,CAAA;AAAA,WACH,CAAA;AAAA,SACF;AACA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MACF,MACE,CAAC,UAAA,KACD,CAAC,EAAE,QAAa,KAAA;AACd,QAAO,OAAA,MAAA,CAAO,QAAS,CAAA,UAAA,CAAW,UAAU,CAAA,CAAA;AAAA,OAC9C;AAAA,KACJ,CAAA;AAAA,GACF;AAAA,EAEA,qBAAwB,GAAA;AACtB,IAAO,OAAA;AAAA,MACL,wCAAyC,CAAA,IAAA,CAAK,OAAS,EAAA,IAAA,CAAK,OAAO,CAAA;AAAA,KACrE,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
@@ -1,198 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var client = require('@liveblocks/client');
3
+ var prosemirror = require('@liveblocks/prosemirror');
4
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
5
  var schema = require('./schema.cjs');
9
- var steps = require('./steps.cjs');
10
6
 
11
- const LIVEBLOCKS_COLLABORATION_PLUGIN_KEY = new state.PluginKey("liveblocks-collaboration");
12
7
  function isProseMirrorJsonNode(value) {
13
8
  return typeof value === "object" && value !== null && typeof value.type === "string";
14
9
  }
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
- let nextDocument;
27
- try {
28
- nextDocument = view.state.schema.nodeFromJSON(document);
29
- } catch {
30
- nextDocument = view.state.schema.nodeFromJSON(schema.createDefaultDocument());
31
- }
32
- if (nextDocument.childCount === 0) {
33
- nextDocument = view.state.schema.nodeFromJSON(schema.createDefaultDocument());
34
- }
35
- const tr = view.state.tr.replace(
36
- 0,
37
- view.state.doc.content.size,
38
- new model.Slice(nextDocument.content, 0, 0)
39
- );
40
- tr.setMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY, { isRemote: true }).setMeta(
41
- "addToHistory",
42
- false
43
- );
44
- view.dispatch(tr);
45
- }
46
- function getDocumentRoot(root, field) {
47
- const documentRoot = root.get(field);
48
- if (!(documentRoot instanceof client.LiveObject)) {
49
- return void 0;
50
- }
51
- return documentRoot;
52
- }
53
- function setDocumentRoot(root, field, document) {
54
- root.set(field, schema.createLiveblocksTiptapNode(document));
55
- }
56
- function createLiveblocksCollaborationPlugin(options) {
57
- const room = options.room;
58
- if (room === void 0) {
59
- throw new Error(
60
- "[Liveblocks] The Liveblocks collaboration plugin requires a room."
61
- );
62
- }
63
- let view;
64
- let root;
65
- let unsubscribe;
66
- let destroyed = false;
67
- let isApplyingRemoteUpdate = false;
68
- let isApplyingLocalUpdate = false;
69
- let lastDocument = "";
70
- const applyStorageToEditor = (updates) => {
71
- if (view === void 0 || root === void 0) {
72
- return;
73
- }
74
- const documentRoot = getDocumentRoot(root, options.field);
75
- if (documentRoot === void 0) {
76
- return;
77
- }
78
- if (isApplyingLocalUpdate) {
79
- return;
80
- }
81
- const document = schema.liveblocksTiptapNodeToJson(documentRoot);
82
- const serializedDocument = schema.stringifyDocument(document);
83
- if (serializedDocument === lastDocument) {
84
- return;
85
- }
86
- if (updates !== void 0) {
87
- const result = remote.applyRemoteStorageUpdates(view, documentRoot, updates);
88
- if (result.type === "applied") {
89
- lastDocument = serializedDocument;
90
- isApplyingRemoteUpdate = true;
91
- try {
92
- view.dispatch(
93
- result.tr.setMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY, { isRemote: true }).setMeta("addToHistory", false)
94
- );
95
- } finally {
96
- isApplyingRemoteUpdate = false;
97
- }
98
- return;
99
- }
100
- }
101
- lastDocument = serializedDocument;
102
- isApplyingRemoteUpdate = true;
103
- try {
104
- replaceEditorDocument(view, document);
105
- } finally {
106
- isApplyingRemoteUpdate = false;
107
- }
108
- };
109
- return new state.Plugin({
110
- key: LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,
111
- state: {
112
- init: () => ({ isReady: false }),
113
- apply(tr, state) {
114
- const meta = tr.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY);
115
- return meta?.isReady !== void 0 ? { ...state, isReady: meta.isReady } : state;
116
- }
117
- },
118
- appendTransaction(transactions, oldState, newState) {
119
- if (root === void 0 || isApplyingRemoteUpdate || !transactions.some((transaction) => transaction.docChanged) || transactions.some(
120
- (transaction) => Boolean(transaction.getMeta(LIVEBLOCKS_COLLABORATION_PLUGIN_KEY))
121
- )) {
122
- return null;
123
- }
124
- const currentRoot = root;
125
- const documentRoot = getDocumentRoot(currentRoot, options.field);
126
- const classified = documentRoot !== void 0 ? steps.classifyTransaction(
127
- transactions,
128
- oldState.doc,
129
- newState.doc,
130
- documentRoot
131
- ) : { type: "unsupported" };
132
- room.batch(() => {
133
- if (classified.type === "incremental") {
134
- isApplyingLocalUpdate = true;
135
- try {
136
- steps.applyIncrementalOperations(classified.operations);
137
- } finally {
138
- isApplyingLocalUpdate = false;
139
- }
140
- } else {
141
- const document = newState.doc.toJSON();
142
- if (!isProseMirrorJsonNode(document)) {
143
- return;
144
- }
145
- const serializedDocument = schema.stringifyDocument(document);
146
- if (serializedDocument === lastDocument) {
147
- return;
148
- }
149
- lastDocument = serializedDocument;
150
- setDocumentRoot(currentRoot, options.field, document);
151
- }
152
- });
153
- return null;
154
- },
155
- view(editorView) {
156
- view = editorView;
157
- room.getStorage().then(({ root: storageRoot }) => {
158
- if (destroyed) {
159
- return;
160
- }
161
- root = storageRoot;
162
- if (getDocumentRoot(storageRoot, options.field) === void 0) {
163
- const initialDocument = getInitialDocument(
164
- options.initialContent,
165
- editorView
166
- );
167
- room.history.disable(() => {
168
- setDocumentRoot(storageRoot, options.field, initialDocument);
169
- });
170
- }
171
- applyStorageToEditor();
172
- const tr = editorView.state.tr.setMeta(
173
- LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,
174
- { isReady: true }
175
- );
176
- editorView.dispatch(tr);
177
- unsubscribe = room.subscribe(storageRoot, applyStorageToEditor, {
178
- isDeep: true
179
- });
180
- });
181
- return {
182
- update(nextView) {
183
- view = nextView;
184
- },
185
- destroy() {
186
- destroyed = true;
187
- unsubscribe?.();
188
- unsubscribe = void 0;
189
- view = void 0;
190
- root = void 0;
191
- }
192
- };
193
- }
194
- });
195
- }
196
10
  const LiveblocksCollaboration = core.Extension.create({
197
11
  name: "collaboration",
198
12
  priority: 1e3,
@@ -240,10 +54,20 @@ const LiveblocksCollaboration = core.Extension.create({
240
54
  };
241
55
  },
242
56
  addProseMirrorPlugins() {
243
- return [createLiveblocksCollaborationPlugin(this.options)];
57
+ return [
58
+ prosemirror.createLiveblocksCollaborationPlugin({
59
+ room: this.options.room,
60
+ field: this.options.field,
61
+ initialContent: isProseMirrorJsonNode(this.options.initialContent) ? this.options.initialContent : void 0,
62
+ fallbackDocument: schema.createDefaultDocument
63
+ })
64
+ ];
244
65
  }
245
66
  });
246
67
 
247
- exports.LIVEBLOCKS_COLLABORATION_PLUGIN_KEY = LIVEBLOCKS_COLLABORATION_PLUGIN_KEY;
68
+ Object.defineProperty(exports, 'LIVEBLOCKS_COLLABORATION_PLUGIN_KEY', {
69
+ enumerable: true,
70
+ get: function () { return prosemirror.LIVEBLOCKS_COLLABORATION_PLUGIN_KEY; }
71
+ });
248
72
  exports.LiveblocksCollaboration = LiveblocksCollaboration;
249
73
  //# sourceMappingURL=plugin.cjs.map
@@ -1 +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 let nextDocument;\n try {\n nextDocument = view.state.schema.nodeFromJSON(document);\n } catch {\n nextDocument = view.state.schema.nodeFromJSON(createDefaultDocument());\n }\n\n if (nextDocument.childCount === 0) {\n nextDocument = view.state.schema.nodeFromJSON(createDefaultDocument());\n }\n\n const tr = view.state.tr.replace(\n 0,\n view.state.doc.content.size,\n new Slice(nextDocument.content, 0, 0)\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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"}
1
+ {"version":3,"file":"plugin.cjs","sources":["../../src/collaboration-liveblocks/plugin.ts"],"sourcesContent":["import {\n createLiveblocksCollaborationPlugin,\n LIVEBLOCKS_COLLABORATION_PLUGIN_KEY,\n type LiveblocksProsemirrorRoom,\n type ProseMirrorJsonNode,\n} from \"@liveblocks/prosemirror\";\nimport type { Content } from \"@tiptap/core\";\nimport { Extension } from \"@tiptap/core\";\n\nimport { createDefaultDocument } from \"./schema\";\n\nexport { LIVEBLOCKS_COLLABORATION_PLUGIN_KEY };\n\ntype LiveblocksCollaborationOptions = {\n room?: LiveblocksProsemirrorRoom;\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\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 [\n createLiveblocksCollaborationPlugin({\n room: this.options.room,\n field: this.options.field,\n initialContent: isProseMirrorJsonNode(this.options.initialContent)\n ? this.options.initialContent\n : undefined,\n fallbackDocument: createDefaultDocument,\n }),\n ];\n },\n});\n"],"names":["Extension","createLiveblocksCollaborationPlugin","createDefaultDocument"],"mappings":";;;;;;AAuBA,SAAS,sBAAsB,KAA8C,EAAA;AAC3E,EAAA,OACE,OAAO,KAAU,KAAA,QAAA,IACjB,UAAU,IACV,IAAA,OAAQ,MAA6B,IAAS,KAAA,QAAA,CAAA;AAElD,CAAA;AAWa,MAAA,uBAAA,GAA0BA,eAAU,MAG/C,CAAA;AAAA,EACA,IAAM,EAAA,eAAA;AAAA,EACN,QAAU,EAAA,GAAA;AAAA,EAEV,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,IAAM,EAAA,KAAA,CAAA;AAAA,MACN,KAAO,EAAA,SAAA;AAAA,MACP,cAAgB,EAAA,KAAA,CAAA;AAAA,KAClB,CAAA;AAAA,GACF;AAAA,EAEA,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,UAAY,EAAA,KAAA;AAAA,KACd,CAAA;AAAA,GACF;AAAA,EAEA,WAAc,GAAA;AACZ,IAAO,OAAA;AAAA,MACL,MACE,MACA,CAAC,EAAE,QAAA,EAAU,IAAS,KAAA;AACpB,QAAG,EAAA,CAAA,OAAA,CAAQ,mBAAmB,IAAI,CAAA,CAAA;AAElC,QACE,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,KAAS,KACtB,CAAA,IAAA,CAAC,KAAK,OAAQ,CAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,EAC3B,EAAA;AACA,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAEA,QAAA,IAAI,QAAU,EAAA;AACZ,UAAK,IAAA,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA,CAAQ,IAAK,EAAA,CAAA;AAAA,SACjC;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MACF,MACE,MACA,CAAC,EAAE,QAAA,EAAU,IAAS,KAAA;AACpB,QAAG,EAAA,CAAA,OAAA,CAAQ,mBAAmB,IAAI,CAAA,CAAA;AAElC,QACE,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,KAAS,KACtB,CAAA,IAAA,CAAC,KAAK,OAAQ,CAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,EAC3B,EAAA;AACA,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAEA,QAAA,IAAI,QAAU,EAAA;AACZ,UAAK,IAAA,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA,CAAQ,IAAK,EAAA,CAAA;AAAA,SACjC;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,KACJ,CAAA;AAAA,GACF;AAAA,EAEA,oBAAuB,GAAA;AACrB,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,MAAM,IAAK,CAAA,MAAA,CAAO,SAAS,IAAK,EAAA;AAAA,MACzC,OAAS,EAAA,MAAM,IAAK,CAAA,MAAA,CAAO,SAAS,IAAK,EAAA;AAAA,MACzC,aAAe,EAAA,MAAM,IAAK,CAAA,MAAA,CAAO,SAAS,IAAK,EAAA;AAAA,KACjD,CAAA;AAAA,GACF;AAAA,EAEA,qBAAwB,GAAA;AACtB,IAAO,OAAA;AAAA,MACLC,+CAAoC,CAAA;AAAA,QAClC,IAAA,EAAM,KAAK,OAAQ,CAAA,IAAA;AAAA,QACnB,KAAA,EAAO,KAAK,OAAQ,CAAA,KAAA;AAAA,QACpB,cAAA,EAAgB,sBAAsB,IAAK,CAAA,OAAA,CAAQ,cAAc,CAC7D,GAAA,IAAA,CAAK,QAAQ,cACb,GAAA,KAAA,CAAA;AAAA,QACJ,gBAAkB,EAAAC,4BAAA;AAAA,OACnB,CAAA;AAAA,KACH,CAAA;AAAA,GACF;AACF,CAAC;;;;;;;;"}