Devtools
@sh1n4ps/plasma-devtools は、実行中の plasma クライアントを検査する 3 つの方法を提供します:
PlasmaDevtools— 開発中にアプリに配置する React パネルコンポーネント。useDevtoolsSnapshot— 独自のパネルを構築したい場合に、現在の sync 状態を返す hook。attachDevtoolsBridge— Chrome DevTools 拡張機能(または任意の外部インスペクタ)向けのwindow.postMessageブリッジ。
インストール
Section titled “インストール”pnpm add @sh1n4ps/plasma-devtoolsアプリの他の部分を変更する必要はありません。
PlasmaDevtools — ページ内パネル
Section titled “PlasmaDevtools — ページ内パネル”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} /> )} </> )}このパネルは:
- 右下隅に小さなバッジ(
plasma · N⏳)としてドッキングします。 - 展開すると以下を表示します:
- 現在の
clientID/clientGroupID - pull cookie(base64 ペイロード)
schemaVersion- outbox の深さ + 個別のエントリリスト
- 最近の
onErrorイベント
- 現在の
プロダクションに出荷されないよう import.meta.env.DEV の背後にゲートしてください。
useDevtoolsSnapshot — hook
Section titled “useDevtoolsSnapshot — hook”独自のパネルやステータスウィジェットを構築するため:
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> )}DevtoolsSnapshot を返します:
interface DevtoolsSnapshot { readonly clientID: string | null readonly cookie: string | null readonly outbox: readonly MutationEnvelope[] readonly schemaVersion: string | null}IndexedDB は変更ストリームを安価に公開しないため、この hook は refreshIntervalMs(デフォルト 500ms)で IDB をポーリングします。より速いフィードバックが欲しければ間隔を調整してください(隠しバッジには 25ms で十分、可視パネルには 500ms で十分です)。
attachDevtoolsBridge — postMessage ブリッジ
Section titled “attachDevtoolsBridge — postMessage ブリッジ”ページの外側からクライアントを観測・制御したい Chrome DevTools 拡張機能(または任意の外部インスペクタ)向け:
import { attachDevtoolsBridge } from "@sh1n4ps/plasma-devtools"
const dispose = attachDevtoolsBridge(client, { dbName: "todos", schema, refreshIntervalMs: 500,
// このオリジンにのみメッセージを送る(デフォルト: "*")。 // プロダクションの機密性のために拡張機能のオリジンに絞る。 targetOrigin: "*",
// どのオリジンがコマンドメッセージを送れるか(デフォルト: // "same-origin")。拡張機能のオリジンの配列に設定するか、 // どこからでもコマンドを受け入れるなら "*"。 allowedOrigins: "same-origin",})
// 後でdispose()ブリッジは window.postMessage を介して 4 種類のメッセージを送ります:
| 方向 | 種類 | 目的 |
|---|---|---|
| page → extension | hello |
アタッチ時の「ランタイム存在」アナウンス |
| page → extension | state-update |
sync 状態のスナップショット(refreshIntervalMs ごと) |
| extension → page | command |
アクションのリクエスト: flush、pull、reset-local-state、ping |
| page → extension | command-result |
先の command に対する OK/error レスポンス、requestId でキー付け |
すべてのメッセージの source フィールドは "plasma-devtools" なので、受信側は無関係なメッセージをフィルタできます:
window.addEventListener("message", (event) => { if (!isDevtoolsMessage(event.data)) return // ... plasma-devtools メッセージを処理})拡張機能の構築
Section titled “拡張機能の構築”拡張機能側は @sh1n4ps/plasma-devtools には含まれていません(別の Chrome 拡張機能プロジェクトです)。構築するには:
- content script が
plasma-devtoolsメッセージのリスナーを注入します。 postMessageを介してコマンドを送り返します。state-updateペイロードを使って DevTools パネルをレンダリングします。
プロトコルの型はすべて @sh1n4ps/plasma-devtools からエクスポートされています:
import type { DevtoolsStateSnapshot, StateUpdateMessage, CommandMessage, CommandResultMessage, HelloMessage, DevtoolsMessage,} from "@sh1n4ps/plasma-devtools"リスナーでユニオン型を使い、TypeScript にすべての分岐を網羅的にチェックさせてください。
次に読むべきもの
Section titled “次に読むべきもの”- Concepts / Change Log and Cookies — パネルが表面化する sync 状態
- Testing — パネルは開発専用; テストは同じ状態をプログラム的にカバーする