Problem
Translation responses are committed unconditionally. A slower older request can therefore overwrite the result, error, or loading state that belongs to a newer selected-text translation.
The selection-only in-flight guard prevents two shortcut captures from overlapping, but it does not serialize an existing manual or document translation with a new global-selection request. Editing, importing, or clearing the source also does not invalidate an older request.
Reproduction
- Start translation A and keep its request pending.
- Trigger the registered global-selection callback with source B.
- Resolve B first and verify that its result appears.
- Resolve or reject A afterward.
Current behavior: A replaces B's result or error state while the source still shows B. If A completes first, it can also clear the shared loading state while B remains pending.
Acceptance criteria
- Assign every translation a monotonic request generation; only the current generation may update
result, error, or loading.
- Replacing source text from global selection immediately invalidates every older translation before B becomes current.
- Editing, importing, and clearing source text also invalidate in-flight translations, so old completions cannot repopulate the UI.
- In both A-then-B and B-then-A completion orders, A cannot modify B's result, error, or loading state.
- A rejection from an old request cannot replace the current request's state.
- Apply the UI-level generation guard to both web fetch and Tauri invoke paths. Transport cancellation can be added as an optimization but is not a substitute for the commit guard.
- Add automated deferred-promise coverage for both completion orders and an old-request rejection.
Relevant code
src/App.tsx: handleSelectedText, translateValue, handleTranslate, document import, textarea editing, and reset paths.
src/platform.ts: the capture guard only covers concurrent selection captures and does not cover existing translation requests.
Problem
Translation responses are committed unconditionally. A slower older request can therefore overwrite the result, error, or loading state that belongs to a newer selected-text translation.
The selection-only in-flight guard prevents two shortcut captures from overlapping, but it does not serialize an existing manual or document translation with a new global-selection request. Editing, importing, or clearing the source also does not invalidate an older request.
Reproduction
Current behavior: A replaces B's result or error state while the source still shows B. If A completes first, it can also clear the shared loading state while B remains pending.
Acceptance criteria
result,error, orloading.Relevant code
src/App.tsx:handleSelectedText,translateValue,handleTranslate, document import, textarea editing, and reset paths.src/platform.ts: the capture guard only covers concurrent selection captures and does not cover existing translation requests.