Skip to content

Add a "Clear Reference Point Cache" button#19

Open
cs-util wants to merge 1 commit into
mainfrom
r/33
Open

Add a "Clear Reference Point Cache" button#19
cs-util wants to merge 1 commit into
mainfrom
r/33

Conversation

@cs-util
Copy link
Copy Markdown
Contributor

@cs-util cs-util commented May 7, 2026

Add a "Clear Reference Point Cache" button in settings to remove cached reference points across all scenarios. This feature ensures that stale caches are refreshed by re-importing ref points from the corresponding zip recordings.

Related Issue

Closes #

Type of Change

  • Bug fix

  • New feature

  • Refactoring (no behavior change)

  • Documentation update

  • Test improvement

Checklist

  • Tests added/updated for this change

  • Sidecar docs (*.md) updated if behavior changed

  • All tests pass locally (pnpm test in both packages)

  • Commit message follows conventional commits format

  • I have read and agreed to the Contributor License Agreement (a bot will prompt me to sign on this PR if I have not already)

Summary by CodeRabbit

  • New Features

    • Added "Clear Reference Point Cache" option in Settings with a confirmation dialog
    • Removes cached reference point data from all scenarios
    • Automatically re-imports reference points for currently open scenarios
  • Tests

    • Added comprehensive test coverage for cache clearing functionality and UI interactions

Wipes the cached refPoints/ directory across all OPFS scenarios so the
next scenario load re-imports ref points from the read folder's *.zip
recordings. Useful when the OPFS cache becomes stale relative to the
zip files.

- Framework: new clearRefPointsCacheForAllScenarios() in file-system.ts
  (collects per-scenario errors, treats missing caches as no-ops).
- Recorder: new "Cache" section in settings modal with confirm dialog.
- main.ts: re-imports ref points for the active scenario after clearing
  so the H3 proximity cache and 3D/2D markers refresh immediately;
  reports the result via toast.
- Tests: confirm/cancel wiring on the button, framework happy-path test
  for the multi-scenario clear.

Co-authored-by: Copilot <copilot@github.com>
@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
gps-plus-slam 99a7f50 Commit Preview URL

Branch Preview URL
May 07 2026, 04:06 AM

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

📝 Walkthrough

Walkthrough

This PR adds a new maintenance feature to clear cached reference points across all OPFS scenarios. It introduces a core framework function clearRefPointsCacheForAllScenarios(), exposes it in the settings UI via a confirmation dialog, integrates the handler into the main application, and includes comprehensive tests at both framework and UI layers.

Changes

Clear Reference Point Cache

Layer / File(s) Summary
Data Types
src/storage/file-system.ts
Introduces ClearRefPointsCacheResult interface with scenariosScanned, scenariosCleared, and errors[] fields.
Framework Implementation
src/storage/file-system.ts
Adds clearRefPointsCacheForAllScenarios() to iterate all legacy scenario directories, recursively delete each refPoints/ subdirectory, treat missing caches as non-fatal, and return aggregated results with error details.
Framework Documentation
src/storage/file-system.ts.md
Documents the new public API and result shape for cache-clearing operations.
Framework Tests
src/storage/file-system.test.ts
Adds test suite validating zero-scenario reporting and successful refPoints removal across multiple scenarios with post-cleanup directory existence checks.
UI Elements
index.html
Adds "Maintenance / Cache" settings section with descriptive warning and btn-clear-refpoint-cache button.
Settings Modal Logic
src/ui/settings-modal.ts
Extends initSettingsModal to accept optional clearRefPointCacheCallback, wires the button to an async handler, implements confirmation dialog, and invokes the callback on user confirm.
Main Application Wiring
src/main.ts
Imports framework cache-clearing function and scenario handle accessor, implements handleClearRefPointCache() to orchestrate clearing, optionally reload current scenario, and display results via toast; passes handler to settings modal initialization.
UI Tests
src/ui/settings-modal.test.ts
Adds async DOM helpers (waitFor, flush), verifies button presence in production HTML, and tests callback invocation flow (confirm triggers callback, cancel prevents it).

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as Settings Modal
    participant Main as Main App
    participant Storage as OPFS Storage
    participant Toast as Toast Notifier

    User->>UI: Clicks "Clear Cache" button
    UI->>UI: Shows confirmation dialog
    User->>UI: Confirms action
    UI->>Main: Calls handleClearRefPointCache()
    Main->>Storage: clearRefPointsCacheForAllScenarios()
    Storage->>Storage: Iterate all scenarios
    Storage->>Storage: Delete refPoints/ dirs
    Storage-->>Main: Return result (count, errors)
    alt Current scenario loaded
        Main->>Storage: Reload scenario refPoints
        Storage-->>Main: RefPoints reimported
    else No current scenario
        Main->>Main: Clear in-memory refPoints
    end
    Main->>Toast: Show success/empty/failure message
    Main->>Toast: Log outcome
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A fuzzy tale of caches cleared,
Where old ref-points have disappeared!
With button clicks and dialogs bright,
The storage fresh, the paths now light.
A hop, a skip, a cache revived—
The scenario's soul, refreshed alive!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main feature being added: a 'Clear Reference Point Cache' button in the settings UI.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 r/33

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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 and usage tips.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a maintenance feature to clear the cached reference point directory across all scenarios in the Origin Private File System (OPFS), facilitating a fresh re-import from source ZIP recordings. The implementation includes the core logic in the storage framework, a new "Clear Reference Point Cache" button in the recorder app's settings modal with a confirmation dialog, and corresponding unit tests. Feedback suggests refining the in-memory state clearing logic to avoid disrupting the UI when the application is in Replay mode.

