refactor: simplify note mutation flushing

This commit is contained in:
lucaronin
2026-04-28 06:25:39 +02:00
parent b85d54bb5d
commit 2a224f78f8
4 changed files with 18 additions and 38 deletions

View File

@@ -541,8 +541,7 @@ function App() {
removeEntry: vault.removeEntry,
entries: vault.entries,
flushBeforeNoteSwitch: flushEditorStateBeforeAction,
flushBeforeFrontmatterChange: flushEditorStateBeforeAction,
flushBeforePathRename: flushEditorStateBeforeAction,
flushBeforeNoteMutation: flushEditorStateBeforeAction,
reloadVault: vault.reloadVault,
setToastMessage,
updateEntry: vault.updateEntry,

View File

@@ -70,16 +70,16 @@ describe('useNoteActions frontmatter persistence', () => {
},
},
])('flushes pending raw content before a frontmatter $label', async ({ run }) => {
const flushBeforeFrontmatterChange = vi.fn().mockResolvedValue(undefined)
const flushBeforeNoteMutation = vi.fn().mockResolvedValue(undefined)
const { result } = renderHook(() => useNoteActions({
...makeConfig(vi.fn()),
flushBeforeFrontmatterChange,
flushBeforeNoteMutation,
}))
await act(async () => {
await run(result)
})
expect(flushBeforeFrontmatterChange).toHaveBeenCalledWith('/vault/note.md')
expect(flushBeforeNoteMutation).toHaveBeenCalledWith('/vault/note.md')
})
})

View File

@@ -77,7 +77,7 @@ describe('useNoteActions title rename guard', () => {
it('flushes pending editor work before renaming through the title property', async () => {
const entry = makeEntry()
const events: string[] = []
const flushBeforePathRename = vi.fn(async (path: string) => {
const flushBeforeNoteMutation = vi.fn(async (path: string) => {
events.push(`flush:${path}`)
})
@@ -90,7 +90,7 @@ describe('useNoteActions title rename guard', () => {
return ''
})
const { result } = renderHook(() => useNoteActions(makeConfig(entry, { flushBeforePathRename })))
const { result } = renderHook(() => useNoteActions(makeConfig(entry, { flushBeforeNoteMutation })))
await act(async () => {
result.current.handleSelectNote(entry)
@@ -100,17 +100,18 @@ describe('useNoteActions title rename guard', () => {
await result.current.handleUpdateFrontmatter(entry.path, 'title', 'New Name')
})
expect(flushBeforePathRename).toHaveBeenCalledWith(entry.path)
expect(flushBeforeNoteMutation).toHaveBeenCalledTimes(1)
expect(flushBeforeNoteMutation).toHaveBeenCalledWith(entry.path)
expect(events).toEqual([`flush:${entry.path}`, 'rename'])
})
it('stops the title rename flow when pending editor work fails to flush', async () => {
const entry = makeEntry()
const flushBeforePathRename = vi.fn().mockRejectedValue(new Error('disk full'))
const flushBeforeNoteMutation = vi.fn().mockRejectedValue(new Error('disk full'))
const updateEntry = vi.fn()
const { result } = renderHook(() => useNoteActions(makeConfig(entry, {
flushBeforePathRename,
flushBeforeNoteMutation,
updateEntry,
})))

View File

@@ -15,8 +15,7 @@ export interface NoteActionsConfig {
removeEntry: (path: string) => void
entries: VaultEntry[]
flushBeforeNoteSwitch?: (path: string) => Promise<void>
flushBeforeFrontmatterChange?: (path: string) => Promise<void>
flushBeforePathRename?: (path: string) => Promise<void>
flushBeforeNoteMutation?: (path: string) => Promise<void>
reloadVault?: () => Promise<unknown>
setToastMessage: (msg: string | null) => void
updateEntry: (path: string, patch: Partial<VaultEntry>) => void
@@ -127,30 +126,14 @@ interface MaybeRenameAfterFrontmatterUpdateParams {
deps: TitleRenameDeps
}
async function flushBeforeTitleRename(
async function flushBeforeNoteMutation(
path: string,
key: string,
value: FrontmatterValue,
flushBeforePathRename?: (path: string) => Promise<void>,
flushBeforeMutation?: (path: string) => Promise<void>,
): Promise<boolean> {
if (!shouldRenameOnTitleUpdate(key, value) || !flushBeforePathRename) return true
if (!flushBeforeMutation) return true
try {
await flushBeforePathRename(path)
return true
} catch {
return false
}
}
async function flushBeforeFrontmatterMutation(
path: string,
flushBeforeFrontmatterChange?: (path: string) => Promise<void>,
): Promise<boolean> {
if (!flushBeforeFrontmatterChange) return true
try {
await flushBeforeFrontmatterChange(path)
await flushBeforeMutation(path)
return true
} catch {
return false
@@ -196,12 +179,9 @@ async function updateFrontmatterAndMaybeRename({
runFrontmatterOp,
value,
}: UpdateFrontmatterAndMaybeRenameParams): Promise<void> {
const canFlush = await flushBeforeFrontmatterMutation(path, config.flushBeforeFrontmatterChange)
const canFlush = await flushBeforeNoteMutation(path, config.flushBeforeNoteMutation)
if (!canFlush) return
const canRename = await flushBeforeTitleRename(path, key, value, config.flushBeforePathRename)
if (!canRename) return
const newContent = await runFrontmatterOp('update', path, key, value, options)
if (!applyFrontmatterCallbacks({ config, path, newContent })) return
@@ -289,7 +269,7 @@ function useFrontmatterActionHandlers({
}, [activeTabPathRef, config, handleSwitchTab, renameTabsRef, runFrontmatterOp, setTabs, setToastMessage, updateTabContent])
const handleDeleteProperty = useCallback(async (path: string, key: string, options?: FrontmatterOpOptions) => {
const canFlush = await flushBeforeFrontmatterMutation(path, config.flushBeforeFrontmatterChange)
const canFlush = await flushBeforeNoteMutation(path, config.flushBeforeNoteMutation)
if (!canFlush) return
const newContent = await runFrontmatterOp('delete', path, key, undefined, options)
@@ -298,7 +278,7 @@ function useFrontmatterActionHandlers({
}, [config, runFrontmatterOp])
const handleAddProperty = useCallback(async (path: string, key: string, value: FrontmatterValue) => {
const canFlush = await flushBeforeFrontmatterMutation(path, config.flushBeforeFrontmatterChange)
const canFlush = await flushBeforeNoteMutation(path, config.flushBeforeNoteMutation)
if (!canFlush) return
const newContent = await runFrontmatterOp('update', path, key, value)