Add desktop persistent cache, offline circuit-breaker states, and panel freshness badges#48
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f241e75b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let mut root: Map<String, Value> = if path.exists() { | ||
| let contents = std::fs::read_to_string(&path) | ||
| .map_err(|e| format!("Failed to read cache store {}: {e}", path.display()))?; | ||
| serde_json::from_str::<Value>(&contents) | ||
| .ok() |
There was a problem hiding this comment.
Serialize cache writes under a lock
write_cache_entry performs an unsynchronized read-modify-write of a single JSON file, so concurrent invoke('write_cache_entry', ...) calls can overwrite each other and drop previously written keys. This can happen during normal startup because multiple services (rss, earthquakes, cached-risk-scores, insights brief) call setPersistentCache in parallel, making persisted fallback data nondeterministically incomplete.
Useful? React with 👍 / 👎.
| })); | ||
| }, []); | ||
|
|
||
| if (live.length > 0) { |
There was a problem hiding this comment.
Preserve successful empty earthquake payloads
This branch treats live.length === 0 as a failure and always falls back to persisted data, so a successful USGS response with zero events (or a valid cached empty result from the breaker) gets replaced with stale historical quakes. That makes the map show outdated incidents instead of the current empty state and prevents the empty snapshot from ever being persisted.
Useful? React with 👍 / 👎.
| const CACHE_TTL = 10 * 60 * 1000; // 10 minutes | ||
|
|
||
| function toSerializable(items: NewsItem[]): Array<Omit<NewsItem, 'pubDate'> & { pubDate: string }> { | ||
| return items.map(item => ({ ...item, pubDate: item.pubDate.toISOString() })); |
There was a problem hiding this comment.
Handle invalid RSS dates before ISO serialization
Persisting feed items now calls item.pubDate.toISOString() unconditionally, but malformed RSS pubDate values produce Invalid Date, and toISOString() throws RangeError. In that case fetchFeed drops into the catch path and returns stale/persistent/empty data even though parsing otherwise succeeded, so a single bad timestamp can suppress an entire feed update.
Useful? React with 👍 / 👎.
f52f4fd
into
codex/add-tauri-v2-integration-and-configuration
…el freshness badges (koala73#48) ### Motivation - Ensure the app remains useful when cloud APIs are unreachable by providing durable local fallbacks and clearer UI indicators for stale/offline data. - Persist recent feed items, latest computed risk snapshots, and stale-tolerant map overlays for desktop builds so a packaged app can operate without network. - Surface data freshness and whether values are `live`, `cached`, or `unavailable` in panels so analysts understand what they are seeing. ### Description - Add a desktop-aware persistent cache service (`src/services/persistent-cache.ts`) that uses Tauri `invoke` commands (`read_cache_entry` / `write_cache_entry`) with `localStorage` as a fallback for non-desktop runtimes. - Extend the Tauri backend (`src-tauri/src/main.rs`) to provide file-backed JSON cache storage under app data and register `read_cache_entry` and `write_cache_entry` handlers. - Wire persistent fallbacks into runtime services: RSS feeds (`src/services/rss.ts`), cached risk scores (`src/services/cached-risk-scores.ts`), earthquake overlay data (`src/services/earthquakes.ts`), and the Insights world-brief snapshot (`src/components/InsightsPanel.ts`). - Enhance circuit-breaker semantics in `src/utils/circuit-breaker.ts` to track `BreakerDataState` (modes: `live` / `cached` / `unavailable`) and detect desktop offline mode so callers can show more precise status and use cached fallbacks. - Add panel-level data-state badges and helpers in `src/components/Panel.ts` and apply them to `NewsPanel`, `InsightsPanel`, and `StrategicRiskPanel`, plus styling in `src/styles/main.css`. - Include static resources in desktop bundle config by adding `../data` and `../src/config` to `src-tauri/tauri.conf.json` so pre-bundled datasets are available in production desktop builds. ### Testing - Ran `npm run typecheck` (`tsc --noEmit`) which completed successfully. - Started the dev server and exercised the UI; captured a screenshot demonstrating panel freshness badges (artifact recorded during the run). - `cargo check` could not complete in this environment due to network/crates.io access being blocked (error: CONNECT tunnel failed / 403), so native Rust/Tauri build verification was not possible here. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_698eb89d5b448333b14174125f76d3c4)
Motivation
live,cached, orunavailablein panels so analysts understand what they are seeing.Description
src/services/persistent-cache.ts) that uses Tauriinvokecommands (read_cache_entry/write_cache_entry) withlocalStorageas a fallback for non-desktop runtimes.src-tauri/src/main.rs) to provide file-backed JSON cache storage under app data and registerread_cache_entryandwrite_cache_entryhandlers.src/services/rss.ts), cached risk scores (src/services/cached-risk-scores.ts), earthquake overlay data (src/services/earthquakes.ts), and the Insights world-brief snapshot (src/components/InsightsPanel.ts).src/utils/circuit-breaker.tsto trackBreakerDataState(modes:live/cached/unavailable) and detect desktop offline mode so callers can show more precise status and use cached fallbacks.src/components/Panel.tsand apply them toNewsPanel,InsightsPanel, andStrategicRiskPanel, plus styling insrc/styles/main.css.../dataand../src/configtosrc-tauri/tauri.conf.jsonso pre-bundled datasets are available in production desktop builds.Testing
npm run typecheck(tsc --noEmit) which completed successfully.cargo checkcould not complete in this environment due to network/crates.io access being blocked (error: CONNECT tunnel failed / 403), so native Rust/Tauri build verification was not possible here.Codex Task