Skip to content

Port feature from vitejs/devtools#525: mirror the dock panel's localStorage state into shared state #211

Description

@antfubot

Context

vitejs/devtools#525 ("feat(core): mirror the dock panel's localStorage state into shared state") by @dvcolomban made the dock panel's browser-local panelStore (vite-devtools-dock-state) visible to Node-side plugins by mirroring it into rpc.sharedState under the same key, via a new useLocalStorageSharedState helper. It touched packages/core/src/client/inject/runtime.ts in vitejs/devtools, which moved here as part of the v0.9 migration — the equivalent bootstrap today is packages/hub-ui/src/client/embedded/index.ts, and the panelStore/DEFAULT_DOCK_PANEL_STORE it wraps now lives in packages/hub-ui/src/client/state/docks.ts.

Original PR description

Why

panelStore (the vite-devtools-dock-state key) is purely browser-local today — nothing on the Node/server side can see it, including whether the panel is even open. Any Node-side plugin that wants to react to dock UI state — gate some behavior on visibility, log usage, sync it elsewhere — has nothing to observe.

What changed

  • Wraps the existing useLocalStorage call with a small generic helper, useLocalStorageSharedState, that mirrors the whole value into rpc.sharedState under the same key. Shared-state mutations already round-trip through the server before reappearing locally, so that's the entire mechanism — no new dock-entry field, no client-script gating, no RPC command, no trust handshake.
  • Mirrors the whole object rather than cherry-picking open: it's already one useLocalStorage-backed, fully serializable, browser-local singleton (not per-tab), so a second, narrower key for just one field would just be a redundant place for that field to live.

Known limitation, flagging it rather than hiding it: shared state is one authoritative value, last-mutation-wins — with two tabs open, a Node-side consumer watching e.g. open sees whichever tab mutated most recently. Per-connection keying would need a way to garbage-collect a disconnected tab's entry, and nothing in the public API exposes that today, so I went with the simpler singleton.

Diff: https://github.com/vitejs/devtools/pull/525/files

For agents picking this up

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions