@liveblocks/react-tiptap 2.16.1-ai3 → 2.16.1-ai4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingComposer.js","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type { ComponentRef, FormEvent, KeyboardEvent } from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type {\n CommentsExtensionStorage,\n ExtendedChainedCommands,\n} from \"../types\";\nimport { compareSelections, getDomRange } from \"../utils\";\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n editor: Editor | null;\n};\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const createThread = useCreateThread();\n const { editor, onComposerSubmit, onKeyDown } = props;\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) return;\n\n return (\n ctx.editor.storage.liveblocksComments as\n | CommentsExtensionStorage\n | undefined\n )?.pendingComment && !ctx.editor.state.selection.empty\n ? ctx.editor.state.selection\n : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRange(editor, pendingCommentSelection);\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={(e) => {\n // Don't send up a click event from emoji popout and close the composer\n e.stopPropagation();\n }}\n autoFocus={true}\n />\n </div>,\n document.body\n );\n});\n"],"names":["forwardRef","FloatingComposer","useCreateThread","useEditorState","compareSelections","useFloating","inline","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","getDomRange","useCallback","createPortal","jsx","Composer"],"mappings":"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"}
1
+ {"version":3,"file":"FloatingComposer.js","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type { ComponentRef, FormEvent, KeyboardEvent } from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type {\n CommentsExtensionStorage,\n ExtendedChainedCommands,\n} from \"../types\";\nimport { compareSelections, getDomRangeFromSelection } from \"../utils\";\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n editor: Editor | null;\n};\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const createThread = useCreateThread();\n const { editor, onComposerSubmit, onKeyDown } = props;\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) return;\n\n return (\n ctx.editor.storage.liveblocksComments as\n | CommentsExtensionStorage\n | undefined\n )?.pendingComment && !ctx.editor.state.selection.empty\n ? ctx.editor.state.selection\n : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(\n editor,\n pendingCommentSelection\n );\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={(e) => {\n // Don't send up a click event from emoji popout and close the composer\n e.stopPropagation();\n }}\n autoFocus={true}\n />\n </div>,\n document.body\n );\n});\n"],"names":["forwardRef","FloatingComposer","useCreateThread","useEditorState","compareSelections","useFloating","inline","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","getDomRangeFromSelection","useCallback","createPortal","jsx","Composer"],"mappings":"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"}
@@ -6,7 +6,7 @@ import { Composer } from '@liveblocks/react-ui';
6
6
  import { useEditorState } from '@tiptap/react';
7
7
  import { forwardRef, useCallback } from 'react';
8
8
  import { createPortal } from 'react-dom';
9
- import { compareSelections, getDomRange } from '../utils.mjs';
9
+ import { compareSelections, getDomRangeFromSelection } from '../utils.mjs';
10
10
 
11
11
  const FLOATING_COMPOSER_COLLISION_PADDING = 10;
