From 831f6eb72ba392e7e249037ee7fa0b3935f5f48d Mon Sep 17 00:00:00 2001 From: lucaronin Date: Thu, 30 Apr 2026 12:58:19 +0200 Subject: [PATCH] fix: guard uninitialized BlockNote suggestion updates --- patches/@blocknote__core@0.46.2.patch | 18 ++++++++++++++++++ pnpm-lock.yaml | 16 ++++++++-------- .../blockNoteSuggestionMenu.regression.test.ts | 9 +++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/patches/@blocknote__core@0.46.2.patch b/patches/@blocknote__core@0.46.2.patch index fc4bcd46..e666130d 100644 --- a/patches/@blocknote__core@0.46.2.patch +++ b/patches/@blocknote__core@0.46.2.patch @@ -9,6 +9,15 @@ n.updateBlock(t.id, { props: { language: d } }); }; i.addEventListener("change", l), s = () => i.removeEventListener("change", l); +@@ -2639,7 +2641,7 @@ + this.editor = t, this.pluginState = void 0, this.emitUpdate = (a) => { + var s; + if (!this.state) +- throw new Error("Attempting to update uninitialized suggestions menu"); ++ return; + n(a, { + ...this.state, + ignoreQueryLength: (s = this.pluginState) == null ? void 0 : s.ignoreQueryLength @@ -2651,17 +2653,23 @@ if (!a && !(o !== void 0 && r !== void 0) && !s) return; @@ -110,6 +119,15 @@ const t = [ --- a/src/extensions/SuggestionMenu/SuggestionMenu.ts +++ b/src/extensions/SuggestionMenu/SuggestionMenu.ts +@@ -32,7 +32,7 @@ + + this.emitUpdate = (menuName: string) => { + if (!this.state) { +- throw new Error("Attempting to update uninitialized suggestions menu"); ++ return; + } + + emitUpdate(menuName, { @@ -83,29 +83,38 @@ this.pluginState = stopped ? prev : next; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 842dac90..100a2eaa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: patchedDependencies: '@blocknote/core@0.46.2': - hash: 88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0 + hash: 28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42 path: patches/@blocknote__core@0.46.2.patch '@blocknote/react@0.46.2': hash: e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76 @@ -27,10 +27,10 @@ importers: version: 0.78.0(zod@4.3.6) '@blocknote/code-block': specifier: ^0.46.2 - version: 0.46.2(@blocknote/core@0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)) + version: 0.46.2(@blocknote/core@0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)) '@blocknote/core': specifier: ^0.46.2 - version: 0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) + version: 0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) '@blocknote/mantine': specifier: ^0.46.2 version: 0.46.2(@floating-ui/dom@1.7.5)(@mantine/core@8.3.14(@mantine/hooks@8.3.14(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@mantine/hooks@8.3.14(react@19.2.4))(@mantine/utils@6.0.22(react@19.2.4))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -5359,9 +5359,9 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@blocknote/code-block@0.46.2(@blocknote/core@0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0))': + '@blocknote/code-block@0.46.2(@blocknote/core@0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0))': dependencies: - '@blocknote/core': 0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) + '@blocknote/core': 0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) '@shikijs/core': 3.23.0 '@shikijs/engine-javascript': 3.23.0 '@shikijs/langs': 3.23.0 @@ -5369,7 +5369,7 @@ snapshots: '@shikijs/themes': 3.23.0 '@shikijs/types': 3.22.0 - '@blocknote/core@0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)': + '@blocknote/core@0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)': dependencies: '@emoji-mart/data': 1.2.1 '@handlewithcare/prosemirror-inputrules': 0.1.4(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6) @@ -5421,7 +5421,7 @@ snapshots: '@blocknote/mantine@0.46.2(@floating-ui/dom@1.7.5)(@mantine/core@8.3.14(@mantine/hooks@8.3.14(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@mantine/hooks@8.3.14(react@19.2.4))(@mantine/utils@6.0.22(react@19.2.4))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@blocknote/core': 0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) + '@blocknote/core': 0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) '@blocknote/react': 0.46.2(patch_hash=e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@mantine/core': 8.3.14(@mantine/hooks@8.3.14(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@mantine/hooks': 8.3.14(react@19.2.4) @@ -5443,7 +5443,7 @@ snapshots: '@blocknote/react@0.46.2(patch_hash=e09f7011df33f4ff92c0d3fd8c9060e62f08997d076f3e438e1e82f8c1ab2f76)(@floating-ui/dom@1.7.5)(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@blocknote/core': 0.46.2(patch_hash=88fd4c0393dc9519af3a96dc4cdb35494424ea6201eff4839a383b41b40c85a0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) + '@blocknote/core': 0.46.2(patch_hash=28d8e7bb45cd7d97aff60af3926d65b831605bfe4d582a1da725d214d3fb1f42)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0) '@emoji-mart/data': 1.2.1 '@floating-ui/react': 0.27.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@floating-ui/utils': 0.2.10 diff --git a/src/lib/blockNoteSuggestionMenu.regression.test.ts b/src/lib/blockNoteSuggestionMenu.regression.test.ts index 80240cf0..cb564fe5 100644 --- a/src/lib/blockNoteSuggestionMenu.regression.test.ts +++ b/src/lib/blockNoteSuggestionMenu.regression.test.ts @@ -32,6 +32,7 @@ type SuggestionEditorView = { } type SuggestionPluginView = { + emitUpdate: (triggerCharacter: string) => void update: (view: SuggestionEditorView, prevState: SuggestionEditorState) => void } @@ -81,6 +82,14 @@ function createEditorView(state: SuggestionEditorState): SuggestionEditorView { } describe('patched BlockNote suggestion menu lifecycle', () => { + it('ignores late updates before the suggestion menu state initializes', () => { + const plugin = createSuggestionPlugin() + const editorView = createEditorView(createState(plugin)) + const pluginView = plugin.spec.view(editorView) + + expect(() => pluginView.emitUpdate('/')).not.toThrow() + }) + it('closes a suggestion menu before its decoration mounts without throwing', () => { const plugin = createSuggestionPlugin() const inactiveState = createState(plugin)