Skip to content

fix(browser): keep a reset from another tab from being undone - #44

Merged
leoisadev1 merged 2 commits into
mainfrom
bg0/review-followups-10
Sep 29, 2026
Merged

leoisadev1 merged 2 commits into
mainfrom
bg0/review-followups-10

Conversation

@leoisadev1

@leoisadev1 leoisadev1 commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #43, fixing the gap Devin and Greptile both reported there. A tab whose IndexedDB model cache had not opened yet never learned about another tab's reset. Its reset count is local to the page, and a versionchange only reaches open connections. Its first write then recreated the deleted database and stored the model again.

Each reset now also writes a new random value to a localStorage key that every tab shares. A cache created before that value changed stays empty, as it already did after a reset in its own page. The key holds no image or model data. The value is written only where IndexedDB exists. Without localStorage, such as in some privacy modes, only resets in the same page are seen, as before.

Another tab can also reset between a cache's check and its open request. The open then lands after the delete, and no version change arrives. So the cache checks the mark again once the open succeeds, and closes the connection if a reset happened.

Two new cache tests load a second copy of the module to stand in for another tab. One resets before the cache opens and fails on main. The other resets between the check and the open request, and it fails without the second check.

I checked it in headless Chrome with two real tabs sharing an origin, over plain http on this machine's Tailscale address. Tab A stored a model and created a second cache without opening it. Tab B reset. Tab A then wrote through the unopened cache. With main's module, a new cache in tab A read the model back. With this change, it did not.

I also ran the remover on WASM from this branch's build over the same origin, so it used IndexedDB after that reset marker was set. The first image processed in 61 s, and the PNG has alpha from 0 to 255 with 245,444 fully transparent pixels. After a reload the model sat in IndexedDB (34 entries), and a second image processed in 51 s with no model fetch. Esc returned to the picker, and an unreadable file showed "This image could not be opened. Try exporting it as PNG or JPG."

Not tested: WebGPU, iOS, and the Cache API path, which this change does not touch. Root lint, typecheck, test (202 browser, 98 web) and build pass.

Created with Claude Opus 5.5 in Claude Code.

🤖 Generated with Claude Code

A tab whose IndexedDB model cache had not opened yet never heard about
another tab's reset: its reset count is local and no version change
reaches a cache without a connection. Its first write then recreated
the deleted database and stored the model again.

Each reset now also writes a new value to a shared localStorage key,
and a cache created before that value changed stays empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
bg0-web Ready Ready Preview Sep 29, 2026 7:07pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
bg0-docs Skipped Skipped Sep 29, 2026 7:07pm UTC

Request Review

devin-ai-integration[bot]

This comment was marked as resolved.

Another tab can reset between a cache's reset check and its open
request, so the open lands after the delete and no version change
arrives. The cache now checks the mark again once the open succeeds,
and closes the connection if a reset happened.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel
vercel Bot temporarily deployed to Preview – bg0-docs September 29, 2026 19:06 Inactive
@leoisadev1
leoisadev1 merged commit 420442c into main Sep 29, 2026
6 checks passed
@leoisadev1
leoisadev1 deleted the bg0/review-followups-10 branch September 29, 2026 19:08
@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium risk] Fixes cross-tab cache reset coordination in the browser storage layer.

The reproduced cache-reset issue is non-blocking; it does not make the PR unsafe to merge.

Fix All in Claude CodeFindings

  1. P2 Reset Can Leave Models Cached ▶

Summary

The PR adds a shared reset marker so an unopened IndexedDB cache can detect a reset from another tab, and rechecks the marker after opening. A reset can still leave a model cached: while deletion is blocked, a fresh cache can accept the new marker, queue a write, and store the model after deletion succeeds.

Reviews (1) · Last reviewed commit: "fix(browser): recheck the reset mark onc..."

Comment thread packages/browser/src/cache.ts
@greptile-apps

greptile-apps Bot commented Sep 29, 2026

Copy link
Copy Markdown

Comments Outside Diff

These findings could not be posted inline.

  • P2 Reset mark allows a fresh cache to write after database deletion ▶

    • Bug
      • While one tab holds a database connection, a second tab starts a reset and publishes the mark. A third tab creates a cache using that mark and queues an open behind the blocked deletion. After the connection closes and deletion succeeds, the queued open recreates the database and writes the model; a fourth tab reads it. The reset therefore does not leave the cache cleared.
    • Cause
      • In packages/browser/src/cache.ts:235-240, clearIndexedDbCache publishes the mark before deletion finishes. The fresh cache captures that same mark at line 110, so the checks at lines 119 and 127 accept its post-deletion connection.
    • Fix
      • Coordinate cache creation with an in-progress reset across tabs, or publish a completion mark after deletion and reject or discard opens and writes queued during the reset. Verify the behavior when deletion is blocked.

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – bg0-web — 1cc25c5f Deployed Sep 29, 2026 by vercel[bot]
Preview – bg0-docs — 1cc25c5f Deployed Sep 29, 2026 by vercel[bot]
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