Comment on lines +364 to +368
} else {
// No active scenario — clear in-memory imported ref points so any
// proximity checks don't keep referring to stale entries.
refPointHandlers.setImportedRefPoints([]);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Clearing the in-memory imported reference points when no scenario is active will also affect the UI in Replay mode. If a user is currently viewing a replay (which loads ref points from a ZIP, not the OPFS cache), clicking 'Clear Cache' in settings will cause their current replay markers to disappear. Consider checking if the app is in replay mode before clearing the in-memory state.

Suggested change
} else {
// No active scenario — clear in-memory imported ref points so any
// proximity checks don't keep referring to stale entries.
refPointHandlers.setImportedRefPoints([]);
}
} else if (!replayHandlers.getIsReplayMode()) {
// No active scenario and not in replay mode — clear in-memory imported
// ref points so any proximity checks don't keep referring to stale entries.
refPointHandlers.setImportedRefPoints([]);
}

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
GpsPlusSlamJs_RecorderApp/src/ui/settings-modal.ts (1)

141-143: ⚡ Quick win

Guard against concurrent cache-clear requests.

handleClearRefPointCache() can be triggered multiple times before completion, which can run overlapping clears. Add an in-flight guard (and optionally disable the button during execution).

Proposed re-entrancy guard
 let onClearRefPointCache: (() => void | Promise<void>) | null = null;
