fix: guard note suggestions during reload

This commit is contained in:
lucaronin
2026-04-30 12:09:35 +02:00
parent 690ace2d1f
commit fdc7d8fd84
8 changed files with 389 additions and 14 deletions

View File

@@ -440,6 +440,25 @@ describe('SingleEditorView', () => {
expect(onMentionItemClick).toHaveBeenCalledOnce()
})
it('renders when a reload returns an entry with missing suggestion metadata', () => {
const reloadedEntry = {
...makeEntry({ path: '/vault/project/reloaded.md', title: 'Reloaded' }),
filename: undefined,
aliases: undefined,
isA: undefined,
} as unknown as VaultEntry
expect(() => {
render(
<SingleEditorView
editor={createEditor() as never}
entries={[reloadedEntry]}
onNavigateWikilink={vi.fn()}
/>,
)
}).not.toThrow()
})
it('ignores stale suggestion item clicks after the editor DOM disconnects', () => {
const editor = createEditor()
editor.domElement = document.createElement('div')

View File

@@ -451,15 +451,42 @@ function handleCodeBlockCopy(event: React.ClipboardEvent<HTMLDivElement>) {
event.preventDefault()
}
function nonEmptyString(value: unknown): string | null {
return typeof value === 'string' && value.trim().length > 0 ? value : null
}
function markdownStem(value: string): string {
return value.replace(/\.md$/i, '')
}
function pathStem(path: string): string {
return markdownStem(path.split('/').pop() ?? path)
}
function safeStringArray(value: unknown): string[] {
return Array.isArray(value)
? value.filter((item): item is string => nonEmptyString(item) !== null)
: []
}
function buildBaseSuggestionItems(entries: VaultEntry[]) {
return deduplicateByPath(entries.map(entry => ({
title: entry.title,
aliases: [...new Set([entry.filename.replace(/\.md$/, ''), ...entry.aliases])],
group: entry.isA || 'Note',
entryType: entry.isA,
entryTitle: entry.title,
path: entry.path,
})))
return deduplicateByPath(entries.flatMap(entry => {
const path = nonEmptyString(entry.path)
if (!path) return []
const filename = nonEmptyString(entry.filename)
const filenameStem = filename ? markdownStem(filename) : pathStem(path)
const title = nonEmptyString(entry.title) ?? filenameStem
const entryType = nonEmptyString(entry.isA)
return [{
title,
aliases: [...new Set([filenameStem, ...safeStringArray(entry.aliases)])],
group: entryType ?? 'Note',
entryType,
entryTitle: title,
path,
}]
}))
}
function useInsertWikilink(