12
12
  const FloatingComposer = forwardRef(function FloatingComposer2(props, forwardedRef) {
@@ -54,7 +54,10 @@ const FloatingComposer = forwardRef(function FloatingComposer2(props, forwardedR
54
54
  if (!pendingCommentSelection) {
55
55
  setReference(null);
56
56
  } else {
57
- const domRange = getDomRange(editor, pendingCommentSelection);
57
+ const domRange = getDomRangeFromSelection(
58
+ editor,
59
+ pendingCommentSelection
60
+ );
58
61
  setReference(domRange);
59
62
  }
60
63
  }, [pendingCommentSelection, editor, isOpen, setReference]);
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingComposer.mjs","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type { ComponentRef, FormEvent, KeyboardEvent } from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type {\n CommentsExtensionStorage,\n ExtendedChainedCommands,\n} from \"../types\";\nimport { compareSelections, getDomRange } from \"../utils\";\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n editor: Editor | null;\n};\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const createThread = useCreateThread();\n const { editor, onComposerSubmit, onKeyDown } = props;\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) return;\n\n return (\n ctx.editor.storage.liveblocksComments as\n | CommentsExtensionStorage\n | undefined\n )?.pendingComment && !ctx.editor.state.selection.empty\n ? ctx.editor.state.selection\n : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRange(editor, pendingCommentSelection);\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={(e) => {\n // Don't send up a click event from emoji popout and close the composer\n e.stopPropagation();\n }}\n autoFocus={true}\n />\n </div>,\n document.body\n );\n});\n"],"names":["FloatingComposer"],"mappings":";;;;;;;;;;AAwCO,MAAM,mCAAsC,GAAA,GAAA;AAE5C,MAAM,gBAAmB,GAAA,UAAA,CAG9B,SAASA,iBAAAA,CAAiB,OAAO,YAAc,EAAA;AAC/C,EAAA,MAAM,eAAe,eAAgB,EAAA,CAAA;AACrC,EAAA,MAAM,EAAE,MAAA,EAAQ,gBAAkB,EAAA,SAAA,EAAc,GAAA,KAAA,CAAA;AAChD,EAAA,MAAM,0BACJ,cAAe,CAAA;AAAA,IACb,MAAA;AAAA,IACA,QAAA,EAAU,CAAC,GAAQ,KAAA;AACjB,MAAA,IAAI,CAAC,GAAI,CAAA,MAAA;AAAQ,QAAA,OAAA;AAEjB,MAAA,OACE,GAAI,CAAA,MAAA,CAAO,OAAQ,CAAA,kBAAA,EAGlB,kBAAkB,CAAC,GAAA,CAAI,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,KAAA,GAC7C,GAAI,CAAA,MAAA,CAAO,MAAM,SACjB,GAAA,KAAA,CAAA,CAAA;AAAA,KACN;AAAA,IACA,UAAY,EAAA,iBAAA;AAAA,GACb,CAAK,IAAA,KAAA,CAAA,CAAA;AACR,EAAA,MAAM,SAAS,uBAA4B,KAAA,KAAA,CAAA,CAAA;AAC3C,EAAM,MAAA;AAAA,IACJ,IAAA,EAAM,EAAE,YAAA,EAAc,WAAY,EAAA;AAAA,IAClC,QAAA;AAAA,IACA,CAAA;AAAA,IACA,CAAA;AAAA,MACE,WAAY,CAAA;AAAA,IACd,QAAU,EAAA,OAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,MACV,MAAO,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,MACvD,KAAK,EAAE,OAAA,EAAS,mCAAqC,EAAA,SAAA,EAAW,OAAO,CAAA;AAAA,MACvE,OAAO,EAAE,CAAA;AAAA,MACT,IAAK,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,MACrD,KAAM,CAAA;AAAA,QACJ,OAAS,EAAA,mCAAA;AAAA,QACT,SAAS,UAAW,EAAA;AAAA,OACrB,CAAA;AAAA,MACD,IAAK,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,KACvD;AAAA,IACA,oBAAA,EAAsB,IAAI,IAAS,KAAA;AACjC,MAAO,OAAA,UAAA,CAAW,GAAG,IAAM,EAAA;AAAA,QACzB,cAAgB,EAAA,IAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACH;AAAA,GACD,CAAA,CAAA;AAED,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAI,IAAA,CAAC,MAAU,IAAA,CAAC,MAAQ,EAAA;AACtB,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAI,CAAC,uBAAyB,EAAA;AAC5B,MAAA,YAAA,CAAa,IAAI,CAAA,CAAA;AAAA,KACZ,MAAA;AACL,MAAM,MAAA,QAAA,GAAW,WAAY,CAAA,MAAA,EAAQ,uBAAuB,CAAA,CAAA;AAE5D,MAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACvB;AAAA,KACC,CAAC,uBAAA,EAAyB,MAAQ,EAAA,MAAA,EAAQ,YAAY,CAAC,CAAA,CAAA;AAG1D,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,SAAgC,KAAsC,KAAA;AACrE,MAAA,gBAAA,GAAmB,SAAS,KAAK,CAAA,CAAA;AACjC,MAAA,IAAI,KAAM,CAAA,gBAAA;AAAkB,QAAA,OAAA;AAE5B,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAA,OAAA;AAAA,OACF;AACA,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAA,MAAM,SAAS,YAAa,CAAA;AAAA,QAC1B,MAAM,OAAQ,CAAA,IAAA;AAAA,QACd,aAAa,OAAQ,CAAA,WAAA;AAAA,QACrB,QAAA,EAAU,KAAM,CAAA,QAAA,IAAY,EAAC;AAAA,OAC9B,CAAA,CAAA;AACD,MAAO,MAAA,CAAA,QAAA,CAAS,UAAW,CAAA,MAAA,CAAO,EAAE,CAAA,CAAA;AAAA,KACtC;AAAA,IACA,CAAC,gBAAA,EAAkB,MAAQ,EAAA,YAAA,EAAc,MAAM,QAAQ,CAAA;AAAA,GACzD,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC,KAA0C,KAAA;AACzC,MAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAEjB,MAAA,IAAI,KAAM,CAAA,kBAAA,EAAwB,IAAA,CAAC,MAAQ,EAAA;AACzC,QAAA,OAAA;AAAA,OACF;AAEA,MAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,QAAC,MAAO,CAAA,KAAA,EACL,CAAA,mBAAA,GACA,GAAI,EAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,IACA,CAAC,QAAQ,SAAS,CAAA;AAAA,GACpB,CAAA;AAEA,EAAI,IAAA,CAAC,MAAU,IAAA,CAAC,MAAQ,EAAA;AACtB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,YAAA;AAAA,oBACJ,GAAA,CAAA,KAAA,EAAA;AAAA,MACC,SAAU,EAAA,+EAAA;AAAA,MACV,GAAK,EAAA,WAAA;AAAA,MACL,KAAO,EAAA;AAAA,QACL,QAAU,EAAA,QAAA;AAAA,QACV,GAAK,EAAA,CAAA;AAAA,QACL,IAAM,EAAA,CAAA;AAAA,QACN,SAAA,EAAW,eAAe,IAAK,CAAA,KAAA,CAAM,CAAC,CAAQ,CAAA,IAAA,EAAA,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,MAAA,CAAA;AAAA,QAC1D,QAAU,EAAA,aAAA;AAAA,OACZ;AAAA,MAEA,QAAC,kBAAA,GAAA,CAAA,QAAA,EAAA;AAAA,QACC,GAAK,EAAA,YAAA;AAAA,QACJ,GAAG,KAAA;AAAA,QACJ,SAAW,EAAA,aAAA;AAAA,QACX,gBAAkB,EAAA,oBAAA;AAAA,QAClB,OAAA,EAAS,CAAC,CAAM,KAAA;AAEd,UAAA,CAAA,CAAE,eAAgB,EAAA,CAAA;AAAA,SACpB;AAAA,QACA,SAAW,EAAA,IAAA;AAAA,OACb,CAAA;AAAA,KACF,CAAA;AAAA,IACA,QAAS,CAAA,IAAA;AAAA,GACX,CAAA;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"FloatingComposer.mjs","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type { ComponentRef, FormEvent, KeyboardEvent } from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type {\n CommentsExtensionStorage,\n ExtendedChainedCommands,\n} from \"../types\";\nimport { compareSelections, getDomRangeFromSelection } from \"../utils\";\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n editor: Editor | null;\n};\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const createThread = useCreateThread();\n const { editor, onComposerSubmit, onKeyDown } = props;\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) return;\n\n return (\n ctx.editor.storage.liveblocksComments as\n | CommentsExtensionStorage\n | undefined\n )?.pendingComment && !ctx.editor.state.selection.empty\n ? ctx.editor.state.selection\n : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(\n editor,\n pendingCommentSelection\n );\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={(e) => {\n // Don't send up a click event from emoji popout and close the composer\n e.stopPropagation();\n }}\n autoFocus={true}\n />\n </div>,\n document.body\n );\n});\n"],"names":["FloatingComposer"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,36 +1,49 @@
1
+ import { ContextualPromptContext, ContextualPromptResponse, BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
1
2
  import { Content, Extension } from '@tiptap/core';
2
3
  import * as react from 'react';
3
4
  import { ComponentProps, ReactNode, ComponentType, PropsWithChildren, ComponentPropsWithoutRef, HTMLAttributes } from 'react';
4
5
  import { Editor } from '@tiptap/react';
5
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
- import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
7
7
  import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
8
8
  import { BaseMetadata as BaseMetadata$1 } from '@liveblocks/client';
9
9
 
10
- type DocumentText = {
11
- beforeSelection: string;
12
- selection: string;
13
- afterSelection: string;
14
- };
15
-
16
10
  /**
17
11
  * @beta
18
12
  */
19
- type ResolveAiPromptArgs = {
13
+ type ResolveContextualPromptArgs = {
14
+ /**
15
+ * The prompt being requested by the user.
16
+ */
20
17
  prompt: string;
21
- signal: AbortSignal;
22
- context: DocumentText;
18
+ /**
19
+ * The context of the document and its current selection.
20
+ */
21
+ context: ContextualPromptContext;
22
+ /**
23
+ * The previous request and its response, if this is a follow-up request.
24
+ */
23
25
  previous?: {
24
26
  prompt: string;
25
- output: {
26
- type: string;
27
- content: string;
28
- };
27
+ response: ContextualPromptResponse;
29
28
  };
29
+ /**
30
+ * An abort signal that can be used to cancel requests.
31
+ */
32
+ signal: AbortSignal;
30
33
  };
34
+ /**
35
+ * @beta
36
+ */
37
+ type ResolveContextualPromptResponse = ContextualPromptResponse;
31
38
  interface AiConfiguration {
39
+ /**
40
+ * The AI's name. ("Ask {name} anything…", "{name} is thinking…", etc)
41
+ */
32
42
  name?: string;
33
- resolveAiPrompt?: (args: ResolveAiPromptArgs) => Promise<AiResponse>;
43
+ /**
44
+ * A function that returns an a response to a contextual prompt.
45
+ */
46
+ resolveContextualPrompt?: (args: ResolveContextualPromptArgs) => Promise<ContextualPromptResponse>;
34
47
  }
35
48
  type LiveblocksExtensionOptions = {
36
49
  field?: string;
@@ -52,10 +65,6 @@ type CommentsCommands<ReturnType = boolean> = {
52
65
  type AiCommands<ReturnType = boolean> = {
53
66
  askAi: (prompt?: string) => ReturnType;
54
67
  };
55
- type AiResponse = {
56
- type: "insert" | "replace" | "other";
57
- content: string;
58
- };
59
68
 
60
69
  interface AiToolbarProps extends Omit<ComponentProps<"div">, "value" | "defaultValue" | "children"> {
61
70
  editor: Editor | null;
@@ -408,4 +417,4 @@ declare module "@tiptap/core" {
408
417
  }
409
418
  }
410
419
 
411
- export { AiConfiguration, AiToolbar, AiToolbarProps, AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, FloatingToolbar, FloatingToolbarProps, HistoryVersionPreview, HistoryVersionPreviewProps, ResolveAiPromptArgs, Toolbar, ToolbarBlockSelectorItem, ToolbarBlockSelectorProps, ToolbarButtonProps, ToolbarProps, ToolbarSeparatorProps, ToolbarToggleProps, useIsEditorReady, useLiveblocksExtension };
420
+ export { AiConfiguration, AiToolbar, AiToolbarProps, AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, FloatingToolbar, FloatingToolbarProps, HistoryVersionPreview, HistoryVersionPreviewProps, ResolveContextualPromptArgs, ResolveContextualPromptResponse, Toolbar, ToolbarBlockSelectorItem, ToolbarBlockSelectorProps, ToolbarButtonProps, ToolbarProps, ToolbarSeparatorProps, ToolbarToggleProps, useIsEditorReady, useLiveblocksExtension };
package/dist/index.d.ts CHANGED
@@ -1,36 +1,49 @@
1
+ import { ContextualPromptContext, ContextualPromptResponse, BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
1
2
  import { Content, Extension } from '@tiptap/core';
2
3
  import * as react from 'react';
3
4
  import { ComponentProps, ReactNode, ComponentType, PropsWithChildren, ComponentPropsWithoutRef, HTMLAttributes } from 'react';
4
5
  import { Editor } from '@tiptap/react';
5
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
- import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
7
7
  import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
8
8
  import { BaseMetadata as BaseMetadata$1 } from '@liveblocks/client';
9
9
 
10
- type DocumentText = {
11
- beforeSelection: string;
12
- selection: string;
13
- afterSelection: string;
14
- };
15
-
16
10
  /**
17
11
  * @beta
18
12
  */
19
- type ResolveAiPromptArgs = {
13
+ type ResolveContextualPromptArgs = {
14
+ /**
15
+ * The prompt being requested by the user.
16
+ */
20
17
  prompt: string;
21
- signal: AbortSignal;
22
- context: DocumentText;
18
+ /**
19
+ * The context of the document and its current selection.
20
+ */
21
+ context: ContextualPromptContext;
22
+ /**
23
+ * The previous request and its response, if this is a follow-up request.
24
+ */
23
25
  previous?: {
24
26
  prompt: string;
25
- output: {
26
- type: string;
27
- content: string;
28
- };
27
+ response: ContextualPromptResponse;
29
28
  };
29
+ /**
30
+ * An abort signal that can be used to cancel requests.
31
+ */
32
+ signal: AbortSignal;
30
33
  };
34
+ /**
35
+ * @beta
36
+ */
37
+ type ResolveContextualPromptResponse = ContextualPromptResponse;
31
38
  interface AiConfiguration {
39
+ /**
40
+ * The AI's name. ("Ask {name} anything…", "{name} is thinking…", etc)
41
+ */
32
42
  name?: string;
33
- resolveAiPrompt?: (args: ResolveAiPromptArgs) => Promise<AiResponse>;
43
+ /**
44
+ * A function that returns an a response to a contextual prompt.
45
+ */
46
+ resolveContextualPrompt?: (args: ResolveContextualPromptArgs) => Promise<ContextualPromptResponse>;
34
47
  }
35
48
  type LiveblocksExtensionOptions = {
36
49
  field?: string;
@@ -52,10 +65,6 @@ type CommentsCommands<ReturnType = boolean> = {
52
65
  type AiCommands<ReturnType = boolean> = {
53
66
  askAi: (prompt?: string) => ReturnType;
54
67
  };
55
- type AiResponse = {
56
- type: "insert" | "replace" | "other";
57
- content: string;
58
- };
59
68
 
60
69
  interface AiToolbarProps extends Omit<ComponentProps<"div">, "value" | "defaultValue" | "children"> {
61
70
  editor: Editor | null;
@@ -408,4 +417,4 @@ declare module "@tiptap/core" {
408
417
  }
409
418
  }
410
419
 
411
- export { AiConfiguration, AiToolbar, AiToolbarProps, AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, FloatingToolbar, FloatingToolbarProps, HistoryVersionPreview, HistoryVersionPreviewProps, ResolveAiPromptArgs, Toolbar, ToolbarBlockSelectorItem, ToolbarBlockSelectorProps, ToolbarButtonProps, ToolbarProps, ToolbarSeparatorProps, ToolbarToggleProps, useIsEditorReady, useLiveblocksExtension };
420
+ export { AiConfiguration, AiToolbar, AiToolbarProps, AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, FloatingToolbar, FloatingToolbarProps, HistoryVersionPreview, HistoryVersionPreviewProps, ResolveContextualPromptArgs, ResolveContextualPromptResponse, Toolbar, ToolbarBlockSelectorItem, ToolbarBlockSelectorProps, ToolbarButtonProps, ToolbarProps, ToolbarSeparatorProps, ToolbarToggleProps, useIsEditorReady, useLiveblocksExtension };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport type { AiCommands, CommentsCommands } from \"./types\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AiToolbarProps } from \"./ai/AiToolbar\";\nexport { AiToolbar } from \"./ai/AiToolbar\";\nexport type { AnchoredThreadsProps } from \"./comments/AnchoredThreads\";\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport type { FloatingComposerProps } from \"./comments/FloatingComposer\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport type { FloatingThreadsProps } from \"./comments/FloatingThreads\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport type { FloatingToolbarProps } from \"./toolbar/FloatingToolbar\";\nexport { FloatingToolbar } from \"./toolbar/FloatingToolbar\";\nexport type {\n ToolbarBlockSelectorItem,\n ToolbarBlockSelectorProps,\n ToolbarButtonProps,\n ToolbarProps,\n ToolbarSeparatorProps,\n ToolbarToggleProps,\n} from \"./toolbar/Toolbar\";\nexport { Toolbar } from \"./toolbar/Toolbar\";\nexport type { AiConfiguration, ResolveAiPromptArgs } from \"./types\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/HistoryVersionPreview\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n liveblocksComments: CommentsCommands<ReturnType>;\n liveblocksAi: AiCommands<ReturnType>;\n }\n}\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;;AAKAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport type { AiCommands, CommentsCommands } from \"./types\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AiToolbarProps } from \"./ai/AiToolbar\";\nexport { AiToolbar } from \"./ai/AiToolbar\";\nexport type { AnchoredThreadsProps } from \"./comments/AnchoredThreads\";\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport type { FloatingComposerProps } from \"./comments/FloatingComposer\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport type { FloatingThreadsProps } from \"./comments/FloatingThreads\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport type { FloatingToolbarProps } from \"./toolbar/FloatingToolbar\";\nexport { FloatingToolbar } from \"./toolbar/FloatingToolbar\";\nexport type {\n ToolbarBlockSelectorItem,\n ToolbarBlockSelectorProps,\n ToolbarButtonProps,\n ToolbarProps,\n ToolbarSeparatorProps,\n ToolbarToggleProps,\n} from \"./toolbar/Toolbar\";\nexport { Toolbar } from \"./toolbar/Toolbar\";\nexport type {\n AiConfiguration,\n ResolveContextualPromptArgs,\n ResolveContextualPromptResponse,\n} from \"./types\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/HistoryVersionPreview\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n liveblocksComments: CommentsCommands<ReturnType>;\n liveblocksAi: AiCommands<ReturnType>;\n }\n}\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;;AAKAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport type { AiCommands, CommentsCommands } from \"./types\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AiToolbarProps } from \"./ai/AiToolbar\";\nexport { AiToolbar } from \"./ai/AiToolbar\";\nexport type { AnchoredThreadsProps } from \"./comments/AnchoredThreads\";\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport type { FloatingComposerProps } from \"./comments/FloatingComposer\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport type { FloatingThreadsProps } from \"./comments/FloatingThreads\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport type { FloatingToolbarProps } from \"./toolbar/FloatingToolbar\";\nexport { FloatingToolbar } from \"./toolbar/FloatingToolbar\";\nexport type {\n ToolbarBlockSelectorItem,\n ToolbarBlockSelectorProps,\n ToolbarButtonProps,\n ToolbarProps,\n ToolbarSeparatorProps,\n ToolbarToggleProps,\n} from \"./toolbar/Toolbar\";\nexport { Toolbar } from \"./toolbar/Toolbar\";\nexport type { AiConfiguration, ResolveAiPromptArgs } from \"./types\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/HistoryVersionPreview\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n liveblocksComments: CommentsCommands<ReturnType>;\n liveblocksAi: AiCommands<ReturnType>;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAKA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport type { AiCommands, CommentsCommands } from \"./types\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AiToolbarProps } from \"./ai/AiToolbar\";\nexport { AiToolbar } from \"./ai/AiToolbar\";\nexport type { AnchoredThreadsProps } from \"./comments/AnchoredThreads\";\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport type { FloatingComposerProps } from \"./comments/FloatingComposer\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport type { FloatingThreadsProps } from \"./comments/FloatingThreads\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport type { FloatingToolbarProps } from \"./toolbar/FloatingToolbar\";\nexport { FloatingToolbar } from \"./toolbar/FloatingToolbar\";\nexport type {\n ToolbarBlockSelectorItem,\n ToolbarBlockSelectorProps,\n ToolbarButtonProps,\n ToolbarProps,\n ToolbarSeparatorProps,\n ToolbarToggleProps,\n} from \"./toolbar/Toolbar\";\nexport { Toolbar } from \"./toolbar/Toolbar\";\nexport type {\n AiConfiguration,\n ResolveContextualPromptArgs,\n ResolveContextualPromptResponse,\n} from \"./types\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/HistoryVersionPreview\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n liveblocksComments: CommentsCommands<ReturnType>;\n liveblocksAi: AiCommands<ReturnType>;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAKA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../src/types.ts"],"sourcesContent":["import type { Relax } from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { Content, Range } from \"@tiptap/core\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { DecorationSet } from \"@tiptap/pm/view\";\nimport type { ChainedCommands, SingleCommands } from \"@tiptap/react\";\nimport type { ProsemirrorBinding } from \"y-prosemirror\";\nimport type { Doc, PermanentUserData, Snapshot } from \"yjs\";\n\nimport type { DocumentText } from \"./utils\";\n\nexport const LIVEBLOCKS_MENTION_KEY = new PluginKey(\"lb-plugin-mention\");\nexport const LIVEBLOCKS_MENTION_PASTE_KEY = new PluginKey(\n \"lb-plugin-mention-paste\"\n);\nexport const LIVEBLOCKS_MENTION_NOTIFIER_KEY = new PluginKey(\n \"lb-plugin-mention-notify\"\n);\nexport const LIVEBLOCKS_MENTION_TYPE = \"liveblocksMention\";\n\nexport const THREADS_ACTIVE_SELECTION_PLUGIN = new PluginKey(\n \"lb-threads-active-selection-plugin\"\n);\nexport const THREADS_PLUGIN_KEY = new PluginKey<ThreadPluginState>(\n \"lb-threads-plugin\"\n);\nexport const AI_TOOLBAR_SELECTION_PLUGIN = new PluginKey(\n \"lb-ai-toolbar-selection-plugin\"\n);\n\nexport const LIVEBLOCKS_COMMENT_MARK_TYPE = \"liveblocksCommentMark\";\n\n/**\n * @beta\n */\nexport type ResolveAiPromptArgs = {\n prompt: string;\n signal: AbortSignal;\n context: DocumentText;\n previous?: {\n prompt: string;\n output: {\n type: string;\n content: string;\n };\n };\n};\n\nexport interface AiConfiguration {\n name?: string;\n resolveAiPrompt?: (args: ResolveAiPromptArgs) => Promise<AiResponse>;\n}\n\nexport type LiveblocksExtensionOptions = {\n field?: string;\n comments?: boolean; // | CommentsConfiguration\n mentions?: boolean; // | MentionsConfiguration\n ai?: boolean | AiConfiguration;\n offlineSupport_experimental?: boolean;\n initialContent?: Content;\n};\n\nexport type LiveblocksExtensionStorage = {\n unsubs: (() => void)[];\n doc: Doc;\n provider: LiveblocksYjsProvider<any, any, any, any, any>;\n permanentUserData: PermanentUserData;\n};\n\nexport type CommentsExtensionStorage = {\n pendingComment: boolean;\n};\n\nexport const enum ThreadPluginActions {\n SET_SELECTED_THREAD_ID = \"SET_SELECTED_THREAD_ID\",\n}\n\nexport type AiExtensionOptions = {\n doc: Doc | undefined;\n pud: PermanentUserData | undefined;\n name: string;\n resolveAiPrompt: (args: ResolveAiPromptArgs) => Promise<AiResponse>;\n};\n\nexport type AiToolbarOutput = Relax<\n | {\n type: \"replace\";\n text: string;\n }\n | {\n type: \"insert\";\n text: string;\n }\n | {\n type: \"other\";\n text: string;\n }\n>;\n\n/**\n * The state of the AI toolbar.\n *\n * ┌────────────────────────────────────────────────────────────────────────────────┐\n * │ │\n * │ ┌──────────────────────────────────────────────┐ │\n * ▼ ▼ │ │\n * ┌───────$closeAiToolbar()───────┐ │ │\n * ▼ ◇ ◇ ◇\n * ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐\n * │ CLOSED │ │ ASKING │ │ THINKING │ │ REVIEWING │\n * └───────────────────────┘ └───────────────────────┘ └───────────────────────┘ └───────────────────────┘\n * ▲ ◇ ◇ ▲ ▲ ◇ ▲ ▲ ◇ ▲ ◇ ◇\n * │ │ └───$openAiToolbarAsking()──┘ │ │ └ ─ ─ ─ ─ ─ ─⚠─ ─ ─ ─ ─ ─ ─│─├── ─ ─ ─ ─ ─ ─✓─ ─ ─ ─ ─ ─ ─ ┘ │ │\n * │ │ │ ▼ │ │ │ │\n * │ └─────────────────$startAiToolbarThinking(prompt)──────────────┘ │ │ │\n * │ │ ▲ │ │ │\n * │ │ └──────────────────────────────┼───────────────────────────────┘ │\n * │ │ │ │\n * │ └───$cancelAiToolbarThinking()───┘ │\n * │ │\n * └──────────────────────────────────────$acceptAiToolbarOutput()──────────────────────────────────────┘\n *\n */\nexport type AiToolbarState = Relax<\n | {\n phase: \"closed\";\n }\n | {\n phase: \"asking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * A potential error that occurred during the last AI request.\n */\n error?: Error;\n }\n | {\n phase: \"thinking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * An abort controller to cancel the AI request.\n */\n abortController: AbortController;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The previous output if this \"thinking\" phase is a refinement.\n */\n previousOutput?: AiToolbarOutput;\n }\n | {\n phase: \"reviewing\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The output of the AI request.\n */\n output: AiToolbarOutput;\n }\n>;\n\nexport type AiExtensionStorage = {\n name: string;\n state: AiToolbarState;\n snapshot?: Snapshot;\n};\n\nexport type ThreadPluginState = {\n threadPositions: Map<string, { from: number; to: number }>;\n selectedThreadId: string | null;\n selectedThreadPos: number | null;\n decorations: DecorationSet;\n};\n\nexport type FloatingPosition = \"top\" | \"bottom\";\n\nexport type ExtendedCommands<\n T extends string,\n A extends any[] = [],\n> = SingleCommands & Record<T, (...args: A) => boolean>;\n\nexport type ExtendedChainedCommands<\n T extends string,\n A extends any[] = [],\n> = ChainedCommands & Record<T, (...args: A) => ChainedCommands>;\n\nexport type ChainedAiCommands = ChainedCommands & {\n [K in keyof AiCommands]: (\n ...args: Parameters<AiCommands[K]>\n ) => ChainedCommands;\n};\n\nexport type CommentsCommands<ReturnType = boolean> = {\n /**\n * Add a comment\n */\n addComment: (id: string) => ReturnType;\n selectThread: (id: string | null) => ReturnType;\n addPendingComment: () => ReturnType;\n\n /** @internal */\n closePendingComment: () => ReturnType;\n};\n\nexport type AiCommands<ReturnType = boolean> = {\n askAi: (prompt?: string) => ReturnType;\n\n // Transitions (see AiToolbarState)\n\n /**\n * @internal\n * @transition\n *\n * Close the AI toolbar.\n */\n $closeAiToolbar: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Accept the current AI output and close the AI toolbar.\n */\n $acceptAiToolbarOutput: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Open the AI toolbar in the \"asking\" phase.\n */\n $openAiToolbarAsking: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Set (and open if not already open) the AI toolbar in the \"thinking\" phase with the given prompt.\n */\n $startAiToolbarThinking: (\n prompt: string,\n withPreviousOutput?: boolean\n ) => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Cancel the current \"thinking\" phase, going back to the \"asking\" phase.\n */\n $cancelAiToolbarThinking: () => ReturnType;\n\n // Other\n\n /**\n * @internal\n *\n * Show the diff of the current \"reviewing\" phase.\n */\n _showAiToolbarOutputDiff: () => ReturnType;\n\n /**\n * @internal\n *\n * Handle the success of the current \"thinking\" phase.\n *\n * This should be handled in $startAiToolbarThinking directly (.then(success).catch(error))\n * but storage updates don't trigger their listeners if not called from a command.\n */\n _handleAiToolbarThinkingSuccess: (output: AiToolbarOutput) => ReturnType;\n\n /**\n * @internal\n *\n * Handle an error of the current \"thinking\" phase.\n *\n * This should be handled in $startAiToolbarThinking directly (.then(success).catch(error))\n * but storage updates don't trigger their listeners if not called from a command.\n */\n _handleAiToolbarThinkingError: (error: unknown) => ReturnType;\n\n /**\n * @internal\n *\n * Update the current custom AI prompt.\n */\n _updateAiToolbarCustomPrompt: (\n customPrompt: string | ((currentCustomPrompt: string) => string)\n ) => ReturnType;\n};\n\nexport type YSyncPluginState = {\n binding: ProsemirrorBinding;\n};\n\nexport type AiResponse = {\n type: \"insert\" | \"replace\" | \"other\";\n content: string;\n};\n"],"names":["PluginKey","ThreadPluginActions"],"mappings":";;;;AAWa,MAAA,sBAAA,GAAyB,IAAIA,eAAA,CAAU,mBAAmB,EAAA;AAChE,MAAM,+BAA+B,IAAIA,eAAA;AAAA,EAC9C,yBAAA;AACF,EAAA;AACO,MAAM,kCAAkC,IAAIA,eAAA;AAAA,EACjD,0BAAA;AACF,EAAA;AACO,MAAM,uBAA0B,GAAA,oBAAA;AAEhC,MAAM,kCAAkC,IAAIA,eAAA;AAAA,EACjD,oCAAA;AACF,EAAA;AACO,MAAM,qBAAqB,IAAIA,eAAA;AAAA,EACpC,mBAAA;AACF,EAAA;AACO,MAAM,8BAA8B,IAAIA,eAAA;AAAA,EAC7C,gCAAA;AACF,EAAA;AAEO,MAAM,4BAA+B,GAAA,wBAAA;AA2C1B,IAAA,mBAAA,qBAAAC,oBAAX,KAAA;AACL,EAAAA,qBAAA,wBAAyB,CAAA,GAAA,wBAAA,CAAA;AADT,EAAAA,OAAAA,oBAAAA,CAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;;;;;;;;;;;;"}
1
+ {"version":3,"file":"types.js","sources":["../src/types.ts"],"sourcesContent":["import type {\n ContextualPromptContext,\n ContextualPromptResponse,\n Relax,\n} from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { Content, Range } from \"@tiptap/core\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { DecorationSet } from \"@tiptap/pm/view\";\nimport type { ChainedCommands, SingleCommands } from \"@tiptap/react\";\nimport type { ProsemirrorBinding } from \"y-prosemirror\";\nimport type { Doc, PermanentUserData, Snapshot } from \"yjs\";\n\nexport const LIVEBLOCKS_MENTION_KEY = new PluginKey(\"lb-plugin-mention\");\nexport const LIVEBLOCKS_MENTION_PASTE_KEY = new PluginKey(\n \"lb-plugin-mention-paste\"\n);\nexport const LIVEBLOCKS_MENTION_NOTIFIER_KEY = new PluginKey(\n \"lb-plugin-mention-notify\"\n);\nexport const LIVEBLOCKS_MENTION_TYPE = \"liveblocksMention\";\n\nexport const THREADS_ACTIVE_SELECTION_PLUGIN = new PluginKey(\n \"lb-threads-active-selection-plugin\"\n);\nexport const THREADS_PLUGIN_KEY = new PluginKey<ThreadPluginState>(\n \"lb-threads-plugin\"\n);\nexport const AI_TOOLBAR_SELECTION_PLUGIN = new PluginKey(\n \"lb-ai-toolbar-selection-plugin\"\n);\n\nexport const LIVEBLOCKS_COMMENT_MARK_TYPE = \"liveblocksCommentMark\";\n\n/**\n * @beta\n */\nexport type ResolveContextualPromptArgs = {\n /**\n * The prompt being requested by the user.\n */\n prompt: string;\n\n /**\n * The context of the document and its current selection.\n */\n context: ContextualPromptContext;\n\n /**\n * The previous request and its response, if this is a follow-up request.\n */\n previous?: {\n prompt: string;\n response: ContextualPromptResponse;\n };\n\n /**\n * An abort signal that can be used to cancel requests.\n */\n signal: AbortSignal;\n};\n\n/**\n * @beta\n */\nexport type ResolveContextualPromptResponse = ContextualPromptResponse;\n\nexport interface AiConfiguration {\n /**\n * The AI's name. (\"Ask {name} anything…\", \"{name} is thinking…\", etc)\n */\n name?: string;\n\n /**\n * A function that returns an a response to a contextual prompt.\n */\n resolveContextualPrompt?: (\n args: ResolveContextualPromptArgs\n ) => Promise<ContextualPromptResponse>;\n}\n\nexport type LiveblocksExtensionOptions = {\n field?: string;\n comments?: boolean; // | CommentsConfiguration\n mentions?: boolean; // | MentionsConfiguration\n ai?: boolean | AiConfiguration;\n offlineSupport_experimental?: boolean;\n initialContent?: Content;\n};\n\nexport type LiveblocksExtensionStorage = {\n unsubs: (() => void)[];\n doc: Doc;\n provider: LiveblocksYjsProvider<any, any, any, any, any>;\n permanentUserData: PermanentUserData;\n};\n\nexport type CommentsExtensionStorage = {\n pendingComment: boolean;\n};\n\nexport const enum ThreadPluginActions {\n SET_SELECTED_THREAD_ID = \"SET_SELECTED_THREAD_ID\",\n}\n\nexport type AiExtensionOptions = Pick<\n AiConfiguration,\n \"name\" | \"resolveContextualPrompt\"\n> & {\n doc: Doc | undefined;\n pud: PermanentUserData | undefined;\n};\n\n/**\n * The state of the AI toolbar.\n *\n * ┌────────────────────────────────────────────────────────────────────────────────┐\n * │ │\n * │ ┌──────────────────────────────────────────────┐ │\n * ▼ ▼ │ │\n * ┌───────$closeAiToolbar()───────┐ │ │\n * ▼ ◇ ◇ ◇\n * ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐\n * │ CLOSED │ │ ASKING │ │ THINKING │ │ REVIEWING │\n * └───────────────────────┘ └───────────────────────┘ └───────────────────────┘ └───────────────────────┘\n * ▲ ◇ ◇ ▲ ▲ ◇ ▲ ▲ ◇ ▲ ◇ ◇\n * │ │ └───$openAiToolbarAsking()──┘ │ │ └ ─ ─ ─ ─ ─ ─⚠─ ─ ─ ─ ─ ─ ─│─├── ─ ─ ─ ─ ─ ─✓─ ─ ─ ─ ─ ─ ─ ┘ │ │\n * │ │ │ ▼ │ │ │ │\n * │ └─────────────────$startAiToolbarThinking(prompt)──────────────┘ │ │ │\n * │ │ ▲ │ │ │\n * │ │ └──────────────────────────────┼───────────────────────────────┘ │\n * │ │ │ │\n * │ └───$cancelAiToolbarThinking()───┘ │\n * │ │\n * └─────────────────────────────────────$acceptAiToolbarResponse()─────────────────────────────────────┘\n *\n */\nexport type AiToolbarState = Relax<\n | {\n phase: \"closed\";\n }\n | {\n phase: \"asking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * A potential error that occurred during the last AI request.\n */\n error?: Error;\n }\n | {\n phase: \"thinking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * An abort controller to cancel the AI request.\n */\n abortController: AbortController;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The previous response if this \"thinking\" phase is a refinement.\n */\n previousResponse?: ContextualPromptResponse;\n }\n | {\n phase: \"reviewing\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The response of the AI request.\n */\n response: ContextualPromptResponse;\n }\n>;\n\nexport type AiExtensionStorage = {\n name: string;\n state: AiToolbarState;\n snapshot?: Snapshot;\n};\n\nexport type ThreadPluginState = {\n threadPositions: Map<string, { from: number; to: number }>;\n selectedThreadId: string | null;\n selectedThreadPos: number | null;\n decorations: DecorationSet;\n};\n\nexport type FloatingPosition = \"top\" | \"bottom\";\n\nexport type ExtendedCommands<\n T extends string,\n A extends any[] = [],\n> = SingleCommands & Record<T, (...args: A) => boolean>;\n\nexport type ExtendedChainedCommands<\n T extends string,\n A extends any[] = [],\n> = ChainedCommands & Record<T, (...args: A) => ChainedCommands>;\n\nexport type ChainedAiCommands = ChainedCommands & {\n [K in keyof AiCommands]: (\n ...args: Parameters<AiCommands[K]>\n ) => ChainedCommands;\n};\n\nexport type CommentsCommands<ReturnType = boolean> = {\n /**\n * Add a comment\n */\n addComment: (id: string) => ReturnType;\n selectThread: (id: string | null) => ReturnType;\n addPendingComment: () => ReturnType;\n\n /** @internal */\n closePendingComment: () => ReturnType;\n};\n\nexport type AiCommands<ReturnType = boolean> = {\n askAi: (prompt?: string) => ReturnType;\n\n // Transitions (see AiToolbarState)\n\n /**\n * @internal\n * @transition\n *\n * Close the AI toolbar.\n */\n $closeAiToolbar: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Accept the current AI response and close the AI toolbar.\n */\n $acceptAiToolbarResponse: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Open the AI toolbar in the \"asking\" phase.\n */\n $openAiToolbarAsking: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Set (and open if not already open) the AI toolbar in the \"thinking\" phase with the given prompt.\n */\n $startAiToolbarThinking: (\n prompt: string,\n withPreviousResponse?: boolean\n ) => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Cancel the current \"thinking\" phase, going back to the \"asking\" phase.\n */\n $cancelAiToolbarThinking: () => ReturnType;\n\n // Other\n\n /**\n * @internal\n *\n * Show the diff of the current \"reviewing\" phase.\n */\n _showAiToolbarReviewingDiff: () => ReturnType;\n\n /**\n * @internal\n *\n * Handle the success of the current \"thinking\" phase.\n */\n _handleAiToolbarThinkingSuccess: (\n response: ContextualPromptResponse\n ) => ReturnType;\n\n /**\n * @internal\n *\n * Handle an error of the current \"thinking\" phase.\n */\n _handleAiToolbarThinkingError: (error: unknown) => ReturnType;\n\n /**\n * @internal\n *\n * Update the current custom AI prompt.\n */\n _updateAiToolbarCustomPrompt: (\n customPrompt: string | ((currentCustomPrompt: string) => string)\n ) => ReturnType;\n};\n\nexport type YSyncPluginState = {\n binding: ProsemirrorBinding;\n};\n"],"names":["PluginKey","ThreadPluginActions"],"mappings":";;;;AAaa,MAAA,sBAAA,GAAyB,IAAIA,eAAA,CAAU,mBAAmB,EAAA;AAChE,MAAM,+BAA+B,IAAIA,eAAA;AAAA,EAC9C,yBAAA;AACF,EAAA;AACO,MAAM,kCAAkC,IAAIA,eAAA;AAAA,EACjD,0BAAA;AACF,EAAA;AACO,MAAM,uBAA0B,GAAA,oBAAA;AAEhC,MAAM,kCAAkC,IAAIA,eAAA;AAAA,EACjD,oCAAA;AACF,EAAA;AACO,MAAM,qBAAqB,IAAIA,eAAA;AAAA,EACpC,mBAAA;AACF,EAAA;AACO,MAAM,8BAA8B,IAAIA,eAAA;AAAA,EAC7C,gCAAA;AACF,EAAA;AAEO,MAAM,4BAA+B,GAAA,wBAAA;AAqE1B,IAAA,mBAAA,qBAAAC,oBAAX,KAAA;AACL,EAAAA,qBAAA,wBAAyB,CAAA,GAAA,wBAAA,CAAA;AADT,EAAAA,OAAAA,oBAAAA,CAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sources":["../src/types.ts"],"sourcesContent":["import type { Relax } from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { Content, Range } from \"@tiptap/core\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { DecorationSet } from \"@tiptap/pm/view\";\nimport type { ChainedCommands, SingleCommands } from \"@tiptap/react\";\nimport type { ProsemirrorBinding } from \"y-prosemirror\";\nimport type { Doc, PermanentUserData, Snapshot } from \"yjs\";\n\nimport type { DocumentText } from \"./utils\";\n\nexport const LIVEBLOCKS_MENTION_KEY = new PluginKey(\"lb-plugin-mention\");\nexport const LIVEBLOCKS_MENTION_PASTE_KEY = new PluginKey(\n \"lb-plugin-mention-paste\"\n);\nexport const LIVEBLOCKS_MENTION_NOTIFIER_KEY = new PluginKey(\n \"lb-plugin-mention-notify\"\n);\nexport const LIVEBLOCKS_MENTION_TYPE = \"liveblocksMention\";\n\nexport const THREADS_ACTIVE_SELECTION_PLUGIN = new PluginKey(\n \"lb-threads-active-selection-plugin\"\n);\nexport const THREADS_PLUGIN_KEY = new PluginKey<ThreadPluginState>(\n \"lb-threads-plugin\"\n);\nexport const AI_TOOLBAR_SELECTION_PLUGIN = new PluginKey(\n \"lb-ai-toolbar-selection-plugin\"\n);\n\nexport const LIVEBLOCKS_COMMENT_MARK_TYPE = \"liveblocksCommentMark\";\n\n/**\n * @beta\n */\nexport type ResolveAiPromptArgs = {\n prompt: string;\n signal: AbortSignal;\n context: DocumentText;\n previous?: {\n prompt: string;\n output: {\n type: string;\n content: string;\n };\n };\n};\n\nexport interface AiConfiguration {\n name?: string;\n resolveAiPrompt?: (args: ResolveAiPromptArgs) => Promise<AiResponse>;\n}\n\nexport type LiveblocksExtensionOptions = {\n field?: string;\n comments?: boolean; // | CommentsConfiguration\n mentions?: boolean; // | MentionsConfiguration\n ai?: boolean | AiConfiguration;\n offlineSupport_experimental?: boolean;\n initialContent?: Content;\n};\n\nexport type LiveblocksExtensionStorage = {\n unsubs: (() => void)[];\n doc: Doc;\n provider: LiveblocksYjsProvider<any, any, any, any, any>;\n permanentUserData: PermanentUserData;\n};\n\nexport type CommentsExtensionStorage = {\n pendingComment: boolean;\n};\n\nexport const enum ThreadPluginActions {\n SET_SELECTED_THREAD_ID = \"SET_SELECTED_THREAD_ID\",\n}\n\nexport type AiExtensionOptions = {\n doc: Doc | undefined;\n pud: PermanentUserData | undefined;\n name: string;\n resolveAiPrompt: (args: ResolveAiPromptArgs) => Promise<AiResponse>;\n};\n\nexport type AiToolbarOutput = Relax<\n | {\n type: \"replace\";\n text: string;\n }\n | {\n type: \"insert\";\n text: string;\n }\n | {\n type: \"other\";\n text: string;\n }\n>;\n\n/**\n * The state of the AI toolbar.\n *\n * ┌────────────────────────────────────────────────────────────────────────────────┐\n * │ │\n * │ ┌──────────────────────────────────────────────┐ │\n * ▼ ▼ │ │\n * ┌───────$closeAiToolbar()───────┐ │ │\n * ▼ ◇ ◇ ◇\n * ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐\n * │ CLOSED │ │ ASKING │ │ THINKING │ │ REVIEWING │\n * └───────────────────────┘ └───────────────────────┘ └───────────────────────┘ └───────────────────────┘\n * ▲ ◇ ◇ ▲ ▲ ◇ ▲ ▲ ◇ ▲ ◇ ◇\n * │ │ └───$openAiToolbarAsking()──┘ │ │ └ ─ ─ ─ ─ ─ ─⚠─ ─ ─ ─ ─ ─ ─│─├── ─ ─ ─ ─ ─ ─✓─ ─ ─ ─ ─ ─ ─ ┘ │ │\n * │ │ │ ▼ │ │ │ │\n * │ └─────────────────$startAiToolbarThinking(prompt)──────────────┘ │ │ │\n * │ │ ▲ │ │ │\n * │ │ └──────────────────────────────┼───────────────────────────────┘ │\n * │ │ │ │\n * │ └───$cancelAiToolbarThinking()───┘ │\n * │ │\n * └──────────────────────────────────────$acceptAiToolbarOutput()──────────────────────────────────────┘\n *\n */\nexport type AiToolbarState = Relax<\n | {\n phase: \"closed\";\n }\n | {\n phase: \"asking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * A potential error that occurred during the last AI request.\n */\n error?: Error;\n }\n | {\n phase: \"thinking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * An abort controller to cancel the AI request.\n */\n abortController: AbortController;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The previous output if this \"thinking\" phase is a refinement.\n */\n previousOutput?: AiToolbarOutput;\n }\n | {\n phase: \"reviewing\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The output of the AI request.\n */\n output: AiToolbarOutput;\n }\n>;\n\nexport type AiExtensionStorage = {\n name: string;\n state: AiToolbarState;\n snapshot?: Snapshot;\n};\n\nexport type ThreadPluginState = {\n threadPositions: Map<string, { from: number; to: number }>;\n selectedThreadId: string | null;\n selectedThreadPos: number | null;\n decorations: DecorationSet;\n};\n\nexport type FloatingPosition = \"top\" | \"bottom\";\n\nexport type ExtendedCommands<\n T extends string,\n A extends any[] = [],\n> = SingleCommands & Record<T, (...args: A) => boolean>;\n\nexport type ExtendedChainedCommands<\n T extends string,\n A extends any[] = [],\n> = ChainedCommands & Record<T, (...args: A) => ChainedCommands>;\n\nexport type ChainedAiCommands = ChainedCommands & {\n [K in keyof AiCommands]: (\n ...args: Parameters<AiCommands[K]>\n ) => ChainedCommands;\n};\n\nexport type CommentsCommands<ReturnType = boolean> = {\n /**\n * Add a comment\n */\n addComment: (id: string) => ReturnType;\n selectThread: (id: string | null) => ReturnType;\n addPendingComment: () => ReturnType;\n\n /** @internal */\n closePendingComment: () => ReturnType;\n};\n\nexport type AiCommands<ReturnType = boolean> = {\n askAi: (prompt?: string) => ReturnType;\n\n // Transitions (see AiToolbarState)\n\n /**\n * @internal\n * @transition\n *\n * Close the AI toolbar.\n */\n $closeAiToolbar: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Accept the current AI output and close the AI toolbar.\n */\n $acceptAiToolbarOutput: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Open the AI toolbar in the \"asking\" phase.\n */\n $openAiToolbarAsking: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Set (and open if not already open) the AI toolbar in the \"thinking\" phase with the given prompt.\n */\n $startAiToolbarThinking: (\n prompt: string,\n withPreviousOutput?: boolean\n ) => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Cancel the current \"thinking\" phase, going back to the \"asking\" phase.\n */\n $cancelAiToolbarThinking: () => ReturnType;\n\n // Other\n\n /**\n * @internal\n *\n * Show the diff of the current \"reviewing\" phase.\n */\n _showAiToolbarOutputDiff: () => ReturnType;\n\n /**\n * @internal\n *\n * Handle the success of the current \"thinking\" phase.\n *\n * This should be handled in $startAiToolbarThinking directly (.then(success).catch(error))\n * but storage updates don't trigger their listeners if not called from a command.\n */\n _handleAiToolbarThinkingSuccess: (output: AiToolbarOutput) => ReturnType;\n\n /**\n * @internal\n *\n * Handle an error of the current \"thinking\" phase.\n *\n * This should be handled in $startAiToolbarThinking directly (.then(success).catch(error))\n * but storage updates don't trigger their listeners if not called from a command.\n */\n _handleAiToolbarThinkingError: (error: unknown) => ReturnType;\n\n /**\n * @internal\n *\n * Update the current custom AI prompt.\n */\n _updateAiToolbarCustomPrompt: (\n customPrompt: string | ((currentCustomPrompt: string) => string)\n ) => ReturnType;\n};\n\nexport type YSyncPluginState = {\n binding: ProsemirrorBinding;\n};\n\nexport type AiResponse = {\n type: \"insert\" | \"replace\" | \"other\";\n content: string;\n};\n"],"names":["ThreadPluginActions"],"mappings":";;AAWa,MAAA,sBAAA,GAAyB,IAAI,SAAA,CAAU,mBAAmB,EAAA;AAChE,MAAM,+BAA+B,IAAI,SAAA;AAAA,EAC9C,yBAAA;AACF,EAAA;AACO,MAAM,kCAAkC,IAAI,SAAA;AAAA,EACjD,0BAAA;AACF,EAAA;AACO,MAAM,uBAA0B,GAAA,oBAAA;AAEhC,MAAM,kCAAkC,IAAI,SAAA;AAAA,EACjD,oCAAA;AACF,EAAA;AACO,MAAM,qBAAqB,IAAI,SAAA;AAAA,EACpC,mBAAA;AACF,EAAA;AACO,MAAM,8BAA8B,IAAI,SAAA;AAAA,EAC7C,gCAAA;AACF,EAAA;AAEO,MAAM,4BAA+B,GAAA,wBAAA;AA2C1B,IAAA,mBAAA,qBAAAA,oBAAX,KAAA;AACL,EAAAA,qBAAA,wBAAyB,CAAA,GAAA,wBAAA,CAAA;AADT,EAAAA,OAAAA,oBAAAA,CAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;;;;"}
1
+ {"version":3,"file":"types.mjs","sources":["../src/types.ts"],"sourcesContent":["import type {\n ContextualPromptContext,\n ContextualPromptResponse,\n Relax,\n} from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { Content, Range } from \"@tiptap/core\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { DecorationSet } from \"@tiptap/pm/view\";\nimport type { ChainedCommands, SingleCommands } from \"@tiptap/react\";\nimport type { ProsemirrorBinding } from \"y-prosemirror\";\nimport type { Doc, PermanentUserData, Snapshot } from \"yjs\";\n\nexport const LIVEBLOCKS_MENTION_KEY = new PluginKey(\"lb-plugin-mention\");\nexport const LIVEBLOCKS_MENTION_PASTE_KEY = new PluginKey(\n \"lb-plugin-mention-paste\"\n);\nexport const LIVEBLOCKS_MENTION_NOTIFIER_KEY = new PluginKey(\n \"lb-plugin-mention-notify\"\n);\nexport const LIVEBLOCKS_MENTION_TYPE = \"liveblocksMention\";\n\nexport const THREADS_ACTIVE_SELECTION_PLUGIN = new PluginKey(\n \"lb-threads-active-selection-plugin\"\n);\nexport const THREADS_PLUGIN_KEY = new PluginKey<ThreadPluginState>(\n \"lb-threads-plugin\"\n);\nexport const AI_TOOLBAR_SELECTION_PLUGIN = new PluginKey(\n \"lb-ai-toolbar-selection-plugin\"\n);\n\nexport const LIVEBLOCKS_COMMENT_MARK_TYPE = \"liveblocksCommentMark\";\n\n/**\n * @beta\n */\nexport type ResolveContextualPromptArgs = {\n /**\n * The prompt being requested by the user.\n */\n prompt: string;\n\n /**\n * The context of the document and its current selection.\n */\n context: ContextualPromptContext;\n\n /**\n * The previous request and its response, if this is a follow-up request.\n */\n previous?: {\n prompt: string;\n response: ContextualPromptResponse;\n };\n\n /**\n * An abort signal that can be used to cancel requests.\n */\n signal: AbortSignal;\n};\n\n/**\n * @beta\n */\nexport type ResolveContextualPromptResponse = ContextualPromptResponse;\n\nexport interface AiConfiguration {\n /**\n * The AI's name. (\"Ask {name} anything…\", \"{name} is thinking…\", etc)\n */\n name?: string;\n\n /**\n * A function that returns an a response to a contextual prompt.\n */\n resolveContextualPrompt?: (\n args: ResolveContextualPromptArgs\n ) => Promise<ContextualPromptResponse>;\n}\n\nexport type LiveblocksExtensionOptions = {\n field?: string;\n comments?: boolean; // | CommentsConfiguration\n mentions?: boolean; // | MentionsConfiguration\n ai?: boolean | AiConfiguration;\n offlineSupport_experimental?: boolean;\n initialContent?: Content;\n};\n\nexport type LiveblocksExtensionStorage = {\n unsubs: (() => void)[];\n doc: Doc;\n provider: LiveblocksYjsProvider<any, any, any, any, any>;\n permanentUserData: PermanentUserData;\n};\n\nexport type CommentsExtensionStorage = {\n pendingComment: boolean;\n};\n\nexport const enum ThreadPluginActions {\n SET_SELECTED_THREAD_ID = \"SET_SELECTED_THREAD_ID\",\n}\n\nexport type AiExtensionOptions = Pick<\n AiConfiguration,\n \"name\" | \"resolveContextualPrompt\"\n> & {\n doc: Doc | undefined;\n pud: PermanentUserData | undefined;\n};\n\n/**\n * The state of the AI toolbar.\n *\n * ┌────────────────────────────────────────────────────────────────────────────────┐\n * │ │\n * │ ┌──────────────────────────────────────────────┐ │\n * ▼ ▼ │ │\n * ┌───────$closeAiToolbar()───────┐ │ │\n * ▼ ◇ ◇ ◇\n * ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐\n * │ CLOSED │ │ ASKING │ │ THINKING │ │ REVIEWING │\n * └───────────────────────┘ └───────────────────────┘ └───────────────────────┘ └───────────────────────┘\n * ▲ ◇ ◇ ▲ ▲ ◇ ▲ ▲ ◇ ▲ ◇ ◇\n * │ │ └───$openAiToolbarAsking()──┘ │ │ └ ─ ─ ─ ─ ─ ─⚠─ ─ ─ ─ ─ ─ ─│─├── ─ ─ ─ ─ ─ ─✓─ ─ ─ ─ ─ ─ ─ ┘ │ │\n * │ │ │ ▼ │ │ │ │\n * │ └─────────────────$startAiToolbarThinking(prompt)──────────────┘ │ │ │\n * │ │ ▲ │ │ │\n * │ │ └──────────────────────────────┼───────────────────────────────┘ │\n * │ │ │ │\n * │ └───$cancelAiToolbarThinking()───┘ │\n * │ │\n * └─────────────────────────────────────$acceptAiToolbarResponse()─────────────────────────────────────┘\n *\n */\nexport type AiToolbarState = Relax<\n | {\n phase: \"closed\";\n }\n | {\n phase: \"asking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * A potential error that occurred during the last AI request.\n */\n error?: Error;\n }\n | {\n phase: \"thinking\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * An abort controller to cancel the AI request.\n */\n abortController: AbortController;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The previous response if this \"thinking\" phase is a refinement.\n */\n previousResponse?: ContextualPromptResponse;\n }\n | {\n phase: \"reviewing\";\n\n /**\n * The selection stored when opening the AI toolbar.\n */\n initialSelection: Range;\n\n /**\n * The custom prompt being written in the toolbar.\n */\n customPrompt: string;\n\n /**\n * The prompt sent to the AI.\n */\n prompt: string;\n\n /**\n * The response of the AI request.\n */\n response: ContextualPromptResponse;\n }\n>;\n\nexport type AiExtensionStorage = {\n name: string;\n state: AiToolbarState;\n snapshot?: Snapshot;\n};\n\nexport type ThreadPluginState = {\n threadPositions: Map<string, { from: number; to: number }>;\n selectedThreadId: string | null;\n selectedThreadPos: number | null;\n decorations: DecorationSet;\n};\n\nexport type FloatingPosition = \"top\" | \"bottom\";\n\nexport type ExtendedCommands<\n T extends string,\n A extends any[] = [],\n> = SingleCommands & Record<T, (...args: A) => boolean>;\n\nexport type ExtendedChainedCommands<\n T extends string,\n A extends any[] = [],\n> = ChainedCommands & Record<T, (...args: A) => ChainedCommands>;\n\nexport type ChainedAiCommands = ChainedCommands & {\n [K in keyof AiCommands]: (\n ...args: Parameters<AiCommands[K]>\n ) => ChainedCommands;\n};\n\nexport type CommentsCommands<ReturnType = boolean> = {\n /**\n * Add a comment\n */\n addComment: (id: string) => ReturnType;\n selectThread: (id: string | null) => ReturnType;\n addPendingComment: () => ReturnType;\n\n /** @internal */\n closePendingComment: () => ReturnType;\n};\n\nexport type AiCommands<ReturnType = boolean> = {\n askAi: (prompt?: string) => ReturnType;\n\n // Transitions (see AiToolbarState)\n\n /**\n * @internal\n * @transition\n *\n * Close the AI toolbar.\n */\n $closeAiToolbar: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Accept the current AI response and close the AI toolbar.\n */\n $acceptAiToolbarResponse: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Open the AI toolbar in the \"asking\" phase.\n */\n $openAiToolbarAsking: () => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Set (and open if not already open) the AI toolbar in the \"thinking\" phase with the given prompt.\n */\n $startAiToolbarThinking: (\n prompt: string,\n withPreviousResponse?: boolean\n ) => ReturnType;\n\n /**\n * @internal\n * @transition\n *\n * Cancel the current \"thinking\" phase, going back to the \"asking\" phase.\n */\n $cancelAiToolbarThinking: () => ReturnType;\n\n // Other\n\n /**\n * @internal\n *\n * Show the diff of the current \"reviewing\" phase.\n */\n _showAiToolbarReviewingDiff: () => ReturnType;\n\n /**\n * @internal\n *\n * Handle the success of the current \"thinking\" phase.\n */\n _handleAiToolbarThinkingSuccess: (\n response: ContextualPromptResponse\n ) => ReturnType;\n\n /**\n * @internal\n *\n * Handle an error of the current \"thinking\" phase.\n */\n _handleAiToolbarThinkingError: (error: unknown) => ReturnType;\n\n /**\n * @internal\n *\n * Update the current custom AI prompt.\n */\n _updateAiToolbarCustomPrompt: (\n customPrompt: string | ((currentCustomPrompt: string) => string)\n ) => ReturnType;\n};\n\nexport type YSyncPluginState = {\n binding: ProsemirrorBinding;\n};\n"],"names":["ThreadPluginActions"],"mappings":";;AAaa,MAAA,sBAAA,GAAyB,IAAI,SAAA,CAAU,mBAAmB,EAAA;AAChE,MAAM,+BAA+B,IAAI,SAAA;AAAA,EAC9C,yBAAA;AACF,EAAA;AACO,MAAM,kCAAkC,IAAI,SAAA;AAAA,EACjD,0BAAA;AACF,EAAA;AACO,MAAM,uBAA0B,GAAA,oBAAA;AAEhC,MAAM,kCAAkC,IAAI,SAAA;AAAA,EACjD,oCAAA;AACF,EAAA;AACO,MAAM,qBAAqB,IAAI,SAAA;AAAA,EACpC,mBAAA;AACF,EAAA;AACO,MAAM,8BAA8B,IAAI,SAAA;AAAA,EAC7C,gCAAA;AACF,EAAA;AAEO,MAAM,4BAA+B,GAAA,wBAAA;AAqE1B,IAAA,mBAAA,qBAAAA,oBAAX,KAAA;AACL,EAAAA,qBAAA,wBAAyB,CAAA,GAAA,wBAAA,CAAA;AADT,EAAAA,OAAAA,oBAAAA,CAAAA;AAAA,CAAA,EAAA,mBAAA,IAAA,EAAA;;;;"}
package/dist/utils.js CHANGED
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var model = require('@tiptap/pm/model');
4
+ var state = require('@tiptap/pm/state');
4
5
  var yProsemirror = require('y-prosemirror');
5
6
  var types = require('./types.js');
6
7
 
8
+ const CONTEXT_TRUNCATION = "[\u2026]";
9
+ const CONTEXT_BLOCK_SEPARATOR = " ";
7
10
  const getRelativeSelectionFromState = (state) => {
8
11
  const pluginState = yProsemirror.ySyncPluginKey.getState(state);
9
12
  if (!pluginState)
@@ -58,13 +61,22 @@ const mapFragment = (fragment, callback) => {
58
61
  });
59
62
  return model.Fragment.from(content);
60
63
  };
61
- function getDomRange(editor, range) {
62
- const { from, to } = range;
63
- const fromPos = editor.view.domAtPos(from);
64
- const endPos = editor.view.domAtPos(to);
64
+ function getDomRangeFromSelection(editor, selection) {
65
+ if (selection.from === selection.to) {
66
+ const parentNode = selection.$from.parent;
67
+ if (parentNode.isBlock && parentNode.content.size === 0) {
68
+ selection = state.TextSelection.create(
69
+ editor.state.doc,
70
+ selection.$from.before(),
71
+ selection.$from.after()
72
+ );
73
+ }
74
+ }
75
+ const from = editor.view.domAtPos(selection.from);
76
+ const to = editor.view.domAtPos(selection.to);
65
77
  const domRange = document.createRange();
66
- domRange.setStart(fromPos.node, fromPos.offset);
67
- domRange.setEnd(endPos.node, endPos.offset);
78
+ domRange.setStart(from.node, from.offset);
79
+ domRange.setEnd(to.node, to.offset);
68
80
  return domRange;
69
81
  }
70
82
  function compareSelections(a, b) {
@@ -73,9 +85,7 @@ function compareSelections(a, b) {
73
85
  }
74
86
  return a.eq(b);
75
87
  }
76
- const DOCUMENT_TEXT_TRUNCATION = "[\u2026]";
77
- const DOCUMENT_TEXT_BLOCK_SEPARATOR = " ";
78
- function getDocumentText(editor, maxLength = 1e4) {
88
+ function getContextualPromptContext(editor, maxLength = 1e4) {
79
89
  const { selection, doc } = editor.state;
80
90
  const selectionLength = selection.to - selection.from;
81
91
  if (maxLength >= doc.content.size) {
@@ -83,33 +93,33 @@ function getDocumentText(editor, maxLength = 1e4) {
83
93
  beforeSelection: doc.textBetween(
84
94
  0,
85
95
  selection.from,
86
- DOCUMENT_TEXT_BLOCK_SEPARATOR
96
+ CONTEXT_BLOCK_SEPARATOR
87
97
  ),
88
98
  selection: doc.textBetween(
89
99
  selection.from,
90
100
  selection.to,
91
- DOCUMENT_TEXT_BLOCK_SEPARATOR
101
+ CONTEXT_BLOCK_SEPARATOR
92
102
  ),
93
103
  afterSelection: doc.textBetween(
94
104
  selection.to,
95
105
  doc.content.size,
96
- DOCUMENT_TEXT_BLOCK_SEPARATOR
106
+ CONTEXT_BLOCK_SEPARATOR
97
107
  )
98
108
  };
99
109
  } else if (selectionLength > maxLength) {
100
110
  const selectionStart = doc.textBetween(
101
111
  selection.from,
102
- selection.from + Math.floor(maxLength / 2) - DOCUMENT_TEXT_TRUNCATION.length,
103
- DOCUMENT_TEXT_BLOCK_SEPARATOR
112
+ selection.from + Math.floor(maxLength / 2) - CONTEXT_TRUNCATION.length,
113
+ CONTEXT_BLOCK_SEPARATOR
104
114
  );
105
115
  const selectionEnd = doc.textBetween(
106
- selection.to - Math.floor(maxLength / 2) + DOCUMENT_TEXT_TRUNCATION.length,
116
+ selection.to - Math.floor(maxLength / 2) + CONTEXT_TRUNCATION.length,
107
117
  selection.to,
108
- DOCUMENT_TEXT_BLOCK_SEPARATOR
118
+ CONTEXT_BLOCK_SEPARATOR
109
119
  );
110
120
  return {
111
121
  beforeSelection: "",
112
- selection: `${selectionStart}${DOCUMENT_TEXT_TRUNCATION}${selectionEnd}`,
122
+ selection: `${selectionStart}${CONTEXT_TRUNCATION}${selectionEnd}`,
113
123
  afterSelection: ""
114
124
  };
115
125
  } else {
@@ -130,25 +140,25 @@ function getDocumentText(editor, maxLength = 1e4) {
130
140
  let beforeSelection = doc.textBetween(
131
141
  Math.max(0, selection.from - beforeLength),
132
142
  selection.from,
133
- DOCUMENT_TEXT_BLOCK_SEPARATOR
143
+ CONTEXT_BLOCK_SEPARATOR
134
144
  );
135
145
  let afterSelection = doc.textBetween(
136
146
  selection.to,
137
147
  Math.min(doc.content.size, selection.to + afterLength),
138
- DOCUMENT_TEXT_BLOCK_SEPARATOR
148
+ CONTEXT_BLOCK_SEPARATOR
139
149
  );
140
150
  if (selection.from - beforeLength > 0) {
141
- beforeSelection = `${DOCUMENT_TEXT_TRUNCATION}${beforeSelection}`;
151
+ beforeSelection = `${CONTEXT_TRUNCATION}${beforeSelection}`;
142
152
  }
143
153
  if (selection.to + afterLength < doc.content.size) {
144
- afterSelection = `${afterSelection}${DOCUMENT_TEXT_TRUNCATION}`;
154
+ afterSelection = `${afterSelection}${CONTEXT_TRUNCATION}`;
145
155
  }
146
156
  return {
147
157
  beforeSelection,
148
158
  selection: doc.textBetween(
149
159
  selection.from,
150
160
  selection.to,
151
- DOCUMENT_TEXT_BLOCK_SEPARATOR
161
+ CONTEXT_BLOCK_SEPARATOR
152
162
  ),
153
163
  afterSelection
154
164
  };
@@ -156,8 +166,8 @@ function getDocumentText(editor, maxLength = 1e4) {
156
166
  }
157
167
 
158
168
  exports.compareSelections = compareSelections;
159
- exports.getDocumentText = getDocumentText;
160
- exports.getDomRange = getDomRange;
169
+ exports.getContextualPromptContext = getContextualPromptContext;
170
+ exports.getDomRangeFromSelection = getDomRangeFromSelection;
161
171
  exports.getMentionsFromNode = getMentionsFromNode;
162
172
  exports.getRangeFromRelativeSelections = getRangeFromRelativeSelections;
163
173
  exports.getRectFromCoords = getRectFromCoords;