@liveblocks/react-tiptap 3.19.5-rc1 → 3.20.0-exp2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LiveblocksExtension.cjs +51 -5
- package/dist/LiveblocksExtension.cjs.map +1 -1
- package/dist/LiveblocksExtension.js +51 -5
- package/dist/LiveblocksExtension.js.map +1 -1
- package/dist/ai/AiExtension.cjs +2 -1
- package/dist/ai/AiExtension.cjs.map +1 -1
- package/dist/ai/AiExtension.js +2 -1
- package/dist/ai/AiExtension.js.map +1 -1
- package/dist/collaboration-liveblocks/cursors.cjs +267 -0
- package/dist/collaboration-liveblocks/cursors.cjs.map +1 -0
- package/dist/collaboration-liveblocks/cursors.js +264 -0
- package/dist/collaboration-liveblocks/cursors.js.map +1 -0
- package/dist/collaboration-liveblocks/mapping.cjs +218 -0
- package/dist/collaboration-liveblocks/mapping.cjs.map +1 -0
- package/dist/collaboration-liveblocks/mapping.js +207 -0
- package/dist/collaboration-liveblocks/mapping.js.map +1 -0
- package/dist/collaboration-liveblocks/plugin.cjs +249 -0
- package/dist/collaboration-liveblocks/plugin.cjs.map +1 -0
- package/dist/collaboration-liveblocks/plugin.js +246 -0
- package/dist/collaboration-liveblocks/plugin.js.map +1 -0
- package/dist/collaboration-liveblocks/remote.cjs +210 -0
- package/dist/collaboration-liveblocks/remote.cjs.map +1 -0
- package/dist/collaboration-liveblocks/remote.js +207 -0
- package/dist/collaboration-liveblocks/remote.js.map +1 -0
- package/dist/collaboration-liveblocks/schema.cjs +150 -0
- package/dist/collaboration-liveblocks/schema.cjs.map +1 -0
- package/dist/collaboration-liveblocks/schema.js +135 -0
- package/dist/collaboration-liveblocks/schema.js.map +1 -0
- package/dist/collaboration-liveblocks/steps.cjs +359 -0
- package/dist/collaboration-liveblocks/steps.cjs.map +1 -0
- package/dist/collaboration-liveblocks/steps.js +356 -0
- package/dist/collaboration-liveblocks/steps.js.map +1 -0
- package/dist/comments/CommentsExtension.cjs +7 -1
- package/dist/comments/CommentsExtension.cjs.map +1 -1
- package/dist/comments/CommentsExtension.js +7 -1
- package/dist/comments/CommentsExtension.js.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/mentions/MentionExtension.cjs +4 -1
- package/dist/mentions/MentionExtension.cjs.map +1 -1
- package/dist/mentions/MentionExtension.js +4 -1
- package/dist/mentions/MentionExtension.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
- package/src/styles/index.css +12 -4
- package/styles.css +1 -1
- package/styles.css.map +1 -1
|
@@ -10,12 +10,15 @@ var react = require('react');
|
|
|
10
10
|
var AiExtension = require('./ai/AiExtension.cjs');
|
|
11
11
|
var collaboration = require('./collaboration/collaboration.cjs');
|
|
12
12
|
var collaborationCaret = require('./collaboration-caret/collaboration-caret.cjs');
|
|
13
|
+
var cursors = require('./collaboration-liveblocks/cursors.cjs');
|
|
14
|
+
var plugin = require('./collaboration-liveblocks/plugin.cjs');
|
|
13
15
|
var CommentsExtension = require('./comments/CommentsExtension.cjs');
|
|
14
16
|
var MentionExtension = require('./mentions/MentionExtension.cjs');
|
|
15
17
|
var types = require('./types.cjs');
|
|
16
18
|
var utils = require('./utils.cjs');
|
|
17
19
|
|
|
18
20
|
const DEFAULT_OPTIONS = {
|
|
21
|
+
collaborationMode: "yjs",
|
|
19
22
|
field: "default",
|
|
20
23
|
comments: true,
|
|
21
24
|
mentions: true,
|
|
@@ -130,8 +133,10 @@ const useLiveblocksExtension = (opts) => {
|
|
|
130
133
|
const store = _private.getUmbrellaStoreForClient(client);
|
|
131
134
|
const roomId = room.id;
|
|
132
135
|
const yjsProvider = _private.useYjsProvider();
|
|
136
|
+
const isLiveblocksStorageMode = options.collaborationMode === "liveblocks";
|
|
137
|
+
const isReadyForSideEffects = isLiveblocksStorageMode || isEditorReady;
|
|
133
138
|
react.useEffect(() => {
|
|
134
|
-
if (!isEditorReady || !yjsProvider || !options.initialContent || !editor.current)
|
|
139
|
+
if (isLiveblocksStorageMode || !isEditorReady || !yjsProvider || !options.initialContent || !editor.current)
|
|
135
140
|
return;
|
|
136
141
|
const ydoc = yjsProvider.getYDoc();
|
|
137
142
|
const hasContentSet = ydoc.getMap("liveblocks_config").get("hasContentSet");
|
|
@@ -139,11 +144,16 @@ const useLiveblocksExtension = (opts) => {
|
|
|
139
144
|
ydoc.getMap("liveblocks_config").set("hasContentSet", true);
|
|
140
145
|
editor.current.commands.setContent(options.initialContent);
|
|
141
146
|
}
|
|
142
|
-
}, [
|
|
147
|
+
}, [
|
|
148
|
+
isEditorReady,
|
|
149
|
+
isLiveblocksStorageMode,
|
|
150
|
+
yjsProvider,
|
|
151
|
+
options.initialContent
|
|
152
|
+
]);
|
|
143
153
|
_private.useReportTextEditor(textEditorType, options.field ?? DEFAULT_OPTIONS.field);
|
|
144
154
|
const prevThreadsRef = react.useRef(void 0);
|
|
145
155
|
react.useEffect(() => {
|
|
146
|
-
if (!
|
|
156
|
+
if (!isReadyForSideEffects) return;
|
|
147
157
|
if (!editor.current) return;
|
|
148
158
|
const newThreads = options.threads_experimental ? new Set(options.threads_experimental.map((t) => t.id)) : void 0;
|
|
149
159
|
const hasFilteredThreadsChanged = !utils.areSetsEqual(
|
|
@@ -160,7 +170,7 @@ const useLiveblocksExtension = (opts) => {
|
|
|
160
170
|
})
|
|
161
171
|
);
|
|
162
172
|
}
|
|
163
|
-
}, [
|
|
173
|
+
}, [isReadyForSideEffects, options.threads_experimental]);
|
|
164
174
|
const createTextMention = _private.useCreateTextMention();
|
|
165
175
|
const deleteTextMention = _private.useDeleteTextMention();
|
|
166
176
|
return core.Extension.create({
|
|
@@ -187,6 +197,13 @@ const useLiveblocksExtension = (opts) => {
|
|
|
187
197
|
if (!info) {
|
|
188
198
|
return;
|
|
189
199
|
}
|
|
200
|
+
if (this.storage.mode === "liveblocks") {
|
|
201
|
+
this.editor.commands.updateUser({
|
|
202
|
+
name: info.name,
|
|
203
|
+
color: info.color
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
190
207
|
const { user: storedUser } = this.storage.provider.awareness.getLocalState();
|
|
191
208
|
if (this.storage.permanentUserData) {
|
|
192
209
|
const pud = this.storage.permanentUserData.clients.get(
|
|
@@ -270,11 +287,18 @@ const useLiveblocksExtension = (opts) => {
|
|
|
270
287
|
];
|
|
271
288
|
},
|
|
272
289
|
addStorage() {
|
|
290
|
+
if (isLiveblocksStorageMode) {
|
|
291
|
+
return {
|
|
292
|
+
mode: "liveblocks",
|
|
293
|
+
unsubs: []
|
|
294
|
+
};
|
|
295
|
+
}
|
|
273
296
|
const provider = yjs.getYjsProviderForRoom(room, {
|
|
274
297
|
enablePermanentUserData: !!options.ai || options.enablePermanentUserData,
|
|
275
298
|
offlineSupport_experimental: options.offlineSupport_experimental
|
|
276
299
|
});
|
|
277
300
|
return {
|
|
301
|
+
mode: "yjs",
|
|
278
302
|
doc: provider.getYDoc(),
|
|
279
303
|
provider,
|
|
280
304
|
permanentUserData: provider.permanentUserData,
|
|
@@ -282,7 +306,23 @@ const useLiveblocksExtension = (opts) => {
|
|
|
282
306
|
};
|
|
283
307
|
},
|
|
284
308
|
addExtensions() {
|
|
285
|
-
const
|
|
309
|
+
const selfInfo = room.getSelf()?.info;
|
|
310
|
+
const selfUser = selfInfo !== void 0 ? {
|
|
311
|
+
name: typeof selfInfo.name === "string" ? selfInfo.name : void 0,
|
|
312
|
+
color: typeof selfInfo.color === "string" ? selfInfo.color : void 0
|
|
313
|
+
} : void 0;
|
|
314
|
+
const extensions = this.storage.mode === "liveblocks" ? [
|
|
315
|
+
plugin.LiveblocksCollaboration.configure({
|
|
316
|
+
room,
|
|
317
|
+
field: options.field,
|
|
318
|
+
initialContent: options.initialContent
|
|
319
|
+
}),
|
|
320
|
+
cursors.LiveblocksCollaborationCaret.configure({
|
|
321
|
+
room,
|
|
322
|
+
field: options.field,
|
|
323
|
+
user: selfUser ?? {}
|
|
324
|
+
})
|
|
325
|
+
] : [
|
|
286
326
|
YChangeMark,
|
|
287
327
|
LiveblocksCollab.configure({
|
|
288
328
|
ySyncOptions: {
|
|
@@ -309,6 +349,12 @@ const useLiveblocksExtension = (opts) => {
|
|
|
309
349
|
);
|
|
310
350
|
}
|
|
311
351
|
if (options.ai) {
|
|
352
|
+
if (this.storage.mode === "liveblocks") {
|
|
353
|
+
console.warn(
|
|
354
|
+
"[Liveblocks] AI in @liveblocks/react-tiptap currently requires the Yjs collaboration mode."
|
|
355
|
+
);
|
|
356
|
+
return extensions;
|
|
357
|
+
}
|
|
312
358
|
const resolveContextualPrompt = async ({
|
|
313
359
|
prompt,
|
|
314
360
|
context,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveblocksExtension.cjs","sources":["../src/LiveblocksExtension.ts"],"sourcesContent":["import type {\n BaseUserMeta,\n IUserInfo,\n JsonObject,\n User,\n} from \"@liveblocks/core\";\nimport { kInternal, TextEditorType } from \"@liveblocks/core\";\nimport { useClient, useRoom } from \"@liveblocks/react\";\nimport {\n getUmbrellaStoreForClient,\n useCreateTextMention,\n useDeleteTextMention,\n useReportTextEditor,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { useInitial } from \"@liveblocks/react-ui/_private\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { AnyExtension, Editor } from \"@tiptap/core\";\nimport { Extension, getMarkType, Mark } from \"@tiptap/core\";\nimport type { Mark as PMMark } from \"@tiptap/pm/model\";\nimport { useCallback, useEffect, useRef, useSyncExternalStore } from \"react\";\n\nimport { AiExtension } from \"./ai/AiExtension\";\nimport { Collaboration } from \"./collaboration/collaboration\";\nimport {\n CollaborationCaret,\n type CollaborationCaretOptions,\n} from \"./collaboration-caret/collaboration-caret\";\nimport {\n CommentsExtension,\n FILTERED_THREADS_PLUGIN_KEY,\n} from \"./comments/CommentsExtension\";\nimport { MentionExtension } from \"./mentions/MentionExtension\";\nimport type {\n LiveblocksExtensionOptions,\n LiveblocksExtensionStorage,\n ResolveContextualPromptArgs,\n ResolveContextualPromptResponse,\n} from \"./types\";\nimport { LIVEBLOCKS_COMMENT_MARK_TYPE } from \"./types\";\nimport { areSetsEqual } from \"./utils\";\n\ntype WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\nconst DEFAULT_OPTIONS: WithRequired<LiveblocksExtensionOptions, \"field\"> = {\n field: \"default\",\n comments: true,\n mentions: true,\n offlineSupport_experimental: false,\n enablePermanentUserData: false,\n};\n\nconst LiveblocksCollab = Collaboration.extend({\n // Override the onCreate method to warn users about potential misconfigurations\n onCreate() {\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"doc\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap document extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n !this.editor.extensionManager.extensions.find(\n (e) => e.name === \"paragraph\"\n )\n ) {\n console.warn(\n \"[Liveblocks] The tiptap paragraph extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"text\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap text extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n this.editor.extensionManager.extensions.find((e) => e.name === \"undoRedo\")\n ) {\n console.warn(\n \"[Liveblocks] The undoRedo extension is enabled, Liveblocks extension provides its own. Please remove or disable the undoRedo extension to prevent conflicts.\"\n );\n }\n },\n});\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n *\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nconst YChangeMark = Mark.create({\n name: \"ychange\",\n inclusive: false,\n parseHTML() {\n return [{ tag: \"ychange\" }];\n },\n addAttributes() {\n return {\n user: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_user\") ?? null,\n renderHTML: (attributes: { user: string | null }) => {\n if (!attributes.user) {\n return {};\n }\n return { \"data-ychange-user\": attributes.user };\n },\n },\n type: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_type\") ?? null,\n renderHTML: (attributes: { type: string | null }) => {\n if (!attributes.type) {\n return {};\n }\n return {\n \"data-ychange-type\": attributes.type,\n \"data-liveblocks\": \"\",\n class: `lb-root lb-tiptap-change lb-tiptap-change-${attributes.type}`,\n };\n },\n },\n color: {\n default: null,\n parseHTML: (element) => {\n return element.getAttribute(\"ychange_color\") ?? null;\n },\n renderHTML: () => {\n // attributes: { color: { light: string; dark: string } | null }\n return {}; // we don't need this color attribute for now\n },\n },\n };\n },\n renderHTML({ HTMLAttributes }) {\n return [\"ychange\", HTMLAttributes, 0];\n },\n});\n\nexport const useLiveblocksExtension = (\n opts?: LiveblocksExtensionOptions\n): Extension => {\n const options = {\n ...DEFAULT_OPTIONS,\n ...opts,\n };\n const textEditorType = useInitial<TextEditorType>(\n options.textEditorType ?? TextEditorType.TipTap\n );\n const editor = useRef<Editor | null>(null);\n const room = useRoom();\n\n // TODO: we don't need these things if comments isn't turned on...\n // TODO: we don't have a reference to the editor here, need to figure this out\n // useErrorListener((error) => {\n // // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n // if (\n // error.context.type === \"CREATE_THREAD_ERROR\" &&\n // error.context.roomId === room.id\n // ) {\n // handleThreadDelete(error.context.threadId);\n // }\n // });\n\n const isEditorReady = useIsEditorReady();\n const client = useClient();\n const store = getUmbrellaStoreForClient(client);\n const roomId = room.id;\n const yjsProvider = useYjsProvider();\n\n // If the user provided initialContent, wait for ready and then set it\n useEffect(() => {\n if (\n !isEditorReady ||\n !yjsProvider ||\n !options.initialContent ||\n !editor.current\n )\n return;\n\n // As noted in the tiptap documentation, you may not set initial content with collaboration.\n // The docs provide the following workaround:\n const ydoc = (yjsProvider as LiveblocksYjsProvider).getYDoc();\n const hasContentSet = ydoc.getMap(\"liveblocks_config\").get(\"hasContentSet\");\n if (!hasContentSet) {\n ydoc.getMap(\"liveblocks_config\").set(\"hasContentSet\", true);\n editor.current.commands.setContent(options.initialContent);\n }\n }, [isEditorReady, yjsProvider, options.initialContent]);\n\n useReportTextEditor(textEditorType, options.field ?? DEFAULT_OPTIONS.field);\n\n const prevThreadsRef = useRef<Set<string> | undefined>(undefined);\n\n useEffect(() => {\n if (!isEditorReady) return;\n\n if (!editor.current) return;\n\n const newThreads = options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined;\n\n const hasFilteredThreadsChanged = !areSetsEqual(\n prevThreadsRef.current,\n newThreads\n );\n\n if (hasFilteredThreadsChanged) {\n prevThreadsRef.current = newThreads;\n }\n\n if (hasFilteredThreadsChanged) {\n editor.current.view.dispatch(\n editor.current.state.tr.setMeta(FILTERED_THREADS_PLUGIN_KEY, {\n filteredThreads: options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined,\n })\n );\n }\n }, [isEditorReady, options.threads_experimental]);\n\n const createTextMention = useCreateTextMention();\n const deleteTextMention = useDeleteTextMention();\n\n // Tiptap has options default as any, in tiptap2, we could use never, but now we must use any\n return Extension.create<any, LiveblocksExtensionStorage>({\n name: \"liveblocksExtension\",\n\n onCreate() {\n editor.current = this.editor;\n if (this.editor.options.content) {\n console.warn(\n \"[Liveblocks] Initial content must be set in the useLiveblocksExtension hook option. Remove content from your editor options.\"\n );\n }\n if (\n options.mentions &&\n this.editor.extensionManager.extensions.find(\n (e) => e.name.toLowerCase() === \"mention\"\n )\n ) {\n console.warn(\n \"[Liveblocks] Liveblocks own mention plugin is enabled, using another mention plugin may cause a conflict.\"\n );\n }\n const self = room.getSelf();\n const updateUser = ({\n info,\n id: userId,\n }: User<JsonObject, BaseUserMeta>) => {\n if (!info) {\n return;\n }\n const { user: storedUser } =\n this.storage.provider.awareness.getLocalState() as {\n user: IUserInfo;\n };\n if (this.storage.permanentUserData) {\n const pud = this.storage.permanentUserData.clients.get(\n this.storage.doc.clientID\n );\n // Only update if there is no entry or if the entry is different\n if (!pud || pud !== userId) {\n this.storage.permanentUserData.setUserMapping(\n this.storage.doc,\n this.storage.doc.clientID,\n userId ?? \"Unknown\" // TODO: change this to the user's ID so we can map it to the user's name\n );\n }\n }\n if (\n info.name !== storedUser?.name ||\n info.color !== storedUser?.color\n ) {\n this.editor.commands.updateUser({\n name: info.name,\n color: info.color,\n });\n }\n };\n // if we already have user info, we update the user\n if (self?.info) {\n updateUser(self);\n }\n // we also listen in case the user info changes\n this.storage.unsubs.push(room.events.self.subscribe(updateUser));\n if (options.comments) {\n const commentMarkType = getMarkType(\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n this.editor.schema\n );\n this.storage.unsubs.push(\n // Subscribe to threads so we can update comment marks if they become resolved/deleted\n store.outputs.threads.subscribe(() => {\n const threadMap = new Map(\n store.outputs.threads\n .get()\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .map((thread) => [thread.id, true])\n );\n function isComment(mark: PMMark): mark is PMMark & {\n attrs: { orphan: boolean; threadId: string };\n } {\n return mark.type.name === LIVEBLOCKS_COMMENT_MARK_TYPE;\n }\n // when threads change, find marks and update them if needed\n this.editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (isComment(mark)) {\n const markThreadId = mark.attrs.threadId;\n const isOrphan = !threadMap.has(markThreadId);\n if (isOrphan !== mark.attrs.orphan) {\n const { tr } = this.editor.state;\n const trimmedFrom = Math.max(pos, 0);\n const trimmedTo = Math.min(\n pos + node.nodeSize,\n this.editor.state.doc.content.size - 1\n );\n tr.removeMark(trimmedFrom, trimmedTo, mark);\n tr.addMark(\n trimmedFrom,\n trimmedTo,\n commentMarkType.create({\n ...mark.attrs,\n orphan: isOrphan,\n })\n );\n this.editor.view.dispatch(tr);\n }\n }\n });\n });\n })\n );\n }\n },\n onDestroy() {\n this.storage.unsubs.forEach((unsub) => unsub());\n },\n addGlobalAttributes() {\n return [\n {\n types: [\"paragraph\", \"heading\"],\n attributes: {\n ychange: { default: null },\n },\n },\n ];\n },\n addStorage() {\n const provider = getYjsProviderForRoom(room, {\n enablePermanentUserData:\n !!options.ai || options.enablePermanentUserData,\n offlineSupport_experimental: options.offlineSupport_experimental,\n });\n return {\n doc: provider.getYDoc(),\n provider,\n permanentUserData: provider.permanentUserData,\n unsubs: [],\n };\n },\n addExtensions() {\n const extensions: AnyExtension[] = [\n YChangeMark,\n\n LiveblocksCollab.configure({\n ySyncOptions: {\n permanentUserData: this.storage.permanentUserData,\n },\n document: this.storage.doc,\n field: options.field,\n }),\n CollaborationCaret.configure({\n provider: this.storage.provider,\n }) as Extension<CollaborationCaretOptions>,\n ];\n\n if (options.comments) {\n extensions.push(CommentsExtension);\n }\n if (options.mentions) {\n extensions.push(\n MentionExtension.configure({\n onCreateMention: (mention) => {\n createTextMention(mention.notificationId, mention);\n },\n onDeleteMention: deleteTextMention,\n })\n );\n }\n if (options.ai) {\n const resolveContextualPrompt = async ({\n prompt,\n context,\n previous,\n signal,\n }: ResolveContextualPromptArgs): Promise<ResolveContextualPromptResponse> => {\n const result = await room[kInternal].executeContextualPrompt({\n prompt,\n context,\n previous,\n signal,\n });\n\n // This response is validated afterwards by AiExtension itself\n return JSON.parse(result) as ResolveContextualPromptResponse;\n };\n\n extensions.push(\n AiExtension.configure({\n resolveContextualPrompt,\n ...(typeof options.ai === \"boolean\" ? {} : options.ai),\n doc: this.storage.doc,\n pud: this.storage.permanentUserData,\n })\n );\n }\n\n return extensions;\n },\n });\n};\n"],"names":["Collaboration","useYjsProvider","useCallback","useSyncExternalStore","Mark","useInitial","TextEditorType","useRef","useRoom","useClient","getUmbrellaStoreForClient","useEffect","useReportTextEditor","areSetsEqual","FILTERED_THREADS_PLUGIN_KEY","useCreateTextMention","useDeleteTextMention","Extension","getMarkType","LIVEBLOCKS_COMMENT_MARK_TYPE","getYjsProviderForRoom","CollaborationCaret","CommentsExtension","MentionExtension","kInternal","AiExtension"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LiveblocksExtension.cjs","sources":["../src/LiveblocksExtension.ts"],"sourcesContent":["import type {\n BaseUserMeta,\n IUserInfo,\n JsonObject,\n User,\n} from \"@liveblocks/core\";\nimport { kInternal, TextEditorType } from \"@liveblocks/core\";\nimport { useClient, useRoom } from \"@liveblocks/react\";\nimport {\n getUmbrellaStoreForClient,\n useCreateTextMention,\n useDeleteTextMention,\n useReportTextEditor,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { useInitial } from \"@liveblocks/react-ui/_private\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { AnyExtension, Editor } from \"@tiptap/core\";\nimport { Extension, getMarkType, Mark } from \"@tiptap/core\";\nimport type { Mark as PMMark } from \"@tiptap/pm/model\";\nimport { useCallback, useEffect, useRef, useSyncExternalStore } from \"react\";\n\nimport { AiExtension } from \"./ai/AiExtension\";\nimport { Collaboration } from \"./collaboration/collaboration\";\nimport {\n CollaborationCaret,\n type CollaborationCaretOptions,\n} from \"./collaboration-caret/collaboration-caret\";\nimport { LiveblocksCollaborationCaret } from \"./collaboration-liveblocks/cursors\";\nimport { LiveblocksCollaboration } from \"./collaboration-liveblocks/plugin\";\nimport {\n CommentsExtension,\n FILTERED_THREADS_PLUGIN_KEY,\n} from \"./comments/CommentsExtension\";\nimport { MentionExtension } from \"./mentions/MentionExtension\";\nimport type {\n LiveblocksExtensionOptions,\n LiveblocksExtensionStorage,\n ResolveContextualPromptArgs,\n ResolveContextualPromptResponse,\n} from \"./types\";\nimport { LIVEBLOCKS_COMMENT_MARK_TYPE } from \"./types\";\nimport { areSetsEqual } from \"./utils\";\n\ntype WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\nconst DEFAULT_OPTIONS: WithRequired<LiveblocksExtensionOptions, \"field\"> = {\n collaborationMode: \"yjs\",\n field: \"default\",\n comments: true,\n mentions: true,\n offlineSupport_experimental: false,\n enablePermanentUserData: false,\n};\n\nconst LiveblocksCollab = Collaboration.extend({\n // Override the onCreate method to warn users about potential misconfigurations\n onCreate() {\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"doc\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap document extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n !this.editor.extensionManager.extensions.find(\n (e) => e.name === \"paragraph\"\n )\n ) {\n console.warn(\n \"[Liveblocks] The tiptap paragraph extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"text\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap text extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n this.editor.extensionManager.extensions.find((e) => e.name === \"undoRedo\")\n ) {\n console.warn(\n \"[Liveblocks] The undoRedo extension is enabled, Liveblocks extension provides its own. Please remove or disable the undoRedo extension to prevent conflicts.\"\n );\n }\n },\n});\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n *\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nconst YChangeMark = Mark.create({\n name: \"ychange\",\n inclusive: false,\n parseHTML() {\n return [{ tag: \"ychange\" }];\n },\n addAttributes() {\n return {\n user: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_user\") ?? null,\n renderHTML: (attributes: { user: string | null }) => {\n if (!attributes.user) {\n return {};\n }\n return { \"data-ychange-user\": attributes.user };\n },\n },\n type: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_type\") ?? null,\n renderHTML: (attributes: { type: string | null }) => {\n if (!attributes.type) {\n return {};\n }\n return {\n \"data-ychange-type\": attributes.type,\n \"data-liveblocks\": \"\",\n class: `lb-root lb-tiptap-change lb-tiptap-change-${attributes.type}`,\n };\n },\n },\n color: {\n default: null,\n parseHTML: (element) => {\n return element.getAttribute(\"ychange_color\") ?? null;\n },\n renderHTML: () => {\n // attributes: { color: { light: string; dark: string } | null }\n return {}; // we don't need this color attribute for now\n },\n },\n };\n },\n renderHTML({ HTMLAttributes }) {\n return [\"ychange\", HTMLAttributes, 0];\n },\n});\n\nexport const useLiveblocksExtension = (\n opts?: LiveblocksExtensionOptions\n): Extension => {\n const options = {\n ...DEFAULT_OPTIONS,\n ...opts,\n };\n const textEditorType = useInitial<TextEditorType>(\n options.textEditorType ?? TextEditorType.TipTap\n );\n const editor = useRef<Editor | null>(null);\n const room = useRoom();\n\n // TODO: we don't need these things if comments isn't turned on...\n // TODO: we don't have a reference to the editor here, need to figure this out\n // useErrorListener((error) => {\n // // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n // if (\n // error.context.type === \"CREATE_THREAD_ERROR\" &&\n // error.context.roomId === room.id\n // ) {\n // handleThreadDelete(error.context.threadId);\n // }\n // });\n\n const isEditorReady = useIsEditorReady();\n const client = useClient();\n const store = getUmbrellaStoreForClient(client);\n const roomId = room.id;\n const yjsProvider = useYjsProvider();\n const isLiveblocksStorageMode = options.collaborationMode === \"liveblocks\";\n const isReadyForSideEffects = isLiveblocksStorageMode || isEditorReady;\n\n // If the user provided initialContent, wait for ready and then set it\n useEffect(() => {\n if (\n isLiveblocksStorageMode ||\n !isEditorReady ||\n !yjsProvider ||\n !options.initialContent ||\n !editor.current\n )\n return;\n\n // As noted in the tiptap documentation, you may not set initial content with collaboration.\n // The docs provide the following workaround:\n const ydoc = (yjsProvider as LiveblocksYjsProvider).getYDoc();\n const hasContentSet = ydoc.getMap(\"liveblocks_config\").get(\"hasContentSet\");\n if (!hasContentSet) {\n ydoc.getMap(\"liveblocks_config\").set(\"hasContentSet\", true);\n editor.current.commands.setContent(options.initialContent);\n }\n }, [\n isEditorReady,\n isLiveblocksStorageMode,\n yjsProvider,\n options.initialContent,\n ]);\n\n useReportTextEditor(textEditorType, options.field ?? DEFAULT_OPTIONS.field);\n\n const prevThreadsRef = useRef<Set<string> | undefined>(undefined);\n\n useEffect(() => {\n if (!isReadyForSideEffects) return;\n\n if (!editor.current) return;\n\n const newThreads = options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined;\n\n const hasFilteredThreadsChanged = !areSetsEqual(\n prevThreadsRef.current,\n newThreads\n );\n\n if (hasFilteredThreadsChanged) {\n prevThreadsRef.current = newThreads;\n }\n\n if (hasFilteredThreadsChanged) {\n editor.current.view.dispatch(\n editor.current.state.tr.setMeta(FILTERED_THREADS_PLUGIN_KEY, {\n filteredThreads: options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined,\n })\n );\n }\n }, [isReadyForSideEffects, options.threads_experimental]);\n\n const createTextMention = useCreateTextMention();\n const deleteTextMention = useDeleteTextMention();\n\n // Tiptap has options default as any, in tiptap2, we could use never, but now we must use any\n return Extension.create<any, LiveblocksExtensionStorage>({\n name: \"liveblocksExtension\",\n\n onCreate() {\n editor.current = this.editor;\n if (this.editor.options.content) {\n console.warn(\n \"[Liveblocks] Initial content must be set in the useLiveblocksExtension hook option. Remove content from your editor options.\"\n );\n }\n if (\n options.mentions &&\n this.editor.extensionManager.extensions.find(\n (e) => e.name.toLowerCase() === \"mention\"\n )\n ) {\n console.warn(\n \"[Liveblocks] Liveblocks own mention plugin is enabled, using another mention plugin may cause a conflict.\"\n );\n }\n const self = room.getSelf();\n const updateUser = ({\n info,\n id: userId,\n }: User<JsonObject, BaseUserMeta>) => {\n if (!info) {\n return;\n }\n if (this.storage.mode === \"liveblocks\") {\n this.editor.commands.updateUser({\n name: info.name,\n color: info.color,\n });\n return;\n }\n\n // y-prosemirror stores arbitrary user metadata in awareness, but its\n // API does not expose a typed local-state shape.\n const { user: storedUser } =\n this.storage.provider.awareness.getLocalState() as {\n user: IUserInfo;\n };\n if (this.storage.permanentUserData) {\n const pud = this.storage.permanentUserData.clients.get(\n this.storage.doc.clientID\n );\n // Only update if there is no entry or if the entry is different\n if (!pud || pud !== userId) {\n this.storage.permanentUserData.setUserMapping(\n this.storage.doc,\n this.storage.doc.clientID,\n userId ?? \"Unknown\" // TODO: change this to the user's ID so we can map it to the user's name\n );\n }\n }\n if (\n info.name !== storedUser?.name ||\n info.color !== storedUser?.color\n ) {\n this.editor.commands.updateUser({\n name: info.name,\n color: info.color,\n });\n }\n };\n // if we already have user info, we update the user\n if (self?.info) {\n updateUser(self);\n }\n // we also listen in case the user info changes\n this.storage.unsubs.push(room.events.self.subscribe(updateUser));\n if (options.comments) {\n const commentMarkType = getMarkType(\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n this.editor.schema\n );\n this.storage.unsubs.push(\n // Subscribe to threads so we can update comment marks if they become resolved/deleted\n store.outputs.threads.subscribe(() => {\n const threadMap = new Map(\n store.outputs.threads\n .get()\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .map((thread) => [thread.id, true])\n );\n function isComment(mark: PMMark): mark is PMMark & {\n attrs: { orphan: boolean; threadId: string };\n } {\n return mark.type.name === LIVEBLOCKS_COMMENT_MARK_TYPE;\n }\n // when threads change, find marks and update them if needed\n this.editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (isComment(mark)) {\n const markThreadId = mark.attrs.threadId;\n const isOrphan = !threadMap.has(markThreadId);\n if (isOrphan !== mark.attrs.orphan) {\n const { tr } = this.editor.state;\n const trimmedFrom = Math.max(pos, 0);\n const trimmedTo = Math.min(\n pos + node.nodeSize,\n this.editor.state.doc.content.size - 1\n );\n tr.removeMark(trimmedFrom, trimmedTo, mark);\n tr.addMark(\n trimmedFrom,\n trimmedTo,\n commentMarkType.create({\n ...mark.attrs,\n orphan: isOrphan,\n })\n );\n this.editor.view.dispatch(tr);\n }\n }\n });\n });\n })\n );\n }\n },\n onDestroy() {\n this.storage.unsubs.forEach((unsub) => unsub());\n },\n addGlobalAttributes() {\n return [\n {\n types: [\"paragraph\", \"heading\"],\n attributes: {\n ychange: { default: null },\n },\n },\n ];\n },\n addStorage() {\n if (isLiveblocksStorageMode) {\n return {\n mode: \"liveblocks\",\n unsubs: [],\n };\n }\n\n const provider = getYjsProviderForRoom(room, {\n enablePermanentUserData:\n !!options.ai || options.enablePermanentUserData,\n offlineSupport_experimental: options.offlineSupport_experimental,\n });\n return {\n mode: \"yjs\",\n doc: provider.getYDoc(),\n provider,\n permanentUserData: provider.permanentUserData,\n unsubs: [],\n };\n },\n addExtensions() {\n const selfInfo = room.getSelf()?.info;\n const selfUser =\n selfInfo !== undefined\n ? {\n name:\n typeof selfInfo.name === \"string\" ? selfInfo.name : undefined,\n color:\n typeof selfInfo.color === \"string\" ? selfInfo.color : undefined,\n }\n : undefined;\n\n const extensions: AnyExtension[] =\n this.storage.mode === \"liveblocks\"\n ? [\n LiveblocksCollaboration.configure({\n room,\n field: options.field,\n initialContent: options.initialContent,\n }),\n LiveblocksCollaborationCaret.configure({\n room,\n field: options.field,\n user: selfUser ?? {},\n }),\n ]\n : [\n YChangeMark,\n\n LiveblocksCollab.configure({\n ySyncOptions: {\n permanentUserData: this.storage.permanentUserData,\n },\n document: this.storage.doc,\n field: options.field,\n }),\n CollaborationCaret.configure({\n provider: this.storage.provider,\n }) as Extension<CollaborationCaretOptions>,\n ];\n\n if (options.comments) {\n extensions.push(CommentsExtension);\n }\n if (options.mentions) {\n extensions.push(\n MentionExtension.configure({\n onCreateMention: (mention) => {\n createTextMention(mention.notificationId, mention);\n },\n onDeleteMention: deleteTextMention,\n })\n );\n }\n if (options.ai) {\n if (this.storage.mode === \"liveblocks\") {\n console.warn(\n \"[Liveblocks] AI in @liveblocks/react-tiptap currently requires the Yjs collaboration mode.\"\n );\n return extensions;\n }\n\n const resolveContextualPrompt = async ({\n prompt,\n context,\n previous,\n signal,\n }: ResolveContextualPromptArgs): Promise<ResolveContextualPromptResponse> => {\n const result = await room[kInternal].executeContextualPrompt({\n prompt,\n context,\n previous,\n signal,\n });\n\n // This response is validated afterwards by AiExtension itself\n return JSON.parse(result) as ResolveContextualPromptResponse;\n };\n\n extensions.push(\n AiExtension.configure({\n resolveContextualPrompt,\n ...(typeof options.ai === \"boolean\" ? {} : options.ai),\n doc: this.storage.doc,\n pud: this.storage.permanentUserData,\n })\n );\n }\n\n return extensions;\n },\n });\n};\n"],"names":["Collaboration","useYjsProvider","useCallback","useSyncExternalStore","Mark","useInitial","TextEditorType","useRef","useRoom","useClient","getUmbrellaStoreForClient","useEffect","useReportTextEditor","areSetsEqual","FILTERED_THREADS_PLUGIN_KEY","useCreateTextMention","useDeleteTextMention","Extension","getMarkType","LIVEBLOCKS_COMMENT_MARK_TYPE","getYjsProviderForRoom","LiveblocksCollaboration","LiveblocksCollaborationCaret","CollaborationCaret","CommentsExtension","MentionExtension","kInternal","AiExtension"],"mappings":"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"}
|
|
@@ -8,12 +8,15 @@ import { useCallback, useSyncExternalStore, useRef, useEffect } from 'react';
|
|
|
8
8
|
import { AiExtension } from './ai/AiExtension.js';
|
|
9
9
|
import { Collaboration } from './collaboration/collaboration.js';
|
|
10
10
|
import { CollaborationCaret } from './collaboration-caret/collaboration-caret.js';
|
|
11
|
+
import { LiveblocksCollaborationCaret } from './collaboration-liveblocks/cursors.js';
|
|
12
|
+
import { LiveblocksCollaboration } from './collaboration-liveblocks/plugin.js';
|
|
11
13
|
import { FILTERED_THREADS_PLUGIN_KEY, CommentsExtension } from './comments/CommentsExtension.js';
|
|
12
14
|
import { MentionExtension } from './mentions/MentionExtension.js';
|
|
13
15
|
import { LIVEBLOCKS_COMMENT_MARK_TYPE } from './types.js';
|
|
14
16
|
import { areSetsEqual } from './utils.js';
|
|
15
17
|
|
|
16
18
|
const DEFAULT_OPTIONS = {
|
|
19
|
+
collaborationMode: "yjs",
|
|
17
20
|
field: "default",
|
|
18
21
|
comments: true,
|
|
19
22
|
mentions: true,
|
|
@@ -128,8 +131,10 @@ const useLiveblocksExtension = (opts) => {
|
|
|
128
131
|
const store = getUmbrellaStoreForClient(client);
|
|
129
132
|
const roomId = room.id;
|
|
130
133
|
const yjsProvider = useYjsProvider();
|
|
134
|
+
const isLiveblocksStorageMode = options.collaborationMode === "liveblocks";
|
|
135
|
+
const isReadyForSideEffects = isLiveblocksStorageMode || isEditorReady;
|
|
131
136
|
useEffect(() => {
|
|
132
|
-
if (!isEditorReady || !yjsProvider || !options.initialContent || !editor.current)
|
|
137
|
+
if (isLiveblocksStorageMode || !isEditorReady || !yjsProvider || !options.initialContent || !editor.current)
|
|
133
138
|
return;
|
|
134
139
|
const ydoc = yjsProvider.getYDoc();
|
|
135
140
|
const hasContentSet = ydoc.getMap("liveblocks_config").get("hasContentSet");
|
|
@@ -137,11 +142,16 @@ const useLiveblocksExtension = (opts) => {
|
|
|
137
142
|
ydoc.getMap("liveblocks_config").set("hasContentSet", true);
|
|
138
143
|
editor.current.commands.setContent(options.initialContent);
|
|
139
144
|
}
|
|
140
|
-
}, [
|
|
145
|
+
}, [
|
|
146
|
+
isEditorReady,
|
|
147
|
+
isLiveblocksStorageMode,
|
|
148
|
+
yjsProvider,
|
|
149
|
+
options.initialContent
|
|
150
|
+
]);
|
|
141
151
|
useReportTextEditor(textEditorType, options.field ?? DEFAULT_OPTIONS.field);
|
|
142
152
|
const prevThreadsRef = useRef(void 0);
|
|
143
153
|
useEffect(() => {
|
|
144
|
-
if (!
|
|
154
|
+
if (!isReadyForSideEffects) return;
|
|
145
155
|
if (!editor.current) return;
|
|
146
156
|
const newThreads = options.threads_experimental ? new Set(options.threads_experimental.map((t) => t.id)) : void 0;
|
|
147
157
|
const hasFilteredThreadsChanged = !areSetsEqual(
|
|
@@ -158,7 +168,7 @@ const useLiveblocksExtension = (opts) => {
|
|
|
158
168
|
})
|
|
159
169
|
);
|
|
160
170
|
}
|
|
161
|
-
}, [
|
|
171
|
+
}, [isReadyForSideEffects, options.threads_experimental]);
|
|
162
172
|
const createTextMention = useCreateTextMention();
|
|
163
173
|
const deleteTextMention = useDeleteTextMention();
|
|
164
174
|
return Extension.create({
|
|
@@ -185,6 +195,13 @@ const useLiveblocksExtension = (opts) => {
|
|
|
185
195
|
if (!info) {
|
|
186
196
|
return;
|
|
187
197
|
}
|
|
198
|
+
if (this.storage.mode === "liveblocks") {
|
|
199
|
+
this.editor.commands.updateUser({
|
|
200
|
+
name: info.name,
|
|
201
|
+
color: info.color
|
|
202
|
+
});
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
188
205
|
const { user: storedUser } = this.storage.provider.awareness.getLocalState();
|
|
189
206
|
if (this.storage.permanentUserData) {
|
|
190
207
|
const pud = this.storage.permanentUserData.clients.get(
|
|
@@ -268,11 +285,18 @@ const useLiveblocksExtension = (opts) => {
|
|
|
268
285
|
];
|
|
269
286
|
},
|
|
270
287
|
addStorage() {
|
|
288
|
+
if (isLiveblocksStorageMode) {
|
|
289
|
+
return {
|
|
290
|
+
mode: "liveblocks",
|
|
291
|
+
unsubs: []
|
|
292
|
+
};
|
|
293
|
+
}
|
|
271
294
|
const provider = getYjsProviderForRoom(room, {
|
|
272
295
|
enablePermanentUserData: !!options.ai || options.enablePermanentUserData,
|
|
273
296
|
offlineSupport_experimental: options.offlineSupport_experimental
|
|
274
297
|
});
|
|
275
298
|
return {
|
|
299
|
+
mode: "yjs",
|
|
276
300
|
doc: provider.getYDoc(),
|
|
277
301
|
provider,
|
|
278
302
|
permanentUserData: provider.permanentUserData,
|
|
@@ -280,7 +304,23 @@ const useLiveblocksExtension = (opts) => {
|
|
|
280
304
|
};
|
|
281
305
|
},
|
|
282
306
|
addExtensions() {
|
|
283
|
-
const
|
|
307
|
+
const selfInfo = room.getSelf()?.info;
|
|
308
|
+
const selfUser = selfInfo !== void 0 ? {
|
|
309
|
+
name: typeof selfInfo.name === "string" ? selfInfo.name : void 0,
|
|
310
|
+
color: typeof selfInfo.color === "string" ? selfInfo.color : void 0
|
|
311
|
+
} : void 0;
|
|
312
|
+
const extensions = this.storage.mode === "liveblocks" ? [
|
|
313
|
+
LiveblocksCollaboration.configure({
|
|
314
|
+
room,
|
|
315
|
+
field: options.field,
|
|
316
|
+
initialContent: options.initialContent
|
|
317
|
+
}),
|
|
318
|
+
LiveblocksCollaborationCaret.configure({
|
|
319
|
+
room,
|
|
320
|
+
field: options.field,
|
|
321
|
+
user: selfUser ?? {}
|
|
322
|
+
})
|
|
323
|
+
] : [
|
|
284
324
|
YChangeMark,
|
|
285
325
|
LiveblocksCollab.configure({
|
|
286
326
|
ySyncOptions: {
|
|
@@ -307,6 +347,12 @@ const useLiveblocksExtension = (opts) => {
|
|
|
307
347
|
);
|
|
308
348
|
}
|
|
309
349
|
if (options.ai) {
|
|
350
|
+
if (this.storage.mode === "liveblocks") {
|
|
351
|
+
console.warn(
|
|
352
|
+
"[Liveblocks] AI in @liveblocks/react-tiptap currently requires the Yjs collaboration mode."
|
|
353
|
+
);
|
|
354
|
+
return extensions;
|
|
355
|
+
}
|
|
310
356
|
const resolveContextualPrompt = async ({
|
|
311
357
|
prompt,
|
|
312
358
|
context,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveblocksExtension.js","sources":["../src/LiveblocksExtension.ts"],"sourcesContent":["import type {\n BaseUserMeta,\n IUserInfo,\n JsonObject,\n User,\n} from \"@liveblocks/core\";\nimport { kInternal, TextEditorType } from \"@liveblocks/core\";\nimport { useClient, useRoom } from \"@liveblocks/react\";\nimport {\n getUmbrellaStoreForClient,\n useCreateTextMention,\n useDeleteTextMention,\n useReportTextEditor,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { useInitial } from \"@liveblocks/react-ui/_private\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { AnyExtension, Editor } from \"@tiptap/core\";\nimport { Extension, getMarkType, Mark } from \"@tiptap/core\";\nimport type { Mark as PMMark } from \"@tiptap/pm/model\";\nimport { useCallback, useEffect, useRef, useSyncExternalStore } from \"react\";\n\nimport { AiExtension } from \"./ai/AiExtension\";\nimport { Collaboration } from \"./collaboration/collaboration\";\nimport {\n CollaborationCaret,\n type CollaborationCaretOptions,\n} from \"./collaboration-caret/collaboration-caret\";\nimport {\n CommentsExtension,\n FILTERED_THREADS_PLUGIN_KEY,\n} from \"./comments/CommentsExtension\";\nimport { MentionExtension } from \"./mentions/MentionExtension\";\nimport type {\n LiveblocksExtensionOptions,\n LiveblocksExtensionStorage,\n ResolveContextualPromptArgs,\n ResolveContextualPromptResponse,\n} from \"./types\";\nimport { LIVEBLOCKS_COMMENT_MARK_TYPE } from \"./types\";\nimport { areSetsEqual } from \"./utils\";\n\ntype WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\nconst DEFAULT_OPTIONS: WithRequired<LiveblocksExtensionOptions, \"field\"> = {\n field: \"default\",\n comments: true,\n mentions: true,\n offlineSupport_experimental: false,\n enablePermanentUserData: false,\n};\n\nconst LiveblocksCollab = Collaboration.extend({\n // Override the onCreate method to warn users about potential misconfigurations\n onCreate() {\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"doc\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap document extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n !this.editor.extensionManager.extensions.find(\n (e) => e.name === \"paragraph\"\n )\n ) {\n console.warn(\n \"[Liveblocks] The tiptap paragraph extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"text\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap text extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n this.editor.extensionManager.extensions.find((e) => e.name === \"undoRedo\")\n ) {\n console.warn(\n \"[Liveblocks] The undoRedo extension is enabled, Liveblocks extension provides its own. Please remove or disable the undoRedo extension to prevent conflicts.\"\n );\n }\n },\n});\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n *\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nconst YChangeMark = Mark.create({\n name: \"ychange\",\n inclusive: false,\n parseHTML() {\n return [{ tag: \"ychange\" }];\n },\n addAttributes() {\n return {\n user: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_user\") ?? null,\n renderHTML: (attributes: { user: string | null }) => {\n if (!attributes.user) {\n return {};\n }\n return { \"data-ychange-user\": attributes.user };\n },\n },\n type: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_type\") ?? null,\n renderHTML: (attributes: { type: string | null }) => {\n if (!attributes.type) {\n return {};\n }\n return {\n \"data-ychange-type\": attributes.type,\n \"data-liveblocks\": \"\",\n class: `lb-root lb-tiptap-change lb-tiptap-change-${attributes.type}`,\n };\n },\n },\n color: {\n default: null,\n parseHTML: (element) => {\n return element.getAttribute(\"ychange_color\") ?? null;\n },\n renderHTML: () => {\n // attributes: { color: { light: string; dark: string } | null }\n return {}; // we don't need this color attribute for now\n },\n },\n };\n },\n renderHTML({ HTMLAttributes }) {\n return [\"ychange\", HTMLAttributes, 0];\n },\n});\n\nexport const useLiveblocksExtension = (\n opts?: LiveblocksExtensionOptions\n): Extension => {\n const options = {\n ...DEFAULT_OPTIONS,\n ...opts,\n };\n const textEditorType = useInitial<TextEditorType>(\n options.textEditorType ?? TextEditorType.TipTap\n );\n const editor = useRef<Editor | null>(null);\n const room = useRoom();\n\n // TODO: we don't need these things if comments isn't turned on...\n // TODO: we don't have a reference to the editor here, need to figure this out\n // useErrorListener((error) => {\n // // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n // if (\n // error.context.type === \"CREATE_THREAD_ERROR\" &&\n // error.context.roomId === room.id\n // ) {\n // handleThreadDelete(error.context.threadId);\n // }\n // });\n\n const isEditorReady = useIsEditorReady();\n const client = useClient();\n const store = getUmbrellaStoreForClient(client);\n const roomId = room.id;\n const yjsProvider = useYjsProvider();\n\n // If the user provided initialContent, wait for ready and then set it\n useEffect(() => {\n if (\n !isEditorReady ||\n !yjsProvider ||\n !options.initialContent ||\n !editor.current\n )\n return;\n\n // As noted in the tiptap documentation, you may not set initial content with collaboration.\n // The docs provide the following workaround:\n const ydoc = (yjsProvider as LiveblocksYjsProvider).getYDoc();\n const hasContentSet = ydoc.getMap(\"liveblocks_config\").get(\"hasContentSet\");\n if (!hasContentSet) {\n ydoc.getMap(\"liveblocks_config\").set(\"hasContentSet\", true);\n editor.current.commands.setContent(options.initialContent);\n }\n }, [isEditorReady, yjsProvider, options.initialContent]);\n\n useReportTextEditor(textEditorType, options.field ?? DEFAULT_OPTIONS.field);\n\n const prevThreadsRef = useRef<Set<string> | undefined>(undefined);\n\n useEffect(() => {\n if (!isEditorReady) return;\n\n if (!editor.current) return;\n\n const newThreads = options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined;\n\n const hasFilteredThreadsChanged = !areSetsEqual(\n prevThreadsRef.current,\n newThreads\n );\n\n if (hasFilteredThreadsChanged) {\n prevThreadsRef.current = newThreads;\n }\n\n if (hasFilteredThreadsChanged) {\n editor.current.view.dispatch(\n editor.current.state.tr.setMeta(FILTERED_THREADS_PLUGIN_KEY, {\n filteredThreads: options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined,\n })\n );\n }\n }, [isEditorReady, options.threads_experimental]);\n\n const createTextMention = useCreateTextMention();\n const deleteTextMention = useDeleteTextMention();\n\n // Tiptap has options default as any, in tiptap2, we could use never, but now we must use any\n return Extension.create<any, LiveblocksExtensionStorage>({\n name: \"liveblocksExtension\",\n\n onCreate() {\n editor.current = this.editor;\n if (this.editor.options.content) {\n console.warn(\n \"[Liveblocks] Initial content must be set in the useLiveblocksExtension hook option. Remove content from your editor options.\"\n );\n }\n if (\n options.mentions &&\n this.editor.extensionManager.extensions.find(\n (e) => e.name.toLowerCase() === \"mention\"\n )\n ) {\n console.warn(\n \"[Liveblocks] Liveblocks own mention plugin is enabled, using another mention plugin may cause a conflict.\"\n );\n }\n const self = room.getSelf();\n const updateUser = ({\n info,\n id: userId,\n }: User<JsonObject, BaseUserMeta>) => {\n if (!info) {\n return;\n }\n const { user: storedUser } =\n this.storage.provider.awareness.getLocalState() as {\n user: IUserInfo;\n };\n if (this.storage.permanentUserData) {\n const pud = this.storage.permanentUserData.clients.get(\n this.storage.doc.clientID\n );\n // Only update if there is no entry or if the entry is different\n if (!pud || pud !== userId) {\n this.storage.permanentUserData.setUserMapping(\n this.storage.doc,\n this.storage.doc.clientID,\n userId ?? \"Unknown\" // TODO: change this to the user's ID so we can map it to the user's name\n );\n }\n }\n if (\n info.name !== storedUser?.name ||\n info.color !== storedUser?.color\n ) {\n this.editor.commands.updateUser({\n name: info.name,\n color: info.color,\n });\n }\n };\n // if we already have user info, we update the user\n if (self?.info) {\n updateUser(self);\n }\n // we also listen in case the user info changes\n this.storage.unsubs.push(room.events.self.subscribe(updateUser));\n if (options.comments) {\n const commentMarkType = getMarkType(\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n this.editor.schema\n );\n this.storage.unsubs.push(\n // Subscribe to threads so we can update comment marks if they become resolved/deleted\n store.outputs.threads.subscribe(() => {\n const threadMap = new Map(\n store.outputs.threads\n .get()\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .map((thread) => [thread.id, true])\n );\n function isComment(mark: PMMark): mark is PMMark & {\n attrs: { orphan: boolean; threadId: string };\n } {\n return mark.type.name === LIVEBLOCKS_COMMENT_MARK_TYPE;\n }\n // when threads change, find marks and update them if needed\n this.editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (isComment(mark)) {\n const markThreadId = mark.attrs.threadId;\n const isOrphan = !threadMap.has(markThreadId);\n if (isOrphan !== mark.attrs.orphan) {\n const { tr } = this.editor.state;\n const trimmedFrom = Math.max(pos, 0);\n const trimmedTo = Math.min(\n pos + node.nodeSize,\n this.editor.state.doc.content.size - 1\n );\n tr.removeMark(trimmedFrom, trimmedTo, mark);\n tr.addMark(\n trimmedFrom,\n trimmedTo,\n commentMarkType.create({\n ...mark.attrs,\n orphan: isOrphan,\n })\n );\n this.editor.view.dispatch(tr);\n }\n }\n });\n });\n })\n );\n }\n },\n onDestroy() {\n this.storage.unsubs.forEach((unsub) => unsub());\n },\n addGlobalAttributes() {\n return [\n {\n types: [\"paragraph\", \"heading\"],\n attributes: {\n ychange: { default: null },\n },\n },\n ];\n },\n addStorage() {\n const provider = getYjsProviderForRoom(room, {\n enablePermanentUserData:\n !!options.ai || options.enablePermanentUserData,\n offlineSupport_experimental: options.offlineSupport_experimental,\n });\n return {\n doc: provider.getYDoc(),\n provider,\n permanentUserData: provider.permanentUserData,\n unsubs: [],\n };\n },\n addExtensions() {\n const extensions: AnyExtension[] = [\n YChangeMark,\n\n LiveblocksCollab.configure({\n ySyncOptions: {\n permanentUserData: this.storage.permanentUserData,\n },\n document: this.storage.doc,\n field: options.field,\n }),\n CollaborationCaret.configure({\n provider: this.storage.provider,\n }) as Extension<CollaborationCaretOptions>,\n ];\n\n if (options.comments) {\n extensions.push(CommentsExtension);\n }\n if (options.mentions) {\n extensions.push(\n MentionExtension.configure({\n onCreateMention: (mention) => {\n createTextMention(mention.notificationId, mention);\n },\n onDeleteMention: deleteTextMention,\n })\n );\n }\n if (options.ai) {\n const resolveContextualPrompt = async ({\n prompt,\n context,\n previous,\n signal,\n }: ResolveContextualPromptArgs): Promise<ResolveContextualPromptResponse> => {\n const result = await room[kInternal].executeContextualPrompt({\n prompt,\n context,\n previous,\n signal,\n });\n\n // This response is validated afterwards by AiExtension itself\n return JSON.parse(result) as ResolveContextualPromptResponse;\n };\n\n extensions.push(\n AiExtension.configure({\n resolveContextualPrompt,\n ...(typeof options.ai === \"boolean\" ? {} : options.ai),\n doc: this.storage.doc,\n pud: this.storage.permanentUserData,\n })\n );\n }\n\n return extensions;\n },\n });\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LiveblocksExtension.js","sources":["../src/LiveblocksExtension.ts"],"sourcesContent":["import type {\n BaseUserMeta,\n IUserInfo,\n JsonObject,\n User,\n} from \"@liveblocks/core\";\nimport { kInternal, TextEditorType } from \"@liveblocks/core\";\nimport { useClient, useRoom } from \"@liveblocks/react\";\nimport {\n getUmbrellaStoreForClient,\n useCreateTextMention,\n useDeleteTextMention,\n useReportTextEditor,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { useInitial } from \"@liveblocks/react-ui/_private\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { AnyExtension, Editor } from \"@tiptap/core\";\nimport { Extension, getMarkType, Mark } from \"@tiptap/core\";\nimport type { Mark as PMMark } from \"@tiptap/pm/model\";\nimport { useCallback, useEffect, useRef, useSyncExternalStore } from \"react\";\n\nimport { AiExtension } from \"./ai/AiExtension\";\nimport { Collaboration } from \"./collaboration/collaboration\";\nimport {\n CollaborationCaret,\n type CollaborationCaretOptions,\n} from \"./collaboration-caret/collaboration-caret\";\nimport { LiveblocksCollaborationCaret } from \"./collaboration-liveblocks/cursors\";\nimport { LiveblocksCollaboration } from \"./collaboration-liveblocks/plugin\";\nimport {\n CommentsExtension,\n FILTERED_THREADS_PLUGIN_KEY,\n} from \"./comments/CommentsExtension\";\nimport { MentionExtension } from \"./mentions/MentionExtension\";\nimport type {\n LiveblocksExtensionOptions,\n LiveblocksExtensionStorage,\n ResolveContextualPromptArgs,\n ResolveContextualPromptResponse,\n} from \"./types\";\nimport { LIVEBLOCKS_COMMENT_MARK_TYPE } from \"./types\";\nimport { areSetsEqual } from \"./utils\";\n\ntype WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\nconst DEFAULT_OPTIONS: WithRequired<LiveblocksExtensionOptions, \"field\"> = {\n collaborationMode: \"yjs\",\n field: \"default\",\n comments: true,\n mentions: true,\n offlineSupport_experimental: false,\n enablePermanentUserData: false,\n};\n\nconst LiveblocksCollab = Collaboration.extend({\n // Override the onCreate method to warn users about potential misconfigurations\n onCreate() {\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"doc\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap document extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n !this.editor.extensionManager.extensions.find(\n (e) => e.name === \"paragraph\"\n )\n ) {\n console.warn(\n \"[Liveblocks] The tiptap paragraph extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n\n if (\n !this.editor.extensionManager.extensions.find((e) => e.name === \"text\")\n ) {\n console.warn(\n \"[Liveblocks] The tiptap text extension is required for Liveblocks collaboration. Please add it or use Tiptap StarterKit extension.\"\n );\n }\n if (\n this.editor.extensionManager.extensions.find((e) => e.name === \"undoRedo\")\n ) {\n console.warn(\n \"[Liveblocks] The undoRedo extension is enabled, Liveblocks extension provides its own. Please remove or disable the undoRedo extension to prevent conflicts.\"\n );\n }\n },\n});\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n *\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nconst YChangeMark = Mark.create({\n name: \"ychange\",\n inclusive: false,\n parseHTML() {\n return [{ tag: \"ychange\" }];\n },\n addAttributes() {\n return {\n user: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_user\") ?? null,\n renderHTML: (attributes: { user: string | null }) => {\n if (!attributes.user) {\n return {};\n }\n return { \"data-ychange-user\": attributes.user };\n },\n },\n type: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"ychange_type\") ?? null,\n renderHTML: (attributes: { type: string | null }) => {\n if (!attributes.type) {\n return {};\n }\n return {\n \"data-ychange-type\": attributes.type,\n \"data-liveblocks\": \"\",\n class: `lb-root lb-tiptap-change lb-tiptap-change-${attributes.type}`,\n };\n },\n },\n color: {\n default: null,\n parseHTML: (element) => {\n return element.getAttribute(\"ychange_color\") ?? null;\n },\n renderHTML: () => {\n // attributes: { color: { light: string; dark: string } | null }\n return {}; // we don't need this color attribute for now\n },\n },\n };\n },\n renderHTML({ HTMLAttributes }) {\n return [\"ychange\", HTMLAttributes, 0];\n },\n});\n\nexport const useLiveblocksExtension = (\n opts?: LiveblocksExtensionOptions\n): Extension => {\n const options = {\n ...DEFAULT_OPTIONS,\n ...opts,\n };\n const textEditorType = useInitial<TextEditorType>(\n options.textEditorType ?? TextEditorType.TipTap\n );\n const editor = useRef<Editor | null>(null);\n const room = useRoom();\n\n // TODO: we don't need these things if comments isn't turned on...\n // TODO: we don't have a reference to the editor here, need to figure this out\n // useErrorListener((error) => {\n // // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n // if (\n // error.context.type === \"CREATE_THREAD_ERROR\" &&\n // error.context.roomId === room.id\n // ) {\n // handleThreadDelete(error.context.threadId);\n // }\n // });\n\n const isEditorReady = useIsEditorReady();\n const client = useClient();\n const store = getUmbrellaStoreForClient(client);\n const roomId = room.id;\n const yjsProvider = useYjsProvider();\n const isLiveblocksStorageMode = options.collaborationMode === \"liveblocks\";\n const isReadyForSideEffects = isLiveblocksStorageMode || isEditorReady;\n\n // If the user provided initialContent, wait for ready and then set it\n useEffect(() => {\n if (\n isLiveblocksStorageMode ||\n !isEditorReady ||\n !yjsProvider ||\n !options.initialContent ||\n !editor.current\n )\n return;\n\n // As noted in the tiptap documentation, you may not set initial content with collaboration.\n // The docs provide the following workaround:\n const ydoc = (yjsProvider as LiveblocksYjsProvider).getYDoc();\n const hasContentSet = ydoc.getMap(\"liveblocks_config\").get(\"hasContentSet\");\n if (!hasContentSet) {\n ydoc.getMap(\"liveblocks_config\").set(\"hasContentSet\", true);\n editor.current.commands.setContent(options.initialContent);\n }\n }, [\n isEditorReady,\n isLiveblocksStorageMode,\n yjsProvider,\n options.initialContent,\n ]);\n\n useReportTextEditor(textEditorType, options.field ?? DEFAULT_OPTIONS.field);\n\n const prevThreadsRef = useRef<Set<string> | undefined>(undefined);\n\n useEffect(() => {\n if (!isReadyForSideEffects) return;\n\n if (!editor.current) return;\n\n const newThreads = options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined;\n\n const hasFilteredThreadsChanged = !areSetsEqual(\n prevThreadsRef.current,\n newThreads\n );\n\n if (hasFilteredThreadsChanged) {\n prevThreadsRef.current = newThreads;\n }\n\n if (hasFilteredThreadsChanged) {\n editor.current.view.dispatch(\n editor.current.state.tr.setMeta(FILTERED_THREADS_PLUGIN_KEY, {\n filteredThreads: options.threads_experimental\n ? new Set(options.threads_experimental.map((t) => t.id))\n : undefined,\n })\n );\n }\n }, [isReadyForSideEffects, options.threads_experimental]);\n\n const createTextMention = useCreateTextMention();\n const deleteTextMention = useDeleteTextMention();\n\n // Tiptap has options default as any, in tiptap2, we could use never, but now we must use any\n return Extension.create<any, LiveblocksExtensionStorage>({\n name: \"liveblocksExtension\",\n\n onCreate() {\n editor.current = this.editor;\n if (this.editor.options.content) {\n console.warn(\n \"[Liveblocks] Initial content must be set in the useLiveblocksExtension hook option. Remove content from your editor options.\"\n );\n }\n if (\n options.mentions &&\n this.editor.extensionManager.extensions.find(\n (e) => e.name.toLowerCase() === \"mention\"\n )\n ) {\n console.warn(\n \"[Liveblocks] Liveblocks own mention plugin is enabled, using another mention plugin may cause a conflict.\"\n );\n }\n const self = room.getSelf();\n const updateUser = ({\n info,\n id: userId,\n }: User<JsonObject, BaseUserMeta>) => {\n if (!info) {\n return;\n }\n if (this.storage.mode === \"liveblocks\") {\n this.editor.commands.updateUser({\n name: info.name,\n color: info.color,\n });\n return;\n }\n\n // y-prosemirror stores arbitrary user metadata in awareness, but its\n // API does not expose a typed local-state shape.\n const { user: storedUser } =\n this.storage.provider.awareness.getLocalState() as {\n user: IUserInfo;\n };\n if (this.storage.permanentUserData) {\n const pud = this.storage.permanentUserData.clients.get(\n this.storage.doc.clientID\n );\n // Only update if there is no entry or if the entry is different\n if (!pud || pud !== userId) {\n this.storage.permanentUserData.setUserMapping(\n this.storage.doc,\n this.storage.doc.clientID,\n userId ?? \"Unknown\" // TODO: change this to the user's ID so we can map it to the user's name\n );\n }\n }\n if (\n info.name !== storedUser?.name ||\n info.color !== storedUser?.color\n ) {\n this.editor.commands.updateUser({\n name: info.name,\n color: info.color,\n });\n }\n };\n // if we already have user info, we update the user\n if (self?.info) {\n updateUser(self);\n }\n // we also listen in case the user info changes\n this.storage.unsubs.push(room.events.self.subscribe(updateUser));\n if (options.comments) {\n const commentMarkType = getMarkType(\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n this.editor.schema\n );\n this.storage.unsubs.push(\n // Subscribe to threads so we can update comment marks if they become resolved/deleted\n store.outputs.threads.subscribe(() => {\n const threadMap = new Map(\n store.outputs.threads\n .get()\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .map((thread) => [thread.id, true])\n );\n function isComment(mark: PMMark): mark is PMMark & {\n attrs: { orphan: boolean; threadId: string };\n } {\n return mark.type.name === LIVEBLOCKS_COMMENT_MARK_TYPE;\n }\n // when threads change, find marks and update them if needed\n this.editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (isComment(mark)) {\n const markThreadId = mark.attrs.threadId;\n const isOrphan = !threadMap.has(markThreadId);\n if (isOrphan !== mark.attrs.orphan) {\n const { tr } = this.editor.state;\n const trimmedFrom = Math.max(pos, 0);\n const trimmedTo = Math.min(\n pos + node.nodeSize,\n this.editor.state.doc.content.size - 1\n );\n tr.removeMark(trimmedFrom, trimmedTo, mark);\n tr.addMark(\n trimmedFrom,\n trimmedTo,\n commentMarkType.create({\n ...mark.attrs,\n orphan: isOrphan,\n })\n );\n this.editor.view.dispatch(tr);\n }\n }\n });\n });\n })\n );\n }\n },\n onDestroy() {\n this.storage.unsubs.forEach((unsub) => unsub());\n },\n addGlobalAttributes() {\n return [\n {\n types: [\"paragraph\", \"heading\"],\n attributes: {\n ychange: { default: null },\n },\n },\n ];\n },\n addStorage() {\n if (isLiveblocksStorageMode) {\n return {\n mode: \"liveblocks\",\n unsubs: [],\n };\n }\n\n const provider = getYjsProviderForRoom(room, {\n enablePermanentUserData:\n !!options.ai || options.enablePermanentUserData,\n offlineSupport_experimental: options.offlineSupport_experimental,\n });\n return {\n mode: \"yjs\",\n doc: provider.getYDoc(),\n provider,\n permanentUserData: provider.permanentUserData,\n unsubs: [],\n };\n },\n addExtensions() {\n const selfInfo = room.getSelf()?.info;\n const selfUser =\n selfInfo !== undefined\n ? {\n name:\n typeof selfInfo.name === \"string\" ? selfInfo.name : undefined,\n color:\n typeof selfInfo.color === \"string\" ? selfInfo.color : undefined,\n }\n : undefined;\n\n const extensions: AnyExtension[] =\n this.storage.mode === \"liveblocks\"\n ? [\n LiveblocksCollaboration.configure({\n room,\n field: options.field,\n initialContent: options.initialContent,\n }),\n LiveblocksCollaborationCaret.configure({\n room,\n field: options.field,\n user: selfUser ?? {},\n }),\n ]\n : [\n YChangeMark,\n\n LiveblocksCollab.configure({\n ySyncOptions: {\n permanentUserData: this.storage.permanentUserData,\n },\n document: this.storage.doc,\n field: options.field,\n }),\n CollaborationCaret.configure({\n provider: this.storage.provider,\n }) as Extension<CollaborationCaretOptions>,\n ];\n\n if (options.comments) {\n extensions.push(CommentsExtension);\n }\n if (options.mentions) {\n extensions.push(\n MentionExtension.configure({\n onCreateMention: (mention) => {\n createTextMention(mention.notificationId, mention);\n },\n onDeleteMention: deleteTextMention,\n })\n );\n }\n if (options.ai) {\n if (this.storage.mode === \"liveblocks\") {\n console.warn(\n \"[Liveblocks] AI in @liveblocks/react-tiptap currently requires the Yjs collaboration mode.\"\n );\n return extensions;\n }\n\n const resolveContextualPrompt = async ({\n prompt,\n context,\n previous,\n signal,\n }: ResolveContextualPromptArgs): Promise<ResolveContextualPromptResponse> => {\n const result = await room[kInternal].executeContextualPrompt({\n prompt,\n context,\n previous,\n signal,\n });\n\n // This response is validated afterwards by AiExtension itself\n return JSON.parse(result) as ResolveContextualPromptResponse;\n };\n\n extensions.push(\n AiExtension.configure({\n resolveContextualPrompt,\n ...(typeof options.ai === \"boolean\" ? {} : options.ai),\n doc: this.storage.doc,\n pud: this.storage.permanentUserData,\n })\n );\n }\n\n return extensions;\n },\n });\n};\n"],"names":[],"mappings":"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"}
|
package/dist/ai/AiExtension.cjs
CHANGED
|
@@ -18,7 +18,8 @@ function getYjsBinding(editor) {
|
|
|
18
18
|
return yProsemirror.ySyncPluginKey.getState(editor.view.state).binding;
|
|
19
19
|
}
|
|
20
20
|
function getLiveblocksYjsProvider(editor) {
|
|
21
|
-
|
|
21
|
+
const storage = editor.extensionStorage.liveblocksExtension;
|
|
22
|
+
return storage?.mode === "yjs" ? storage.provider : void 0;
|
|
22
23
|
}
|
|
23
24
|
function isContextualPromptDiffResponse(response) {
|
|
24
25
|
return response.type === "replace" || response.type === "insert";
|