Skip to content

Clean up Explore autosave lifecycle - #1086

Merged
tannerlinsley merged 1 commit into
mainfrom
agent/cleanup-explore-autosave
Jul 31, 2026
Merged

Clean up Explore autosave lifecycle#1086
tannerlinsley merged 1 commit into
mainfrom
agent/cleanup-explore-autosave

Conversation

@tannerlinsley

@tannerlinsley tannerlinsley commented Jul 31, 2026

Copy link
Copy Markdown
Member

What changed

Move Explore's periodic save timer and beforeunload listener from module scope into the IslandExplorer component lifecycle.

The lifecycle hook now:

  • starts one autosave timer while Explore is mounted
  • removes the timer and listener when navigating away
  • saves once during cleanup so the latest progress is retained

Evidence and impact

Importing useGameStore.ts previously started a permanent five-second interval and registered an anonymous beforeunload listener. TanStack Router keeps that loaded module alive after SPA navigation, so an active game continued writing to localStorage every five seconds after leaving /explore; HMR could also register additional timers and listeners.

This change ties both resources to the only UI that needs them and prevents background work after leaving Explore.

Validation

  • pnpm test — TypeScript and type-aware lint clean; 135 tests (134 passed, 1 skipped)
  • commit hook reran formatting and the full test gate successfully
  • git diff --check

Risk

Low. Save cadence and unload behavior are unchanged while Explore is mounted. Cleanup adds one final save before stopping persistence.

Summary by CodeRabbit

  • New Features
    • Game progress is now saved automatically during gameplay.
    • Progress is also saved when leaving or closing the game, helping prevent lost changes.
  • Bug Fixes
    • Improved persistence handling so save operations are managed consistently while the game is active and stopped cleanly when it is no longer in use.

@tannerlinsley tannerlinsley added the source-audit Tracked by the automated source audit label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR replaces module-level game persistence setup with a new useGamePersistence React hook. The hook saves game state every five seconds, saves on beforeunload, and cleans up on unmount. IslandExplorer now calls this hook.

Changes

Game Persistence

Layer / File(s) Summary
Persistence hook implementation
src/components/game/hooks/useGameStore.ts
Adds useEffect import and replaces the unconditional module-level interval and unload registration with an exported useGamePersistence hook. The hook saves playing or game-over state every five seconds, saves on unload, and clears the interval and event listener on cleanup.
IslandExplorer wiring
src/components/game/IslandExplorer.client.tsx
Imports useGamePersistence and calls it during render to enable persistence for the component.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant IslandExplorer
  participant useGamePersistence
  participant GameStore
  participant Browser

  IslandExplorer->>useGamePersistence: invoke on render
  useGamePersistence->>Browser: register beforeunload handler
  loop every 5 seconds
    useGamePersistence->>GameStore: save state if playing or game-over
  end
  Browser-->>useGamePersistence: beforeunload event
  useGamePersistence->>GameStore: save final state
  IslandExplorer->>useGamePersistence: unmount
  useGamePersistence->>Browser: clear interval and remove handler
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: moving autosave lifecycle management from module scope into component lifecycle for the Explore feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/cleanup-explore-autosave

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com 739fccf Commit Preview URL

Branch Preview URL
Jul 31 2026, 03:11 PM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/game/hooks/useGameStore.ts`:
- Around line 1015-1018: Update the cleanup around the useGameStore persistence
effect so startOver’s explicit STORAGE_KEY removal is tracked and the unmount
persist() call is skipped after that reset. Clear the tracking state when a new
game starts, preserve normal unmount persistence otherwise, and add a regression
test covering startOver followed by unmount without recreating the save key.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7eb677f-8021-4a45-8fa9-97bff3eff9ba

📥 Commits

Reviewing files that changed from the base of the PR and between 0ba1117 and 739fccf.

📒 Files selected for processing (2)
  • src/components/game/IslandExplorer.client.tsx
  • src/components/game/hooks/useGameStore.ts

Comment on lines +1015 to +1018
return () => {
window.clearInterval(interval)
window.removeEventListener('beforeunload', persist)
persist()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Preserve the storage clear during unmount.

startOver removes STORAGE_KEY at Line [887]. When IslandExplorer unmounts, this cleanup calls persist() at Line [1018] and recreates the save key with the reset state. Track the explicit clear and skip the final save until a new game starts. Add a regression test for startOver followed by unmount.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/game/hooks/useGameStore.ts` around lines 1015 - 1018, Update
the cleanup around the useGameStore persistence effect so startOver’s explicit
STORAGE_KEY removal is tracked and the unmount persist() call is skipped after
that reset. Clear the tracking state when a new game starts, preserve normal
unmount persistence otherwise, and add a regression test covering startOver
followed by unmount without recreating the save key.

@tannerlinsley
tannerlinsley merged commit 24799a3 into main Jul 31, 2026
7 checks passed
@tannerlinsley
tannerlinsley deleted the agent/cleanup-explore-autosave branch July 31, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

source-audit Tracked by the automated source audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant