fix(stage-ui): skip optimistic updates before apply (#1304)

* fix(stage-ui): skip optimistic updates before apply

Avoid leaving phantom optimistic state behind when a mutation is intentionally skipped by checking the guard before applying the optimistic update.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Ryanba
2026-03-12 12:12:31 +08:00
committed by GitHub
co-authored by Sisyphus autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
parent 8251b8a512
commit 41ce282e95
3 changed files with 30 additions and 2 deletions
@@ -20,7 +20,7 @@ menu:
open_caption: Mở phụ đề...
caption_overlay: Lớp phủ phụ đề
follow_window: Theo cửa sổ
reset_position: Đặt lại vị trí
reset_position: Đặt lại vị trí
devtools: Công cụ phát triển
troubleshoot_beatsync: Sửa lỗi BeatSync...
quit: Thoát ra
@@ -120,4 +120,31 @@ describe('useOptimistic', () => {
await execute()
expect(error.value).toBeDefined()
})
it('should skip without applying optimistic state', async () => {
const state = ref('initial')
const apply = vi.fn(() => {
state.value = 'optimistic'
return () => {
state.value = 'initial'
}
})
const action = vi.fn(async () => 'should-not-run')
const skipActionIf = vi.fn(() => true)
const { execute, state: resultState } = useOptimisticMutation({
apply,
action,
skipActionIf,
lazy: true,
})
await execute()
expect(skipActionIf).toHaveBeenCalled()
expect(apply).not.toHaveBeenCalled()
expect(action).not.toHaveBeenCalled()
expect(state.value).toBe('initial')
expect(resultState.value).toBeUndefined()
})
})
@@ -50,11 +50,12 @@ export function useOptimisticMutation<T, R = T, E = unknown>(options: UseOptimis
} = options
return useAsyncState(async () => {
const rollback = await apply()
if (skipActionIf && await skipActionIf()) {
return undefined as R
}
const rollback = await apply()
try {
const result = await action()
if (onSuccess) {