From a09280470efda1471479706c5419444df6f296a5 Mon Sep 17 00:00:00 2001 From: Hikari Date: Tue, 31 Mar 2026 10:35:29 -0700 Subject: [PATCH] fix: prevent auto-save race from discarding collected exploration materials (#160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Block the auto-save tick while the /explore/collect request is in-flight, clear the stale HMAC signature after the server-side DB write, and reset the save timer so the next auto-save fires after React has re-rendered with the new materials in stateReference — eliminating the window where a stale client snapshot could overwrite the server's freshly saved collect result. --- apps/web/src/context/gameContext.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/web/src/context/gameContext.tsx b/apps/web/src/context/gameContext.tsx index 22b2ec3..206b84c 100644 --- a/apps/web/src/context/gameContext.tsx +++ b/apps/web/src/context/gameContext.tsx @@ -1810,7 +1810,18 @@ export const GameProvider = ({ const collectExploration = useCallback( async(areaId: string): Promise => { + isSyncingReference.current = true; const result = await collectExplorationApi({ areaId }); + + /* + * Collect mutates server state outside the normal save flow — clear the + * stale HMAC signature and reset the timer so the next auto-save fires + * after React has re-rendered with the new materials in stateReference. + */ + signatureReference.current = null; + localStorage.removeItem("elysium_save_signature"); + lastSaveReference.current = Date.now(); + isSyncingReference.current = false; setState((previous) => { if (previous?.exploration === undefined) { return previous;