fix(tanstack-query-plugin): resync the panel after an app reload - #392
Merged
Conversation
The panel iframe is recreated on every reload and asks for the cache before the app's React tree has mounted the plugin, so its single request-initial-data message is dropped and the panel stays empty. The device now announces itself once its handlers are registered, and the panel clears its stale cache and pulls again in response.
V3RON
added a commit
that referenced
this pull request
Aug 12, 2026
## Description Fixes the Storage panel coming back empty after an app reload, stuck on `Waiting for storages…` until the app is killed and relaunched. - The device now sends a `device-ready` event once its message handlers are registered. - The panel re-runs discovery when it receives that event, and resets its query cache so it does not render entries read from the previous JS context. ## Related Issue Closes #389 ## Context `PluginView` destroys and recreates the panel iframe on every execution-context cycle, so the panel restarts with no descriptors on each reload. `BackendExecutionContextCreated` fires as soon as the new JS context exists — before the app's React tree mounts `useRozeniteStoragePlugin` — so the recreated panel's single `discover-storages` request usually arrives while the device has no listener registered, and `RozeniteDevToolsClient` drops it. Discovery uses `client.send` rather than `client.request`, so there is no timeout to surface the loss either, and nothing asks again. This is a regression from #341, which replaced the device's push-on-mount snapshot with panel-initiated discovery. That earlier flow was ordering-independent, and `device-ready` restores that property without giving up the pull-based data path: it is a bare signal, so discovery logic stays in one place and no entries are read speculatively. `device-ready` is sent after the handler subscriptions are created, so a panel reacting to it is guaranteed to be answered. The panel subscribes before it sends its own first request, so the reverse ordering is covered too — whichever side is late, one of the two paths lands. The same race exists in `@rozenite/tanstack-query-plugin`; it is fixed separately in #392. ## Testing - `pnpm --filter @rozenite/storage-plugin test` — 194 tests passed, including a new regression guard in `panel.test.tsx` that asserts the panel runs discovery again on `device-ready`. Verified it fails against `main` (`expected [...] to have a length of 2 but got 1`). - `pnpm --filter @rozenite/storage-plugin typecheck` - `pnpm --filter @rozenite/storage-plugin lint` - `pnpm format:all` Not verified on a device or emulator — the diagnosis and fix were derived from the panel/runtime lifecycle and reproduced with a message-level harness.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes the TanStack Query panel staying empty after an app reload until the app is killed and relaunched.
device-readyevent once its message handlers are registered.Related Issue
Closes #391
Context
PluginViewdestroys and recreates the panel iframe on every execution-context cycle, so the panel restarts empty on each reload.BackendExecutionContextCreatedfires as soon as the new JS context exists — before the app's React tree mountsuseTanStackQueryDevTools— so the recreated panel's singlerequest-initial-datamessage usually arrives whileuseHandleInitialDatahas not registered its handler yet, andRozeniteDevToolsClientdrops it. Nothing asks again.device-readyis sent fromuseHandleInitialData, which runs last inuseTanStackQueryDevTools, so a panel reacting to it is guaranteed to find every handler listening. The panel subscribes before it sends its own first request, so the reverse ordering is covered too — whichever side is late, one of the two paths lands.The same race affects
@rozenite/storage-plugin; it is fixed separately in #390.Testing
pnpm --filter @rozenite/tanstack-query-plugin test— 20 tests passed, including a new regression guard asserting the panel re-requests and drops its stale cache ondevice-ready. Verified it fails againstmain(expected [...] to have a length of 2 but got 1).pnpm --filter @rozenite/tanstack-query-plugin typecheckpnpm --filter @rozenite/tanstack-query-plugin lintpnpm format:allNot verified on a device or emulator — the diagnosis and fix were derived from the panel/runtime lifecycle and reproduced with a message-level harness.