Files
lanspread/IMPL_DECISIONS.md
T
ddidderr 9835e77e8d feat: store launcher state outside game dirs
Move launcher-owned metadata from game roots into the configured peer state
area. Peer identity, the local library index, install intent logs, and setup
markers now live under app/CLI state instead of being written beside games.
The Tauri shell passes its app data directory into the peer, and the peer CLI
runs the same path through its explicit --state-dir.

Add a dedicated pre-start migration phase for legacy files. It migrates the
old global library index, per-game install intents, and the old first-start
marker into app state, then deletes legacy files only after the replacement
write succeeds. Normal scan, install, recovery, and transfer paths no longer
read legacy state files.

Rename the old first-start meaning to setup_done and only set it after
launching game_setup.cmd. Start/setup scripts keep the shared argument shape,
while server_start.cmd now uses cmd /k and a visible window so server logs stay
open for inspection.

While validating the Docker scenario matrix, make download terminal events
come from the handler after local state refresh and operation cleanup. This
makes download-finished/download-failed safe points for immediate follow-up CLI
commands. Also update the multi-peer chunking scenario to use a sparse archive
large enough to actually span multiple production chunks.

Test Plan:
- just fmt
- just test
- just frontend-test
- just build
- just clippy
- git diff --check
- python3 crates/lanspread-peer-cli/scripts/run_extended_scenarios.py

Refs: local app-state migration discussion
2026-05-21 21:32:28 +02:00

2.3 KiB

Implementation Decisions

  • Added a just test recipe so unit tests can be run through the repository's required just ... command surface instead of invoking cargo test directly.
  • Renamed the frontend success event to game-install-finished; the old unpack name no longer matched the transactional install/update lifecycle.
  • Implemented watcher rescans by reusing the app-state local_library/index.json cache and updating a single game entry in that index. This satisfies the per-ID optimized rescan requirement without adding a second cache format.
  • Split full startup recovery from ordinary settled refreshes. Startup and real SetGameDir changes run recovery plus a scan; install/update/uninstall completion only rescans the affected game after operation tracking has been cleared.
  • Rejected path-changing SetGameDir while operations are active. Same-path refreshes are allowed and deliberately skip full recovery so they cannot sweep download transients for in-flight work.
  • Kept a separate active_downloads cancellation-token map next to the single active_operations table. The operation table is the authoritative state for gates; the token map is only cancellation plumbing for in-flight downloads.
  • Treated a downloaded-but-not-installed game as immediately installable from Tauri by sending PeerCommand::InstallGame directly. A not-downloaded game still uses GetGame, and the peer auto-installs after the sentinel commit.
  • Removed the dead internal PeerCommand::UpdateGame path. The UI update button now sends FetchLatestFromPeers, which skips local manifest serving and asks latest-version peers for fresh file metadata before the normal download and update transaction runs.
  • Removed the unreachable Availability::Downloading protocol value. Active operations are reported separately, and local summaries emit only settled availability.
  • Threaded availability through the UI-facing Game payload so LocalOnly rendering follows backend state instead of reverse-engineering it from installed && !downloaded.
  • Removed Tauri's parallel whole-library filesystem scan. The UI database keeps bundled catalog metadata, while peer LocalLibraryChanged snapshots now own downloaded, installed, local_version, and availability.