Skip to content

fix(tanstack-query-plugin): resync the panel after an app reload - #392

Merged
V3RON merged 1 commit into
mainfrom
fix/tanstack-query-plugin-reload-sync
Aug 12, 2026
Merged

fix(tanstack-query-plugin): resync the panel after an app reload#392
V3RON merged 1 commit into
mainfrom
fix/tanstack-query-plugin-reload-sync

Conversation

@V3RON

@V3RON V3RON commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes the TanStack Query panel staying empty after an app reload until the app is killed and relaunched.

  • The device now sends a device-ready event once its message handlers are registered.
  • The panel pulls the cache again when it receives that event, clearing what it holds first so it does not render queries from the previous JS context.

Related Issue

Closes #391

Context

PluginView destroys and recreates the panel iframe on every execution-context cycle, so the panel restarts empty on each reload. BackendExecutionContextCreated fires as soon as the new JS context exists — before the app's React tree mounts useTanStackQueryDevTools — so the recreated panel's single request-initial-data message usually arrives while useHandleInitialData has not registered its handler yet, and RozeniteDevToolsClient drops it. Nothing asks again.

device-ready is sent from useHandleInitialData, which runs last in useTanStackQueryDevTools, 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 on device-ready. Verified it fails against main (expected [...] to have a length of 2 but got 1).
  • pnpm --filter @rozenite/tanstack-query-plugin typecheck
  • pnpm --filter @rozenite/tanstack-query-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.

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.
@V3RON
V3RON merged commit 55e47d0 into main Aug 12, 2026
4 checks passed
@V3RON
V3RON deleted the fix/tanstack-query-plugin-reload-sync branch August 12, 2026 11:04
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.

tanstack-query-plugin: panel stays empty after an app reload

1 participant