+let isClearingRefPointCache = false;

 async function handleClearRefPointCache(): Promise<void> {
+  if (isClearingRefPointCache) {
+    log.debug('Clear ref-point cache already in progress');
+    return;
+  }
   if (!onClearRefPointCache) {
     log.warn('Clear ref-point cache requested but no callback is wired');
     return;
   }

+  isClearingRefPointCache = true;
   const confirmed = await showConfirmDialog({
@@
-  try {
+  try {
     await onClearRefPointCache();
     log.info('Ref-point cache cleared');
   } catch (err) {
     log.error('Failed to clear ref-point cache:', err);
+  } finally {
+    isClearingRefPointCache = false;
   }
 }

Also applies to: 478-502

🤖 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 `@GpsPlusSlamJs_RecorderApp/src/ui/settings-modal.ts` around lines 141 - 143,
handleClearRefPointCache can be invoked re-entrantly and must be serialized: add
an in-flight guard (e.g., a boolean like isClearingRefPointCache) scoped near
the UI module and check it at the start of the click handler and inside any
functions that call handleClearRefPointCache; if the guard is true, return
early. When starting the operation set isClearingRefPointCache = true and when
finished (or on error) set it back to false in a finally block, and optionally
disable/enable the btnClearRefPointCache DOM element while the operation runs.
Apply the same guard pattern to the other invocation(s) that call
handleClearRefPointCache so overlapping clears cannot occur.
GpsPlusSlamJs_AppFramework/src/storage/file-system.test.ts (1)

328-361: ⚡ Quick win

Test only verifies cache deletion for one seeded scenario.

The test says “every scenario” but only asserts refPoints removal for ScenarioA (Line 359). Add the same assertion for ScenarioB to validate full behavior.

Proposed test hardening
       const reA = await setCurrentScenario('ScenarioA');
       await expect(reA!.getDirectoryHandle('refPoints')).rejects.toThrow();
+      const reB = await setCurrentScenario('ScenarioB');
+      await expect(reB!.getDirectoryHandle('refPoints')).rejects.toThrow();
🤖 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 `@GpsPlusSlamJs_AppFramework/src/storage/file-system.test.ts` around lines 328
- 361, The test seeds refPoints for both ScenarioA and ScenarioB but only
asserts removal for ScenarioA; update the test in file-system.test.ts to also
verify ScenarioB's refPoints directory was removed by calling
setCurrentScenario('ScenarioB') (e.g., const reB = await
setCurrentScenario('ScenarioB')) and then await
expect(reB!.getDirectoryHandle('refPoints')).rejects.toThrow(); so both seeded
scenarios are validated after clearRefPointsCacheForAllScenarios().
🤖 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 `@GpsPlusSlamJs_AppFramework/src/storage/file-system.ts`:
- Around line 395-405: The function clearRefPointsCacheForAllScenarios currently
proceeds when OPFS root/scenariosDir is unavailable and returns zeroed counts;
instead add a guard at the start of clearRefPointsCacheForAllScenarios that
checks scenariosDir (and any OPFS root dependency) and immediately throw a
descriptive Error (or return a ClearRefPointsCacheResult with an explicit
surfaced error) if it's falsy before calling listScenarios(); update
callers/tests accordingly so they expect the thrown error/explicit failure
rather than a silent no-op.

In `@GpsPlusSlamJs_RecorderApp/src/main.ts`:
- Around line 359-367: When folderManager.loadAndDisplayRefPoints(currentHandle)
throws, the catch only logs the error so stale imported ref points remain;
update the catch block to clear in-memory imported points by calling
refPointHandlers.setImportedRefPoints([]) (and keep the existing log.warn with
the error) so proximity checks won't use stale entries after a failed re-import.

---

Nitpick comments:
In `@GpsPlusSlamJs_AppFramework/src/storage/file-system.test.ts`:
- Around line 328-361: The test seeds refPoints for both ScenarioA and ScenarioB
but only asserts removal for ScenarioA; update the test in file-system.test.ts
to also verify ScenarioB's refPoints directory was removed by calling
setCurrentScenario('ScenarioB') (e.g., const reB = await
setCurrentScenario('ScenarioB')) and then await
expect(reB!.getDirectoryHandle('refPoints')).rejects.toThrow(); so both seeded
scenarios are validated after clearRefPointsCacheForAllScenarios().

In `@GpsPlusSlamJs_RecorderApp/src/ui/settings-modal.ts`:
- Around line 141-143: handleClearRefPointCache can be invoked re-entrantly and
must be serialized: add an in-flight guard (e.g., a boolean like
isClearingRefPointCache) scoped near the UI module and check it at the start of
the click handler and inside any functions that call handleClearRefPointCache;
if the guard is true, return early. When starting the operation set
isClearingRefPointCache = true and when finished (or on error) set it back to
false in a finally block, and optionally disable/enable the
btnClearRefPointCache DOM element while the operation runs. Apply the same guard
pattern to the other invocation(s) that call handleClearRefPointCache so
overlapping clears cannot occur.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2781b11c-6f08-453f-bbab-810e2f40b816

📥 Commits

Reviewing files that changed from the base of the PR and between a7dd6b5 and 99a7f50.

📒 Files selected for processing (7)
  • GpsPlusSlamJs_AppFramework/src/storage/file-system.test.ts
  • GpsPlusSlamJs_AppFramework/src/storage/file-system.ts
  • GpsPlusSlamJs_AppFramework/src/storage/file-system.ts.md
  • GpsPlusSlamJs_RecorderApp/index.html
  • GpsPlusSlamJs_RecorderApp/src/main.ts
  • GpsPlusSlamJs_RecorderApp/src/ui/settings-modal.test.ts
  • GpsPlusSlamJs_RecorderApp/src/ui/settings-modal.ts

Comment on lines +395 to +405
export async function clearRefPointsCacheForAllScenarios(): Promise<ClearRefPointsCacheResult> {
const errors: { scenarioName: string; reason: string }[] = [];
let scenariosCleared = 0;
let scenariosScanned = 0;

const scenarios = await listScenarios();
for (const scenarioName of scenarios) {
scenariosScanned++;
try {
const handle = await scenariosDir?.getDirectoryHandle(scenarioName);
if (!handle) continue;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when storage is unavailable before scanning scenarios.

clearRefPointsCacheForAllScenarios() currently degrades to zero counts if storage isn’t initialized, which can incorrectly report a no-op success path. It should throw (or return a surfaced error) when OPFS root/scenarios dir is unavailable.

Proposed guard
 export async function clearRefPointsCacheForAllScenarios(): Promise<ClearRefPointsCacheResult> {
+  if (!storageInitialized) {
+    throw new Error('Storage not initialized. Call initStorage first.');
+  }
+  const scenRoot = await ensureScenariosDir();
+  if (!scenRoot) {
+    throw new Error('Scenarios directory unavailable.');
+  }
+
   const errors: { scenarioName: string; reason: string }[] = [];
@@
-      const handle = await scenariosDir?.getDirectoryHandle(scenarioName);
+      const handle = await scenRoot.getDirectoryHandle(scenarioName);
       if (!handle) continue;
🤖 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 `@GpsPlusSlamJs_AppFramework/src/storage/file-system.ts` around lines 395 -
405, The function clearRefPointsCacheForAllScenarios currently proceeds when
OPFS root/scenariosDir is unavailable and returns zeroed counts; instead add a
guard at the start of clearRefPointsCacheForAllScenarios that checks
scenariosDir (and any OPFS root dependency) and immediately throw a descriptive
Error (or return a ClearRefPointsCacheResult with an explicit surfaced error) if
it's falsy before calling listScenarios(); update callers/tests accordingly so
they expect the thrown error/explicit failure rather than a silent no-op.

Comment on lines +359 to +367
try {
await folderManager.loadAndDisplayRefPoints(currentHandle);
} catch (err) {
log.warn('Re-import after cache clear failed:', err);
}
} else {
// No active scenario — clear in-memory imported ref points so any
// proximity checks don't keep referring to stale entries.
refPointHandlers.setImportedRefPoints([]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Clear in-memory ref points when post-clear re-import fails.

If folderManager.loadAndDisplayRefPoints(currentHandle) fails, stale imported points remain in memory. That can keep old proximity matches even after cache clear.

Proposed fallback
     if (currentHandle) {
       try {
         await folderManager.loadAndDisplayRefPoints(currentHandle);
       } catch (err) {
         log.warn('Re-import after cache clear failed:', err);
+        refPointHandlers.setImportedRefPoints([]);
       }
     } else {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
await folderManager.loadAndDisplayRefPoints(currentHandle);
} catch (err) {
log.warn('Re-import after cache clear failed:', err);
}
} else {
// No active scenario — clear in-memory imported ref points so any
// proximity checks don't keep referring to stale entries.
refPointHandlers.setImportedRefPoints([]);
try {
await folderManager.loadAndDisplayRefPoints(currentHandle);
} catch (err) {
log.warn('Re-import after cache clear failed:', err);
refPointHandlers.setImportedRefPoints([]);
}
} else {
// No active scenario — clear in-memory imported ref points so any
// proximity checks don't keep referring to stale entries.
refPointHandlers.setImportedRefPoints([]);
🤖 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 `@GpsPlusSlamJs_RecorderApp/src/main.ts` around lines 359 - 367, When
folderManager.loadAndDisplayRefPoints(currentHandle) throws, the catch only logs
the error so stale imported ref points remain; update the catch block to clear
in-memory imported points by calling refPointHandlers.setImportedRefPoints([])
(and keep the existing log.warn with the error) so proximity checks won't use
stale entries after a failed re-import.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant