diff --git a/CHANGELOG.md b/CHANGELOG.md index bcadabc55..2c679ae54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fixed memory leak attributed to CodeMirror allocating objects on heap that were never freed. [#1580](https://github.com/sourcebot-dev/sourcebot/pull/1580) + ## [5.1.7] - 2026-08-13 ### Added diff --git a/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.test.ts b/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.test.ts new file mode 100644 index 000000000..cba8d1160 --- /dev/null +++ b/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.test.ts @@ -0,0 +1,6 @@ +import { expect, test } from 'vitest'; +import { zoekt } from './zoektLanguageExtension'; + +test('reuses the same language support across calls', () => { + expect(zoekt()).toBe(zoekt()); +}); diff --git a/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.ts b/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.ts index 6d86a710d..a57ada05b 100644 --- a/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.ts +++ b/packages/web/src/app/(app)/components/searchBar/zoektLanguageExtension.ts @@ -1,7 +1,9 @@ import { LanguageSupport, StreamLanguage } from "@codemirror/language"; import { tags as t } from "@lezer/highlight"; -export const zoekt = () => { +// StreamLanguage permanently registers a document NodeType, so this must be a +// module singleton rather than one instance per SearchBar render. +const zoektLanguageSupport = (() => { const zoektLanguage = StreamLanguage.define({ startState() { return { @@ -75,4 +77,6 @@ export const zoekt = () => { }); return new LanguageSupport(zoektLanguage); -}; +})(); + +export const zoekt = () => zoektLanguageSupport;