diff --git a/docs/package.json b/docs/package.json index 24f5f3e410..18b6792b6f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -55,7 +55,7 @@ "@shikijs/langs-precompiled": "^4", "@shikijs/themes": "^4", "@shikijs/types": "^4", - "@tiptap/core": "^3.13.0", + "@tiptap/core": "^3.29.2", "@uppy/core": "^3.13.1", "@uppy/dashboard": "^3.9.1", "@uppy/drag-drop": "^3.1.1", diff --git a/examples/08-extensions/01-tiptap-arrow-conversion/package.json b/examples/08-extensions/01-tiptap-arrow-conversion/package.json index 84bd386a13..e2e2ce414d 100644 --- a/examples/08-extensions/01-tiptap-arrow-conversion/package.json +++ b/examples/08-extensions/01-tiptap-arrow-conversion/package.json @@ -20,7 +20,7 @@ "@mantine/hooks": "^9.0.2", "react": "^19.2.3", "react-dom": "^19.2.3", - "@tiptap/core": "^3.13.0" + "@tiptap/core": "^3.29.2" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/package.json b/package.json index 2012524d6a..c6a2b830cd 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,8 @@ "@ai-sdk/react": "3.0.5", "@ai-sdk/gateway": "3.0.4", "@headlessui/react": "^2.2.4", - "@tiptap/core": "^3.0.0", - "@tiptap/pm": "^3.0.0" + "@tiptap/core": "^3.29.2", + "@tiptap/pm": "^3.29.2" }, "workspaces": [ "packages/*", diff --git a/packages/core/package.json b/packages/core/package.json index 80535a0cb8..11e9d02eef 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -98,24 +98,24 @@ "@handlewithcare/prosemirror-inputrules": "^0.1.4", "@shikijs/types": "^4", "@tanstack/store": "^0.7.7", - "@tiptap/core": "^3.13.0", - "@tiptap/extension-bold": "^3.13.0", - "@tiptap/extension-code": "^3.13.0", - "@tiptap/extension-italic": "^3.13.0", - "@tiptap/extension-strike": "^3.13.0", - "@tiptap/extension-text": "^3.13.0", - "@tiptap/extension-underline": "^3.13.0", - "@tiptap/extensions": "^3.13.0", - "@tiptap/pm": "^3.13.0", + "@tiptap/core": "^3.29.2", + "@tiptap/extension-bold": "^3.29.2", + "@tiptap/extension-code": "^3.29.2", + "@tiptap/extension-italic": "^3.29.2", + "@tiptap/extension-strike": "^3.29.2", + "@tiptap/extension-text": "^3.29.2", + "@tiptap/extension-underline": "^3.29.2", + "@tiptap/extensions": "^3.29.2", + "@tiptap/pm": "^3.29.2", "emoji-mart": "^5.6.0", "fast-deep-equal": "^3.1.3", "lib0": "1.0.0-rc.22", "prosemirror-highlight": "^0.15.1", - "prosemirror-model": "^1.25.4", + "prosemirror-model": "^1.25.11", "prosemirror-state": "^1.4.4", - "prosemirror-tables": "^1.8.3", - "prosemirror-transform": "^1.11.0", - "prosemirror-view": "^1.41.4" + "prosemirror-tables": "^1.8.5", + "prosemirror-transform": "^1.12.0", + "prosemirror-view": "^1.41.9" }, "devDependencies": { "jsdom": "^29.0.2", diff --git a/packages/core/src/schema/blocks/createSpec.ts b/packages/core/src/schema/blocks/createSpec.ts index faf0d35292..5db7ff48eb 100644 --- a/packages/core/src/schema/blocks/createSpec.ts +++ b/packages/core/src/schema/blocks/createSpec.ts @@ -15,7 +15,7 @@ import { import { nonFormattingMarks } from "../markGroups.js"; import { PropSchema } from "../propTypes.js"; import { - getBlockFromPos, + getBlockFromNodeView, propsToAttributes, wrapInBlockStructure, } from "./internal.js"; @@ -247,8 +247,15 @@ export function addNodeAndExtensionsToSpec< return (props) => { // Gets the BlockNote editor instance const editor = this.options.editor; - // Gets the block - const block = getBlockFromPos(props.getPos, props.view.state.doc); + // Gets the block. Resolving this can't rely on `getPos()` alone — + // node views are constructed part-way through ProseMirror's + // reconciliation, where positions don't always line up with + // `view.state.doc` yet (see `getBlockFromNodeView`). + const block = getBlockFromNodeView( + props.getPos, + props.node, + props.view.state.doc, + ); // Gets the custom HTML attributes for `blockContent` nodes const blockContentDOMAttributes = this.options.domAttributes?.blockContent || {}; diff --git a/packages/core/src/schema/blocks/internal.test.ts b/packages/core/src/schema/blocks/internal.test.ts new file mode 100644 index 0000000000..809a314ed7 --- /dev/null +++ b/packages/core/src/schema/blocks/internal.test.ts @@ -0,0 +1,86 @@ +import { afterEach, beforeEach, describe, expect, it } from "vite-plus/test"; + +import { getNodeById } from "../../api/nodeUtil.js"; +import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js"; +import { getBlockFromNodeView } from "./internal.js"; + +describe("getBlockFromNodeView", () => { + let editor: BlockNoteEditor; + + beforeEach(() => { + editor = BlockNoteEditor.create({ + trailingBlock: false, + initialContent: [ + { type: "paragraph", content: "first" }, + { type: "paragraph", content: "second" }, + ], + }); + }); + + afterEach(() => { + // Leaving the editor alive leaks a ProseMirror `DOMObserver`, whose + // `stop()` schedules a `flush()` 20ms later. That can outlive the test + // environment and then fail the run with `ReferenceError: document is not + // defined`, attributed to whichever test file happens to be running. + editor._tiptapEditor.destroy(); + editor = undefined as any; + }); + + it("resolves from the position when it is valid", () => { + const doc = editor.prosemirrorState.doc; + const target = editor.document[1]; + // `getBlockFromPos` resolves the *parent* of the position, so the position + // sits just inside the block container — which is what ProseMirror hands a + // node view. + const pos = getNodeById(target.id, doc)!.posBeforeNode + 1; + const block = getBlockFromNodeView(() => pos, doc.nodeAt(pos)!, doc) as any; + + expect(block.id).toBe(target.id); + }); + + it("builds a standalone block when the node is no longer in the document", () => { + // The only way `getPos()` fails at node view construction is a re-entrant + // dispatch superseding `view.state.doc`, which takes the node with it — so + // the node genuinely isn't in the document any more. See #2937. + const doc = editor.prosemirrorState.doc; + const orphan = editor.pmSchema.nodes.paragraph.create( + { textAlignment: "right" }, + editor.pmSchema.text("orphaned content"), + ); + const block = getBlockFromNodeView( + () => doc.content.size + 1000, + orphan, + doc, + ) as any; + + // Everything readable off the node is correct... + expect(block.type).toBe("paragraph"); + expect(block.props.textAlignment).toBe("right"); + expect(block.content[0].text).toBe("orphaned content"); + // ...but the id belongs to no block in the document, so it must not + // collide with a real one. + expect(editor.document.map((b) => b.id)).not.toContain(block.id); + }); + + it("recovers from an in-range position that resolves to the wrong node", () => { + // Position 0 resolves to the doc rather than a block container — the shape + // a bounds check alone would not catch. + const doc = editor.prosemirrorState.doc; + const orphan = editor.pmSchema.nodes.paragraph.create( + null, + editor.pmSchema.text("orphaned content"), + ); + expect(() => getBlockFromNodeView(() => 0, orphan, doc)).not.toThrow(); + }); + + it("recovers when the position is undefined", () => { + const doc = editor.prosemirrorState.doc; + const orphan = editor.pmSchema.nodes.paragraph.create( + null, + editor.pmSchema.text("orphaned content"), + ); + expect(() => + getBlockFromNodeView(() => undefined, orphan, doc), + ).not.toThrow(); + }); +}); diff --git a/packages/core/src/schema/blocks/internal.ts b/packages/core/src/schema/blocks/internal.ts index 4f5a7941a9..cfd17b9d11 100644 --- a/packages/core/src/schema/blocks/internal.ts +++ b/packages/core/src/schema/blocks/internal.ts @@ -93,6 +93,70 @@ export function getBlockFromPos(getPos: () => number | undefined, doc: PMNode) { return block; } +/** + * Resolves the block a node view should render, tolerating a `getPos()` that + * can't be trusted. + * + * ProseMirror derives `getPos()` from its view-desc tree, but + * `EditorView.updateStateInner` assigns the new state *before* it reconciles + * that tree. Anything that runs partway through reconciliation - a re-entrant + * dispatch from a node view's effect, TipTap's `flushSync` while mounting a + * node view - therefore sees positions that no longer line up with + * `view.state.doc`. The position then either lands out of range or, just as + * bad, in range but pointing at the wrong node. + * + * Node views are constructed inside that same window, so this applies at + * construction just as much as on re-render. The state is always transient: + * ProseMirror finishes reconciling and rebuilds the node view against the + * current document immediately after. So we degrade instead of throwing, + * because a stale frame is invisible where a throw is not. + * + * See issues #2937, #2682 and #2621. + */ +export function getBlockFromNodeView( + getPos: () => number | undefined, + node: PMNode, + doc: PMNode, +) { + try { + return getBlockFromPos(getPos, doc); + } catch (e) { + // Failing here means the node is not in `doc` — a re-entrant dispatch + // superseded the document ProseMirror is building node views for, and the + // node went with it. So there is no container to read an id from, and the + // block has to be built from the node alone. Deliberately silent: this is + // expected and self-correcting, and there is nothing a consumer could do + // about it in the meantime. + // + // `type`, `props` and `content` are read off the node and are correct. + // `children` is empty and `id` is freshly generated, i.e. it belongs to no + // block in the document — callers must not treat it as addressable. (It + // can't collide with a real block: ids are uuids, and the deterministic + // test-mode generator shares one monotonic counter with real ids.) This is + // short-lived; ProseMirror rebuilds the node view against the real document + // right after. + // + // The alternatives are worse. Throwing is the crash this exists to prevent. + // Returning an empty placeholder node view can leave the block + // *permanently* blank, since vanilla node views don't implement `update()` + // and so are only rebuilt when something else changes the document. + // + // `createAndFill` rather than `create` so an unexpected node shape yields + // `null` instead of throwing over the top of the original failure. + const standalone = doc.type.schema.nodes["blockContainer"]?.createAndFill( + null, + node, + ); + if (standalone) { + return nodeToBlock(standalone, doc); + } + + // Nothing left to render from. Surface the original failure rather than + // inventing a block that isn't grounded in anything. + throw e; + } +} + // Function that wraps the `dom` element returned from 'blockConfig.render' in a // `blockContent` div, which contains the block type and props as HTML // attributes. If `blockConfig.render` also returns a `contentDOM`, it also adds diff --git a/packages/react/package.json b/packages/react/package.json index da4c0a6e69..7ad41c87db 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -61,9 +61,9 @@ "@emoji-mart/data": "^1.2.1", "@floating-ui/react": "^0.27.18", "@tanstack/react-store": "0.7.7", - "@tiptap/core": "^3.13.0", - "@tiptap/pm": "^3.13.0", - "@tiptap/react": "^3.13.0", + "@tiptap/core": "^3.29.2", + "@tiptap/pm": "^3.29.2", + "@tiptap/react": "^3.29.2", "emoji-mart": "^5.6.0", "fast-deep-equal": "^3.1.3", "use-sync-external-store": "1.6.0" diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index bae514dc94..2259babd84 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -139,6 +139,7 @@ export * from "./hooks/useEditorState.js"; export * from "./schema/ReactBlockSpec.js"; export * from "./schema/ReactInlineContentSpec.js"; export * from "./schema/ReactStyleSpec.js"; +export * from "./schema/useNodeViewBlock.js"; export * from "./icons.js"; diff --git a/packages/react/src/schema/ReactBlockSpec.tsx b/packages/react/src/schema/ReactBlockSpec.tsx index fb0e767d8f..4bd1649292 100644 --- a/packages/react/src/schema/ReactBlockSpec.tsx +++ b/packages/react/src/schema/ReactBlockSpec.tsx @@ -10,7 +10,6 @@ import { Extension, ExtensionFactoryInstance, ExtractBlockConfigFromConfigOrCreator, - getBlockFromPos, mergeCSSClasses, Props, PropSchema, @@ -23,6 +22,7 @@ import { } from "@tiptap/react"; import { FC, ReactNode } from "react"; import { renderToDOMSpec } from "./@util/ReactRenderUtil.js"; +import { useNodeViewBlock } from "./useNodeViewBlock.js"; // this file is mostly analogoues to `customBlocks.ts`, but for React blocks @@ -267,17 +267,20 @@ export function createReactBlockSpec< }, render(block, editor) { if (this.renderType === "nodeView") { + // The block core's `addNodeView` resolved when this node view was + // constructed (itself guarded, via `getBlockFromNodeView`). Seeds + // the fallback below so there is always something to render. + const initialBlock = block; + return ReactNodeViewRenderer( (props: NodeViewProps) => { // Vanilla JS node views are recreated on each update. However, // using `ReactNodeViewRenderer` makes it so the node view is // only created once, so the block we get in the node view will // be outdated. Therefore, we have to get the block in the - // `ReactNodeViewRenderer` instead. - const block = getBlockFromPos( - props.getPos, - props.view.state.doc, - ); + // `ReactNodeViewRenderer` instead. That position can be stale, + // so resolving it is guarded (see `useNodeViewBlock`). + const block = useNodeViewBlock(props, initialBlock); const ref = useReactNodeView().nodeViewContentRef; diff --git a/packages/react/src/schema/useNodeViewBlock.ts b/packages/react/src/schema/useNodeViewBlock.ts new file mode 100644 index 0000000000..02393a2fd0 --- /dev/null +++ b/packages/react/src/schema/useNodeViewBlock.ts @@ -0,0 +1,57 @@ +import { Block, getBlockFromPos } from "@blocknote/core"; +import type { NodeViewProps } from "@tiptap/react"; +import { useRef } from "react"; + +/** + * Resolves the `Block` that a React node view should render. + * + * A node view's `getPos()` is not always usable. ProseMirror computes it by + * walking the view-desc tree, but `EditorView.updateStateInner` assigns the new + * state *before* it reconciles that tree, so any render that happens partway + * through reconciliation sees positions computed against a half-updated tree + * while `view.state.doc` is already the new document. React node views get + * rendered in exactly that window: TipTap's `ReactRenderer` calls `flushSync` + * while mounting a node view, and anything that runs from the resulting commit + * (a layout effect, a re-entrant dispatch, another node view's pending update) + * renders with a position that no longer matches the document. `getPos()` can + * also return `undefined` outright once a desc has been detached. + * + * The resulting position is either out of range (`RangeError: Position N out of + * range`) or in range but pointing at the wrong node (`Node should be a + * bnBlock, but is instead: doc`) — both thrown out of the render path, which + * under React 19 tears down the consumer's tree rather than being rethrown. + * + * Upstream considers this TipTap's problem (ProseMirror/prosemirror#1532) and + * TipTap considers `flushSync` unavoidable, so we recover here instead, by + * reusing the last block we rendered. The bad position is always transient — + * ProseMirror finishes reconciling and re-renders the node view with a valid + * one immediately after — so a stale frame is invisible, whereas a throw is + * not. + * + * See BlockNote issues #2937, #2682 and #2621. + */ +export function useNodeViewBlock( + props: NodeViewProps, + /** + * The block core's `addNodeView` resolved when the node view was constructed + * — via `getBlockFromNodeView`, so it is already guarded against the same + * problem. Seeds the fallback so there is always a block to render. + */ + initialBlock: Block, +): Block { + const lastBlockRef = useRef(initialBlock); + const doc = props.view.state.doc; + + try { + // Deliberate render-phase write: a monotonic "last good value" cache, so a + // repeated render (e.g. StrictMode's double invoke) recomputes the same + // thing. + lastBlockRef.current = getBlockFromPos(props.getPos, doc); + } catch { + // Expected and self-correcting, so deliberately silent: ProseMirror + // re-renders the node view with a usable position immediately after, and + // there is nothing a consumer could do about it in the meantime. + } + + return lastBlockRef.current; +} diff --git a/packages/server-util/package.json b/packages/server-util/package.json index c7e60dd042..bd6fe5a23a 100644 --- a/packages/server-util/package.json +++ b/packages/server-util/package.json @@ -58,7 +58,7 @@ "dependencies": { "@blocknote/core": "workspace:^", "@blocknote/react": "workspace:^", - "@tiptap/pm": "^3.13.0", + "@tiptap/pm": "^3.29.2", "jsdom": "^25.0.1", "yjs": "^13.6.27" }, diff --git a/packages/xl-ai/package.json b/packages/xl-ai/package.json index 543cda210d..f9ed498783 100644 --- a/packages/xl-ai/package.json +++ b/packages/xl-ai/package.json @@ -74,16 +74,16 @@ "@blocknote/react": "workspace:^", "@floating-ui/react": "^0.27.18", "@handlewithcare/prosemirror-suggest-changes": "^0.1.8", - "@tiptap/core": "^3.13.0", + "@tiptap/core": "^3.29.2", "ai": "^6.0.5", "lodash.isequal": "^4.5.0", "lodash.merge": "^4.6.2", - "prosemirror-changeset": "^2.3.1", - "prosemirror-model": "^1.25.4", + "prosemirror-changeset": "^2.4.1", + "prosemirror-model": "^1.25.11", "prosemirror-state": "^1.4.4", - "prosemirror-tables": "^1.8.3", - "prosemirror-transform": "^1.11.0", - "prosemirror-view": "^1.41.4" + "prosemirror-tables": "^1.8.5", + "prosemirror-transform": "^1.12.0", + "prosemirror-view": "^1.41.9" }, "devDependencies": { "@blocknote/shared": "workspace:^", diff --git a/packages/xl-multi-column/package.json b/packages/xl-multi-column/package.json index 008ce36e0a..bf7e343256 100644 --- a/packages/xl-multi-column/package.json +++ b/packages/xl-multi-column/package.json @@ -52,10 +52,10 @@ "dependencies": { "@blocknote/core": "workspace:^", "@blocknote/react": "workspace:^", - "@tiptap/core": "^3.13.0", - "prosemirror-model": "^1.25.4", + "@tiptap/core": "^3.29.2", + "prosemirror-model": "^1.25.11", "prosemirror-state": "^1.4.4", - "prosemirror-view": "^1.41.4" + "prosemirror-view": "^1.41.9" }, "devDependencies": { "@blocknote/shared": "workspace:^", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 090c217f93..1a530aa87b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ catalogs: overrides: '@headlessui/react': ^2.2.4 - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 vitest: 4.1.7 '@vitest/runner': 4.1.7 '@y/y': 14.0.0-rc.23 @@ -128,10 +128,10 @@ importers: version: 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) '@liveblocks/react-blocknote': specifier: ^3.19.5 - version: 3.19.5(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 3.19.5(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) '@liveblocks/react-tiptap': specifier: ^3.19.5 - version: 3.19.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 3.19.5(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) '@liveblocks/react-ui': specifier: ^3.19.5 version: 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -187,8 +187,8 @@ importers: specifier: ^4 version: 4.0.2 '@tiptap/core': - specifier: ^3.0.0 - version: 3.22.4(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/pm@3.29.2) '@uppy/core': specifier: ^3.13.1 version: 3.13.1 @@ -230,7 +230,7 @@ importers: version: 0.6.4(react@19.2.5)(yjs@13.6.30) '@y/prosemirror': specifier: 2.0.0-6 - version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) + version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2) '@y/protocols': specifier: ^1.0.6-rc.1 version: 1.0.6-rc.1(@y/y@14.0.0-rc.23) @@ -3639,10 +3639,10 @@ importers: version: 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) '@liveblocks/react-blocknote': specifier: ^3.19.5 - version: 3.19.5(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 3.19.5(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) '@liveblocks/react-tiptap': specifier: ^3.19.5 - version: 3.19.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 3.19.5(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) '@liveblocks/react-ui': specifier: ^3.19.5 version: 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -4028,7 +4028,7 @@ importers: version: 9.1.1(react@19.2.5) '@y/prosemirror': specifier: 2.0.0-6 - version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) + version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2) '@y/protocols': specifier: ^1.0.6-rc.1 version: 1.0.6-rc.1(@y/y@14.0.0-rc.23) @@ -4190,7 +4190,7 @@ importers: version: 9.1.1(react@19.2.5) '@y/prosemirror': specifier: 2.0.0-6 - version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) + version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2) '@y/protocols': specifier: ^1.0.6-rc.1 version: 1.0.6-rc.1(@y/y@14.0.0-rc.23) @@ -4302,8 +4302,8 @@ importers: specifier: ^9.0.2 version: 9.1.1(react@19.2.5) '@tiptap/core': - specifier: ^3.0.0 - version: 3.22.4(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/pm@3.29.2) react: specifier: ^19.2.3 version: 19.2.5 @@ -4349,7 +4349,7 @@ importers: version: 9.1.1(react@19.2.5) '@y/prosemirror': specifier: 2.0.0-6 - version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) + version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2) '@y/y': specifier: 14.0.0-rc.23 version: 14.0.0-rc.23 @@ -4948,7 +4948,7 @@ importers: version: 1.2.1 '@handlewithcare/prosemirror-inputrules': specifier: ^0.1.4 - version: 0.1.4(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) + version: 0.1.4(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2) '@shikijs/types': specifier: ^4 version: 4.0.2 @@ -4956,35 +4956,35 @@ importers: specifier: ^0.7.7 version: 0.7.7 '@tiptap/core': - specifier: ^3.0.0 - version: 3.22.4(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/pm@3.29.2) '@tiptap/extension-bold': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4)) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) '@tiptap/extension-code': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4)) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) '@tiptap/extension-italic': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4)) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) '@tiptap/extension-strike': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4)) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) '@tiptap/extension-text': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4)) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) '@tiptap/extension-underline': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4)) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) '@tiptap/extensions': - specifier: ^3.13.0 - version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) '@tiptap/pm': - specifier: ^3.0.0 - version: 3.22.4 + specifier: ^3.29.2 + version: 3.29.2 '@y/prosemirror': specifier: 2.0.0-6 - version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) + version: 2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2) '@y/protocols': specifier: ^1.0.6-rc.1 version: 1.0.6-rc.1(@y/y@14.0.0-rc.23) @@ -5002,22 +5002,22 @@ importers: version: 1.0.0-rc.22 prosemirror-highlight: specifier: ^0.15.1 - version: 0.15.1(@shikijs/types@4.0.2)(@types/hast@3.0.4)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8) + version: 0.15.1(@shikijs/types@4.0.2)(@types/hast@3.0.4)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.42.2) prosemirror-model: - specifier: ^1.25.4 - version: 1.25.4 + specifier: ^1.25.11 + version: 1.25.11 prosemirror-state: specifier: ^1.4.4 version: 1.4.4 prosemirror-tables: - specifier: ^1.8.3 + specifier: ^1.8.5 version: 1.8.5 prosemirror-transform: - specifier: ^1.11.0 + specifier: ^1.12.0 version: 1.12.0 prosemirror-view: - specifier: ^1.41.4 - version: 1.41.8 + specifier: ^1.41.9 + version: 1.42.2 devDependencies: jsdom: specifier: ^29.0.2 @@ -5036,7 +5036,7 @@ importers: version: 0.1.24(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.1.0))(terser@5.46.2)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) y-prosemirror: specifier: ^1.3.7 - version: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 1.3.7(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) y-protocols: specifier: ^1.0.6 version: 1.0.7(yjs@13.6.30) @@ -5141,14 +5141,14 @@ importers: specifier: 0.7.7 version: 0.7.7(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tiptap/core': - specifier: ^3.0.0 - version: 3.22.4(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/pm@3.29.2) '@tiptap/pm': - specifier: ^3.0.0 - version: 3.22.4 + specifier: ^3.29.2 + version: 3.29.2 '@tiptap/react': - specifier: ^3.13.0 - version: 3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + specifier: ^3.29.2 + version: 3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) emoji-mart: specifier: ^5.6.0 version: 5.6.0 @@ -5212,8 +5212,8 @@ importers: specifier: workspace:^ version: link:../react '@tiptap/pm': - specifier: ^3.0.0 - version: 3.22.4 + specifier: ^3.29.2 + version: 3.29.2 jsdom: specifier: ^25.0.1 version: 25.0.1(canvas@2.11.2) @@ -5250,7 +5250,7 @@ importers: version: 0.1.24(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(jsdom@25.0.1(canvas@2.11.2))(terser@5.46.2)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0))(yaml@2.9.0) y-prosemirror: specifier: ^1.3.7 - version: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 1.3.7(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) y-protocols: specifier: ^1.0.6 version: 1.0.7(yjs@13.6.30) @@ -5365,10 +5365,10 @@ importers: version: 0.27.19(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@handlewithcare/prosemirror-suggest-changes': specifier: ^0.1.8 - version: 0.1.8(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8) + version: 0.1.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.42.2) '@tiptap/core': - specifier: ^3.0.0 - version: 3.22.4(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/pm@3.29.2) ai: specifier: ^6.0.5 version: 6.0.5(zod@4.3.6) @@ -5379,23 +5379,23 @@ importers: specifier: ^4.6.2 version: 4.6.2 prosemirror-changeset: - specifier: ^2.3.1 + specifier: ^2.4.1 version: 2.4.1 prosemirror-model: - specifier: ^1.25.4 - version: 1.25.4 + specifier: ^1.25.11 + version: 1.25.11 prosemirror-state: specifier: ^1.4.4 version: 1.4.4 prosemirror-tables: - specifier: ^1.8.3 + specifier: ^1.8.5 version: 1.8.5 prosemirror-transform: - specifier: ^1.11.0 + specifier: ^1.12.0 version: 1.12.0 prosemirror-view: - specifier: ^1.41.4 - version: 1.41.8 + specifier: ^1.41.9 + version: 1.42.2 react: specifier: ^18.0 || ^19.0 || >= 19.0.0-rc version: 19.2.5 @@ -5659,17 +5659,17 @@ importers: specifier: workspace:^ version: link:../react '@tiptap/core': - specifier: ^3.0.0 - version: 3.22.4(@tiptap/pm@3.22.4) + specifier: ^3.29.2 + version: 3.29.2(@tiptap/pm@3.29.2) prosemirror-model: - specifier: ^1.25.4 - version: 1.25.4 + specifier: ^1.25.11 + version: 1.25.11 prosemirror-state: specifier: ^1.4.4 version: 1.4.4 prosemirror-view: - specifier: ^1.41.4 - version: 1.41.8 + specifier: ^1.41.9 + version: 1.42.2 devDependencies: '@blocknote/shared': specifier: workspace:^ @@ -5879,10 +5879,10 @@ importers: version: 3.17.0(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) '@liveblocks/react-blocknote': specifier: ^3.17.0 - version: 3.17.0(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + version: 3.17.0(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) '@liveblocks/react-tiptap': specifier: ^3.17.0 - version: 3.17.0(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30)) + version: 3.17.0(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30)) '@liveblocks/react-ui': specifier: ^3.17.0 version: 3.17.0(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -6040,8 +6040,8 @@ importers: specifier: ^4.1.14 version: 4.2.2(vite@8.0.8(@types/node@20.19.37)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0)) '@tiptap/pm': - specifier: ^3.0.0 - version: 3.22.4 + specifier: ^3.29.2 + version: 3.29.2 '@types/node': specifier: ^20.19.22 version: 20.19.37 @@ -7362,7 +7362,7 @@ packages: peerDependencies: '@blocknote/core': 0.43.0 - 1.0.0 '@blocknote/react': 0.43.0 - 1.0.0 - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 '@types/react': '*' '@types/react-dom': '*' react: ^18 || ^19 || ^19.0.0-rc @@ -7378,7 +7378,7 @@ packages: peerDependencies: '@blocknote/core': '>=0.43' '@blocknote/react': '>=0.43' - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 '@types/react': ^18 || ^19 '@types/react-dom': ^18 || ^19 react: ^18 || ^19 || ^19.0.0-rc @@ -7392,7 +7392,7 @@ packages: '@liveblocks/react-tiptap@3.17.0': resolution: {integrity: sha512-IVAN5sZCOTtGy8alKw4EpArikBLu/dwjvbNya5IaH3ZiO6eoYmPFbHxinVN08BKPe208YjhZWefwrFr7bKAVNw==} peerDependencies: - '@tiptap/pm': ^3.0.0 + '@tiptap/pm': ^3.29.2 '@tiptap/react': ^3.19.0 '@tiptap/suggestion': ^3.19.0 '@types/react': '*' @@ -7408,8 +7408,8 @@ packages: '@liveblocks/react-tiptap@3.19.5': resolution: {integrity: sha512-XRafUZ/usOpAZNdC0kbvWga+tjGb4CyAi8j5XBKM38KWhh7sMhA0lpk3P8jjS9zBrl+NlApJym0NledF8LBRGw==} peerDependencies: - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 '@tiptap/react': ^3 '@tiptap/suggestion': ^3 '@types/react': ^18 || ^19 @@ -10116,68 +10116,68 @@ packages: '@types/react-dom': optional: true - '@tiptap/core@3.22.4': - resolution: {integrity: sha512-vGIGm/HpqLg8EAAQXQ+koV+/S828OEpzocfWcPOwo1u2QUVf9dQG47Yy6JJ8zFFaJwfv4dBcOXli+7BrJwsxDQ==} + '@tiptap/core@3.29.2': + resolution: {integrity: sha512-oKUkiPUB7noilVYxI9lNzUD4rX17sHub+PYjMfHMWHG9A3nvIy+FdePIVIIhThKWF7ijhr3eIqHY51Bn+GAFtw==} peerDependencies: - '@tiptap/pm': ^3.0.0 + '@tiptap/pm': ^3.29.2 - '@tiptap/extension-bold@3.22.4': - resolution: {integrity: sha512-jIaPKfNOQu2lhpbLDvtwlQqM+mjF+Kk+auHpzYjBnsuwUli1Cl5ZOau7RH+rru/SQvZe1DtpQlANujDywugZAA==} + '@tiptap/extension-bold@3.29.2': + resolution: {integrity: sha512-elYbGxJsYnBb4leqrcjdIJuiG380BcOgN+UUzvOv+qEjfGVzHodFOMBl3qnmD6urYHNu5/qQK2S0qSSRXKCLNQ==} peerDependencies: - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 - '@tiptap/extension-bubble-menu@3.22.4': - resolution: {integrity: sha512-v4pux5Ql3THAEjaLMY4ldtdy/Xy2qU7PJLBkq8ugLp8qicaKC+tpqxp6sGif4vLIjz7Ap5hurRbTNbXzszyyHA==} + '@tiptap/extension-bubble-menu@3.29.2': + resolution: {integrity: sha512-kzcWarcpr031rZu+R3Hzut5uxb3Qj/xxMDEYZIQ3uiq1yb5vEMXj8/SIyWautk6Nu8Rr1leV3rGdR4NzhzyFAA==} peerDependencies: - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 - '@tiptap/extension-code@3.22.4': - resolution: {integrity: sha512-cnbxmVhAcc7X3G81QUYEmKP0ve2hRmvAiFXBuuv9RUtQlBiRnzmhHoJOMgkX0CsMR7+8kMRpTfeDUYq2xp5s5w==} + '@tiptap/extension-code@3.29.2': + resolution: {integrity: sha512-c6W5UGuB7WNLpYocsgRzpO2OOTI4QjaI9jjHRMuty9z+s9DtaYM/HrRLNwVh6MopkHb+i/89Wkv8gCS34fftig==} peerDependencies: - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 - '@tiptap/extension-floating-menu@3.22.4': - resolution: {integrity: sha512-DFuyYxgaZPgxum5z1yvJPbfYCvDdO8geXsdyqt0qYYdiat3aGE4ncJhiLRIFDhSHBhaZg5eCgu/YPYAN6jZnrA==} + '@tiptap/extension-floating-menu@3.29.2': + resolution: {integrity: sha512-CBTq4Xs5aGWr65uFCIkKBms796OhmirWf/ax//iJ4fl9IfwqjwFuc2vQs9PmuwpKn9ctDHo2sMTtvyeCvIt5LQ==} peerDependencies: '@floating-ui/dom': ^1.0.0 - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 - '@tiptap/extension-italic@3.22.4': - resolution: {integrity: sha512-fVSDx5AYXgDI3v2zZIqb7V8EewthwM2NJ/ZCX+XaxRsqNEpnjVhgHs7UlvDqK1wj2OJ6zmUNjPtVlAFRxwT+HQ==} + '@tiptap/extension-italic@3.29.2': + resolution: {integrity: sha512-iH63V/5wsaMnY4Jz0+meaAGhaec4AiOzOduzl6ZZr5IyGhZ1kthyW84ELt0dyLI3hNceAUhaNWc+I7+vX0aoXA==} peerDependencies: - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 - '@tiptap/extension-strike@3.22.4': - resolution: {integrity: sha512-aRHWQj42HiailXSC9LkKYM3jWMcSeGwOjbqM4PiuxQZmHVDRFmeHkfJItOdn2cSHaO0vuEVK+TvrWUWsBFi3pg==} + '@tiptap/extension-strike@3.29.2': + resolution: {integrity: sha512-aEvLAbddUQZ+FukCreV3q4G2HfNI+odE7E9U+wbq6XsSWKyo8/pDu1muz+TFKNre4blSMOQ3JQmw5UeHDKy+fg==} peerDependencies: - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 - '@tiptap/extension-text@3.22.4': - resolution: {integrity: sha512-mM69uUW5cSxIhyEpWXi/YcfyupcJMDLCPEfYi62awH0iOP/LRoCv/nHjJq4Hyj/KxRJbe8HKwIUnqaCUf7m5Pg==} + '@tiptap/extension-text@3.29.2': + resolution: {integrity: sha512-Ubko45JWWHe8glBt2PiGNF8hcbys/JNalFhiR7Y1X4iOOtAxAKJJxh3+eq+//NTlGuBPdWGp7zw8EEUp7anjKA==} peerDependencies: - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 - '@tiptap/extension-underline@3.22.4': - resolution: {integrity: sha512-08kGdbhIrA6h10GWXqOkqIveaBj5tmxclK208/nUIAlonI9hPd739vu7fmVtpnmqCnSSNpoRtU4u6Gj5at0ZpA==} + '@tiptap/extension-underline@3.29.2': + resolution: {integrity: sha512-K7XwH/xS/5AIREWQ00VTEf/W5U0olp7j6wwit7cdd/8nHv6h6AGr1+iEApHKoLXWQZLfGQKzJlT9W61LAl+fHA==} peerDependencies: - '@tiptap/core': ^3.0.0 + '@tiptap/core': ^3.29.2 - '@tiptap/extensions@3.22.4': - resolution: {integrity: sha512-fOe8VptJvLPs32bNdUYo8SRyljwqKNQVXWW056VoXIc5en/59OdJlJQVeHI0jRRciH3MtrqODi/gfJR0VHNZ8A==} + '@tiptap/extensions@3.29.2': + resolution: {integrity: sha512-BCz+FCAChSYtUe4BFj97HEO+nSK+J7GxbJgZG4Hg7DT/gI+hRyeNndU8efiQAx3WGdzsFi3UxRpcF1tTQM7iMQ==} peerDependencies: - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 - '@tiptap/pm@3.22.4': - resolution: {integrity: sha512-hj8Qka6WcHRllHUdeSjDnq2XaisUo4KsoGJc1WcFpoa1Yd+OeD861zUMnV7DFVGdZRy45Obht0CUYJpXQ4yA4w==} + '@tiptap/pm@3.29.2': + resolution: {integrity: sha512-GCOme7xHaS+DSoaA4CDcAD3l6JyBlvZhvCyfsy2Vp6j8tEoBkZWio7soYVosmlyn7zq8/64VeFZP5s47yfG7fQ==} - '@tiptap/react@3.22.4': - resolution: {integrity: sha512-XIQZPwLakR1t8+Q1UeCpr+kUHDWxpJzGy9r2xUi3mpPd6Wh8dtNltScBkUlCcr0sqc6J1GF6Is02JJVQGmCZMA==} + '@tiptap/react@3.29.2': + resolution: {integrity: sha512-ZMKgteYmZXnq7C22U9fbCTC6jAF8XlQM5n2K2FLWCdYAlP4FNV3XeQ9hY2a13KSQ0Q3yltWXZlcWBpt5ClxScg==} peerDependencies: - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -10186,8 +10186,8 @@ packages: '@tiptap/suggestion@2.27.2': resolution: {integrity: sha512-dQyvCIg0hcAVeh4fCIVCxogvbp+bF+GpbUb8sNlgnGrmHXnapGxzkvrlHnvneXZxLk/j7CxmBPKJNnm4Pbx4zw==} peerDependencies: - '@tiptap/core': ^3.0.0 - '@tiptap/pm': ^3.0.0 + '@tiptap/core': ^3.29.2 + '@tiptap/pm': ^3.29.2 '@transloadit/prettier-bytes@0.3.5': resolution: {integrity: sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA==} @@ -14182,11 +14182,14 @@ packages: prosemirror-history@1.5.0: resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + prosemirror-inputrules@1.5.1: + resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + prosemirror-keymap@1.2.3: resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} - prosemirror-model@1.25.4: - resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} + prosemirror-model@1.25.11: + resolution: {integrity: sha512-QWg9RhnpLlogAmp3p96uEFrE5txQpFynd4vhBAELkwgOCWQs/X0yCzB3/hrHqiPwf91RG5KyWq6553zs9JqIOQ==} prosemirror-schema-list@1.5.1: resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} @@ -14200,8 +14203,8 @@ packages: prosemirror-transform@1.12.0: resolution: {integrity: sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==} - prosemirror-view@1.41.8: - resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==} + prosemirror-view@1.42.2: + resolution: {integrity: sha512-Pdg0l5kXm8aLDquFAnQFTCITg0q44sLqBlHlpsVLD9segdOao8TOfQdAhCrCXyVgPSRr6UDDROOIWA3bIrN9YQ==} proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -16943,20 +16946,20 @@ snapshots: next: 16.2.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) tailwindcss: 4.2.2 - '@handlewithcare/prosemirror-inputrules@0.1.4(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)': + '@handlewithcare/prosemirror-inputrules@0.1.4(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)': dependencies: prosemirror-history: 1.5.0 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 - '@handlewithcare/prosemirror-suggest-changes@0.1.8(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)': + '@handlewithcare/prosemirror-suggest-changes@0.1.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.42.2)': dependencies: - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 '@hapi/address@5.1.1': dependencies: @@ -17255,17 +17258,17 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@liveblocks/react-blocknote@3.17.0(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': + '@liveblocks/react-blocknote@3.17.0(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': dependencies: '@blocknote/core': link:packages/core '@blocknote/react': link:packages/react '@liveblocks/client': 3.17.0(@types/json-schema@7.0.15) '@liveblocks/core': 3.17.0(@types/json-schema@7.0.15) '@liveblocks/react': 3.17.0(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) - '@liveblocks/react-tiptap': 3.17.0(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30)) + '@liveblocks/react-tiptap': 3.17.0(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30)) '@liveblocks/react-ui': 3.17.0(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@liveblocks/yjs': 3.17.0(@types/json-schema@7.0.15)(yjs@13.6.30) - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) react: 19.2.5 react-dom: 19.2.5(react@19.2.5) vitest-tsconfig-paths: 3.4.1 @@ -17284,17 +17287,17 @@ snapshots: - y-protocols - yjs - '@liveblocks/react-blocknote@3.19.5(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': + '@liveblocks/react-blocknote@3.19.5(@blocknote/core@packages+core)(@blocknote/react@packages+react)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': dependencies: '@blocknote/core': link:packages/core '@blocknote/react': link:packages/react '@liveblocks/client': 3.19.5(@types/json-schema@7.0.15) '@liveblocks/core': 3.19.5(@types/json-schema@7.0.15) '@liveblocks/react': 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) - '@liveblocks/react-tiptap': 3.19.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + '@liveblocks/react-tiptap': 3.19.5(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) '@liveblocks/react-ui': 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@liveblocks/yjs': 3.19.5(@types/json-schema@7.0.15)(yjs@13.6.30) - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) react: 19.2.5 react-dom: 19.2.5(react@19.2.5) optionalDependencies: @@ -17311,7 +17314,7 @@ snapshots: - y-protocols - yjs - '@liveblocks/react-tiptap@3.17.0(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))': + '@liveblocks/react-tiptap@3.17.0(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))': dependencies: '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@liveblocks/client': 3.17.0(@types/json-schema@7.0.15) @@ -17319,15 +17322,15 @@ snapshots: '@liveblocks/react': 3.17.0(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) '@liveblocks/react-ui': 3.17.0(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@liveblocks/yjs': 3.17.0(@types/json-schema@7.0.15)(yjs@13.6.30) - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 - '@tiptap/react': 3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@tiptap/suggestion': 2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + '@tiptap/react': 3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@tiptap/suggestion': 2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) cmdk: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) radix-ui: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - y-prosemirror: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + y-prosemirror: 1.3.7(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) yjs: 13.6.30 optionalDependencies: '@types/react': 19.2.14 @@ -17339,7 +17342,7 @@ snapshots: - prosemirror-view - y-protocols - '@liveblocks/react-tiptap@3.19.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': + '@liveblocks/react-tiptap@3.19.5(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': dependencies: '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@liveblocks/client': 3.19.5(@types/json-schema@7.0.15) @@ -17347,15 +17350,15 @@ snapshots: '@liveblocks/react': 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react@19.2.5) '@liveblocks/react-ui': 3.19.5(@types/json-schema@7.0.15)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@liveblocks/yjs': 3.19.5(@types/json-schema@7.0.15)(yjs@13.6.30) - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 - '@tiptap/react': 3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@tiptap/suggestion': 2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + '@tiptap/react': 3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@tiptap/suggestion': 2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) cmdk: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) radix-ui: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - y-prosemirror: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) + y-prosemirror: 1.3.7(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) yjs: 13.6.30 optionalDependencies: '@types/react': 19.2.14 @@ -20204,72 +20207,73 @@ snapshots: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@tiptap/core@3.22.4(@tiptap/pm@3.22.4)': + '@tiptap/core@3.29.2(@tiptap/pm@3.29.2)': dependencies: - '@tiptap/pm': 3.22.4 + '@tiptap/pm': 3.29.2 - '@tiptap/extension-bold@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': + '@tiptap/extension-bold@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) - '@tiptap/extension-bubble-menu@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': + '@tiptap/extension-bubble-menu@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': dependencies: '@floating-ui/dom': 1.7.6 - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 optional: true - '@tiptap/extension-code@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': + '@tiptap/extension-code@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) - '@tiptap/extension-floating-menu@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': + '@tiptap/extension-floating-menu@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': dependencies: '@floating-ui/dom': 1.7.6 - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 optional: true - '@tiptap/extension-italic@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': + '@tiptap/extension-italic@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) - '@tiptap/extension-strike@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': + '@tiptap/extension-strike@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) - '@tiptap/extension-text@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': + '@tiptap/extension-text@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) - '@tiptap/extension-underline@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': + '@tiptap/extension-underline@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) - '@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': + '@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 - '@tiptap/pm@3.22.4': + '@tiptap/pm@3.29.2': dependencies: prosemirror-changeset: 2.4.1 prosemirror-commands: 1.7.1 prosemirror-dropcursor: 1.8.2 prosemirror-gapcursor: 1.4.1 prosemirror-history: 1.5.0 + prosemirror-inputrules: 1.5.1 prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-schema-list: 1.5.1 prosemirror-state: 1.4.4 prosemirror-tables: 1.8.5 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 - '@tiptap/react@3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@tiptap/react@3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) '@types/use-sync-external-store': 0.0.6 @@ -20278,15 +20282,15 @@ snapshots: react-dom: 19.2.5(react@19.2.5) use-sync-external-store: 1.6.0(react@19.2.5) optionalDependencies: - '@tiptap/extension-bubble-menu': 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) - '@tiptap/extension-floating-menu': 3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + '@tiptap/extension-bubble-menu': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-floating-menu': 3.29.2(@floating-ui/dom@1.7.6)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) transitivePeerDependencies: - '@floating-ui/dom' - '@tiptap/suggestion@2.27.2(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': + '@tiptap/suggestion@2.27.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 '@transloadit/prettier-bytes@0.3.5': {} @@ -21236,14 +21240,14 @@ snapshots: dependencies: '@types/node': 20.19.39 - '@y/prosemirror@2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)': + '@y/prosemirror@2.0.0-6(patch_hash=e49b17b47e301dd138d7e383a779a0e2125bf7f038e10e3c740e26b43d988776)(@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23))(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)': dependencies: '@y/protocols': 1.0.6-rc.1(@y/y@14.0.0-rc.23) '@y/y': 14.0.0-rc.23 lib0: 1.0.0-rc.22 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 '@y/protocols@1.0.6-rc.1(@y/y@14.0.0-rc.23)': dependencies: @@ -25255,7 +25259,7 @@ snapshots: prosemirror-commands@1.7.1: dependencies: - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 @@ -25263,67 +25267,72 @@ snapshots: dependencies: prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 prosemirror-gapcursor@1.4.1: dependencies: prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 - prosemirror-highlight@0.15.1(@shikijs/types@4.0.2)(@types/hast@3.0.4)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8): + prosemirror-highlight@0.15.1(@shikijs/types@4.0.2)(@types/hast@3.0.4)(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-transform@1.12.0)(prosemirror-view@1.42.2): optionalDependencies: '@shikijs/types': 4.0.2 '@types/hast': 3.0.4 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 prosemirror-history@1.5.0: dependencies: prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 rope-sequence: 1.3.4 + prosemirror-inputrules@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-keymap@1.2.3: dependencies: prosemirror-state: 1.4.4 w3c-keyname: 2.2.8 - prosemirror-model@1.25.4: + prosemirror-model@1.25.11: dependencies: orderedmap: 2.1.1 prosemirror-schema-list@1.5.1: dependencies: - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 prosemirror-state@1.4.4: dependencies: - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 prosemirror-tables@1.8.5: dependencies: prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 prosemirror-transform@1.12.0: dependencies: - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 - prosemirror-view@1.41.8: + prosemirror-view@1.42.2: dependencies: - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 @@ -27212,7 +27221,7 @@ snapshots: picomatch: 4.0.4 std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.0.4 + tinyexec: 1.2.4 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 vite: 8.0.8(@types/node@20.19.37)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0) @@ -27242,7 +27251,7 @@ snapshots: picomatch: 4.0.4 std-env: 4.0.0 tinybench: 2.9.0 - tinyexec: 1.0.4 + tinyexec: 1.2.4 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0) @@ -27485,12 +27494,12 @@ snapshots: y-protocols: 1.0.7(yjs@13.6.30) yjs: 13.6.30 - y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30): + y-prosemirror@1.3.7(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30): dependencies: lib0: 1.0.0-rc.22 - prosemirror-model: 1.25.4 + prosemirror-model: 1.25.11 prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 + prosemirror-view: 1.42.2 y-protocols: 1.0.7(yjs@13.6.30) yjs: 13.6.30 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 11b8e3c0b1..284861edef 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -15,8 +15,8 @@ publicHoistPattern: - "prosemirror-*" overrides: "@headlessui/react": "^2.2.4" - "@tiptap/core": "^3.0.0" - "@tiptap/pm": "^3.0.0" + "@tiptap/core": "^3.29.2" + "@tiptap/pm": "^3.29.2" "vitest": "4.1.7" "@vitest/runner": "4.1.7" "@y/y": "14.0.0-rc.23" diff --git a/tests/package.json b/tests/package.json index 8a45c0c53b..3ec4b42e3a 100644 --- a/tests/package.json +++ b/tests/package.json @@ -16,7 +16,7 @@ "@blocknote/shadcn": "workspace:^", "@playwright/test": "1.60.0", "@tailwindcss/vite": "^4.1.14", - "@tiptap/pm": "^3.13.0", + "@tiptap/pm": "^3.29.2", "@types/node": "^20.19.22", "@types/react": "^19.2.3", "@types/react-dom": "^19.2.3", diff --git a/tests/src/unit/react/staleNodeViewPos.test.tsx b/tests/src/unit/react/staleNodeViewPos.test.tsx new file mode 100644 index 0000000000..2328f09ae0 --- /dev/null +++ b/tests/src/unit/react/staleNodeViewPos.test.tsx @@ -0,0 +1,261 @@ +import { + BlockNoteEditor, + BlockNoteSchema, + createBlockSpec, + defaultProps, +} from "@blocknote/core"; +import { BlockNoteViewRaw, createReactBlockSpec } from "@blocknote/react"; +import { useLayoutEffect } from "react"; +import { flushSync } from "react-dom"; +import { createRoot, type Root } from "react-dom/client"; +import { afterEach, describe, expect, it, vi } from "vite-plus/test"; + +/** + * Regression tests for #2937 (and the same family: #2682, #2621). + * + * A React node view resolves its block from `getPos()`, which ProseMirror + * derives from its view-desc tree. `EditorView.updateStateInner` assigns the + * new state *before* it reconciles that tree, so anything rendering part-way + * through reconciliation reads a position that doesn't line up with + * `view.state.doc`. Resolving it then threw out of the render path, which under + * React 19 tears down the consumer's tree rather than being rethrown. + */ + +// Set by a test to make a newly mounted node view dispatch a transaction from +// its layout effect, i.e. re-entrantly during ProseMirror's reconciliation. +let onMount: ((blockId: string, text: string) => void) | undefined; + +// Whether each node view render resolved to a block that was actually in the +// document *at the time it rendered*. Proves the recovery path ran without +// relying on a log line: a successful resolve always yields a block from the +// current document, whereas core's fallback builds one from the node alone +// under a freshly generated id that belongs to no block at all. +let renderedFromFallbackCount = 0; + +function noteRender(id: string, ed: BlockNoteEditor) { + let found = false; + ed.prosemirrorState.doc.descendants((node) => { + found ||= node.attrs.id === id; + return !found; + }); + if (!found) { + renderedFromFallbackCount++; + } +} + +// Typed structurally rather than with `ReactCustomBlockRenderProps`, whose +// `contentRef` is conditional on the block config's `content` type and so +// doesn't resolve through `any`. +function ReproComponent(props: { + block: { id: string; content?: unknown }; + editor: BlockNoteEditor; + contentRef: (element: HTMLElement | null) => void; +}) { + const { id, content } = props.block; + const text = + Array.isArray(content) && content[0]?.type === "text" + ? content[0].text + : ""; + + noteRender(id, props.editor); + + useLayoutEffect(() => { + onMount?.(id, text); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id]); + + return

; +} + +const createFillerBlock = createBlockSpec( + { type: "filler", propSchema: defaultProps, content: "inline" }, + { + render(block, editor) { + noteRender(block.id, editor as BlockNoteEditor); + const dom = document.createElement("p"); + return { dom, contentDOM: dom }; + }, + }, +); + +const createReproBlock = createReactBlockSpec( + { + type: "repro", + propSchema: defaultProps, + content: "inline", + }, + { render: ReproComponent }, +); + +const schema = BlockNoteSchema.create().extend({ + blockSpecs: { repro: createReproBlock(), filler: createFillerBlock() }, +}); + +type ReproEditor = BlockNoteEditor< + typeof schema.blockSchema, + typeof schema.inlineContentSchema, + typeof schema.styleSchema +>; + +let root: Root | undefined; +let div: HTMLDivElement | undefined; +let editor: ReproEditor | undefined; +/** Render-phase errors. React 19 reports rather than rethrows these. */ +let uncaught: unknown[] = []; + +function paragraphs(count: number, prefix: string) { + return Array.from({ length: count }, (_, i) => ({ + type: "filler" as const, + content: `${prefix} ${i} — filler text so the document has real size`, + })); +} + +function mountEditor(initialContent: any[]): ReproEditor { + div = document.createElement("div"); + document.body.appendChild(div); + + editor = BlockNoteEditor.create({ + schema, + trailingBlock: false, + initialContent, + }) as ReproEditor; + + uncaught = []; + renderedFromFallbackCount = 0; + root = createRoot(div, { + onUncaughtError: (error) => uncaught.push(error), + onCaughtError: (error) => uncaught.push(error), + }); + + flushSync(() => { + root!.render(); + }); + + // TipTap's `ReactRenderer` only renders a node view synchronously (via + // `flushSync`) when `isEditorContentInitialized` is set; otherwise it defers + // to a microtask. TipTap's own `PureEditorContent` sets it, but BlockNote + // replaces that component with its own mounting (`BlockNoteView.tsx`) and + // never does, so BlockNote currently gets the deferred path by accident. + // Set it here so node views mount the way they do for every other TipTap + // React user — and the way they do for anyone resolving `@tiptap/react` + // below 3.22, where this flag was still the always-true `isInitialized`. + // That is the configuration #2937 was reported against. + (editor as any)._tiptapEditor.isEditorContentInitialized = true; + + return editor; +} + +afterEach(() => { + onMount = undefined; + root?.unmount(); + root = undefined; + if (div) { + document.body.removeChild(div); + div = undefined; + } + editor?._tiptapEditor.destroy(); + editor = undefined; + vi.restoreAllMocks(); +}); + +/** Collects everything that went wrong during an action, however it surfaced. */ +function runCapturingErrors(action: () => void): string[] { + const errors: unknown[] = []; + const onWindowError = (e: ErrorEvent) => errors.push(e.error ?? e.message); + window.addEventListener("error", onWindowError); + try { + action(); + } catch (e) { + errors.push(e); + } finally { + window.removeEventListener("error", onWindowError); + } + errors.push(...uncaught); + uncaught = []; + return errors.map(String); +} + +const MARKER = "newly mounted repro block"; + +describe("stale node view getPos (#2937)", () => { + it("shrinking the doc while mounting a node view resolves normally", () => { + const ed = mountEditor([ + ...paragraphs(30, "head"), + { type: "repro", content: "existing repro block" }, + ...paragraphs(10, "tail"), + ]); + const errors = runCapturingErrors(() => { + ed.replaceBlocks(ed.document.slice(0, 28), [ + { type: "repro", content: MARKER } as any, + ]); + }); + + expect(errors).toEqual([]); + // The straightforward case must not go anywhere near the fallback. + expect(renderedFromFallbackCount).toBe(0); + }); + + it("recovers when a node view dispatches re-entrantly from its mount effect", () => { + const ed = mountEditor([ + ...paragraphs(30, "head"), + { type: "repro", content: "existing repro block" }, + ...paragraphs(10, "tail"), + ]); + let fired = false; + onMount = (_id, text) => { + if (fired || text !== MARKER) { + return; + } + fired = true; + // Runs inside React's commit phase, which is inside the `flushSync` in + // TipTap's `ReactRenderer` constructor, which is inside ProseMirror's + // `updateChildren`. Node views built or rendered from here see a + // `getPos()` computed against a half-updated view-desc tree. + ed.removeBlocks(ed.document.slice(-8)); + }; + + const errors = runCapturingErrors(() => { + ed.replaceBlocks(ed.document.slice(0, 28), [ + { type: "repro", content: MARKER } as any, + ]); + }); + + expect(fired).toBe(true); + // Before the fix this threw "Node should be a bnBlock, but is instead: doc" + // out of the render path. + expect(errors).toEqual([]); + // Guards against this silently ceasing to exercise the recovery path: a + // node view rendered the new block's content under an id that no block in + // the document has, which only core's fallback produces. + expect(renderedFromFallbackCount).toBeGreaterThan(0); + // The editor is still usable and shows the document it should. + expect(ed.document.some((b) => b.type === "repro")).toBe(true); + }); + + it("recovers when a re-entrant dispatch empties most of the document", () => { + const ed = mountEditor([ + ...paragraphs(40, "head"), + { type: "repro", content: "existing repro block" }, + ...paragraphs(20, "tail"), + ]); + let fired = false; + onMount = (_id, text) => { + if (fired || text !== MARKER) { + return; + } + fired = true; + ed.removeBlocks(ed.document.slice(1)); + }; + + const errors = runCapturingErrors(() => { + ed.replaceBlocks(ed.document.slice(0, 35), [ + { type: "repro", content: MARKER } as any, + ]); + }); + + expect(fired).toBe(true); + expect(errors).toEqual([]); + expect(renderedFromFallbackCount).toBeGreaterThan(0); + expect(ed.document.length).toBe(1); + }); +}); diff --git a/tests/src/unit/react/useNodeViewBlock.test.tsx b/tests/src/unit/react/useNodeViewBlock.test.tsx new file mode 100644 index 0000000000..71101c7fa7 --- /dev/null +++ b/tests/src/unit/react/useNodeViewBlock.test.tsx @@ -0,0 +1,173 @@ +import { + BlockNoteEditor, + BlockNoteSchema, + defaultProps, + getNodeById, +} from "@blocknote/core"; +import { createReactBlockSpec, useNodeViewBlock } from "@blocknote/react"; +import { flushSync } from "react-dom"; +import { createRoot, type Root } from "react-dom/client"; +import { + afterEach, + beforeEach, + describe, + expect, + it, + vi, +} from "vite-plus/test"; + +/** + * Branch-level coverage of the fallback `useNodeViewBlock` uses when a node + * view's `getPos()` can't be trusted. See `staleNodeViewPos.test.tsx` for the + * end-to-end reproduction of #2937. + */ + +const createReproBlock = createReactBlockSpec( + { type: "repro", propSchema: defaultProps, content: "inline" }, + { render: (props) =>

}, +); + +const schema = BlockNoteSchema.create().extend({ + blockSpecs: { repro: createReproBlock() }, +}); + +let editor: BlockNoteEditor; +let root: Root | undefined; +let div: HTMLDivElement; + +beforeEach(() => { + editor = BlockNoteEditor.create({ + schema, + trailingBlock: false, + initialContent: [ + { type: "paragraph", content: "first" }, + { type: "repro", content: "target block" }, + { type: "paragraph", content: "last" }, + ], + }) as BlockNoteEditor; + + div = document.createElement("div"); + document.body.appendChild(div); +}); + +afterEach(() => { + root?.unmount(); + root = undefined; + document.body.removeChild(div); + editor._tiptapEditor.destroy(); + vi.restoreAllMocks(); +}); + +/** Renders the hook once and returns what it resolved to. */ +function renderHook( + props: Parameters[0], + initialBlock: any, +) { + let resolved: any; + + function Probe() { + resolved = useNodeViewBlock(props, initialBlock); + return null; + } + + root = createRoot(div); + flushSync(() => { + root!.render(); + }); + + return resolved; +} + +// Only the two fields `useNodeViewBlock` reads. Built structurally so `tests` +// doesn't need a dependency on `@tiptap/react` just for its prop types. +function makeProps(getPos: () => number | undefined) { + return { + getPos, + view: { state: { doc: editor.prosemirrorState.doc } }, + } as unknown as Parameters[0]; +} + +describe("useNodeViewBlock", () => { + it("resolves from the position when it is valid", () => { + const doc = editor.prosemirrorState.doc; + const target = editor.document[1]; + // `getBlockFromPos` resolves the *parent* of the position, so the position + // has to sit just inside the block container. + const pos = getNodeById(target.id, doc)!.posBeforeNode + 1; + const stale = { ...target, id: "some-other-id" }; + const resolved = renderHook( + makeProps(() => pos), + stale, + ); + + expect(resolved.id).toBe(target.id); + expect(resolved.type).toBe("repro"); + }); + + it("falls back to the last known block when the position is out of range", () => { + const doc = editor.prosemirrorState.doc; + const lastKnown = editor.document[1]; + const resolved = renderHook( + makeProps(() => doc.content.size + 1000), + lastKnown, + ); + + // Returned as-is rather than throwing. + expect(resolved).toBe(lastKnown); + }); + + it("falls back to the last known block when the position is undefined", () => { + const lastKnown = editor.document[1]; + const resolved = renderHook( + makeProps(() => undefined), + lastKnown, + ); + + expect(resolved).toBe(lastKnown); + }); + + it("falls back to the last known block when the position resolves to the wrong node", () => { + const lastKnown = editor.document[1]; + // In range, but resolves to the doc rather than a block container — the + // shape that a bounds check alone would not have caught. + const resolved = renderHook( + makeProps(() => 0), + lastKnown, + ); + + expect(resolved).toBe(lastKnown); + }); + + it("keeps the last successfully resolved block, not the seed", () => { + const doc = editor.prosemirrorState.doc; + const target = editor.document[1]; + const pos = getNodeById(target.id, doc)!.posBeforeNode + 1; + const seed = { ...target, id: "stale-seed" }; + let positions = [pos, doc.content.size + 1000]; + let resolved: any; + + function Probe() { + resolved = useNodeViewBlock( + makeProps(() => positions[0]), + seed, + ); + return null; + } + + root = createRoot(div); + flushSync(() => { + root!.render(); + }); + expect(resolved.id).toBe(target.id); + + // Re-render with a position that no longer resolves: it must fall back to + // what it resolved last time, not to the seed it started with. + positions = positions.slice(1); + flushSync(() => { + root!.render(); + }); + + expect(resolved.id).toBe(target.id); + expect(resolved).not.toBe(seed); + }); +});