Devtools
@sh1n4ps/plasma-devtools gives you three ways to inspect a running plasma
client:
PlasmaDevtools— a React panel component you drop into your app during development.useDevtoolsSnapshot— a hook that returns the current sync state, if you want to build your own panel.attachDevtoolsBridge— awindow.postMessagebridge for a Chrome DevTools extension (or any external inspector).
Install
Section titled “Install”pnpm add @sh1n4ps/plasma-devtoolsNothing else in your app needs to change.
PlasmaDevtools — the in-page panel
Section titled “PlasmaDevtools — the in-page panel”import { PlasmaDevtools } from "@sh1n4ps/plasma-devtools"import { plasma } from "./main"
function App() { return ( <> <YourAppUI /> {import.meta.env.DEV && ( <PlasmaDevtools client={plasma} dbName="todos" schema={schema} /> )} </> )}The panel:
- Docks to the bottom-right corner as a small badge (
plasma · N⏳). - Expands to show:
- Current
clientID/clientGroupID - Pull cookie (base64 payload)
schemaVersion- Outbox depth + individual entry list
- Recent
onErrorevents
- Current
Gate it behind import.meta.env.DEV so it doesn’t ship to production.
useDevtoolsSnapshot — the hook
Section titled “useDevtoolsSnapshot — the hook”For building your own panel or a status widget:
import { useDevtoolsSnapshot } from "@sh1n4ps/plasma-devtools"
function SyncStatus() { const snap = useDevtoolsSnapshot(client, { dbName: "todos", schema, refreshIntervalMs: 500, }) return ( <div> Outbox: {snap.outbox.length}<br /> Cookie: {snap.cookie ?? "none"}<br /> Client: {snap.clientID ?? "..."}<br /> </div> )}Returns a DevtoolsSnapshot:
interface DevtoolsSnapshot { readonly clientID: string | null readonly cookie: string | null readonly outbox: readonly MutationEnvelope[] readonly schemaVersion: string | null}The hook polls IDB on refreshIntervalMs (default 500ms) because
IndexedDB doesn’t surface a change stream cheaply. Adjust the
interval if you want faster feedback (25ms is fine for a hidden
badge; 500ms is fine for a visible panel).
attachDevtoolsBridge — the postMessage bridge
Section titled “attachDevtoolsBridge — the postMessage bridge”For a Chrome DevTools extension (or any external inspector) that wants to observe and control the client from outside the page:
import { attachDevtoolsBridge } from "@sh1n4ps/plasma-devtools"
const dispose = attachDevtoolsBridge(client, { dbName: "todos", schema, refreshIntervalMs: 500,
// Post messages only to this origin (default: "*"). Narrow to the // extension's origin for production sensitivity. targetOrigin: "*",
// Which origins may SEND command messages to us (default: // "same-origin"). Set to an array of extension origins, or "*" if // you truly accept commands from anywhere. allowedOrigins: "same-origin",})
// laterdispose()The bridge sends four message kinds via window.postMessage:
| Direction | Kind | Purpose |
|---|---|---|
| page → extension | hello |
“Runtime present” announcement on attach |
| page → extension | state-update |
Snapshot of sync state (every refreshIntervalMs) |
| extension → page | command |
Request an action: flush, pull, reset-local-state, ping |
| page → extension | command-result |
OK/error response for a prior command, keyed by requestId |
The source field on every message is "plasma-devtools" so
receivers can filter unrelated messages:
window.addEventListener("message", (event) => { if (!isDevtoolsMessage(event.data)) return // ... handle the plasma-devtools message})Building an extension
Section titled “Building an extension”The extension side isn’t shipped in @sh1n4ps/plasma-devtools (it’s a
separate Chrome extension project). To build one:
- Content script injects a listener for
plasma-devtoolsmessages. - Sends commands back via
postMessage. - Renders a DevTools panel using the
state-updatepayloads.
The protocol types are all exported from @sh1n4ps/plasma-devtools:
import type { DevtoolsStateSnapshot, StateUpdateMessage, CommandMessage, CommandResultMessage, HelloMessage, DevtoolsMessage,} from "@sh1n4ps/plasma-devtools"Use the union type in your listener and let TypeScript exhaustively check every branch.
What to read next
Section titled “What to read next”- Concepts / Change Log and Cookies — the sync state the panel surfaces
- Testing — the panel is dev-only; testing covers the same state programmatically