Usage: DevTools Panel
Relevant source files
The following files were used as context for generating this wiki page:
The webext-bridge library provides a dedicated entry point for use within a browser extension's DevTools panel. This module simplifies communication between the DevTools context and other parts of the extension, such as the background script or content scripts. It establishes a reliable messaging channel that abstracts away the complexities of runtime.Port management and message routing.
The DevTools module is designed to be self-contained, offering the standard sendMessage, onMessage, and stream APIs (openStream, onOpenStreamChannel) scoped to the DevTools context. It automatically handles the connection to the background script, which acts as a central message broker for the entire extension.
Sources: src/devtools.ts, README.md:12-14
Architecture and Initialization
The DevTools bridge is initialized by importing from webext-bridge/devtools. This setup involves creating a persistent connection to the background script and wrapping it with a runtime environment that provides the high-level messaging API.
Sources: src/devtools.ts, package.json:28-31
Core Components
The initialization in src/devtools.ts orchestrates several key components:
- Persistent Port (
createPersistentPort): Establishes and maintains a long-lived connection to the background script. This is crucial for Manifest V3, where the background service worker can be terminated. The persistent port automatically reconnects if the connection is lost. - Endpoint Runtime (
createEndpointRuntime): Creates the user-facing API (sendMessage,onMessage) for thedevtoolscontext. It manages message transactions, listeners, and routes outgoing messages to the persistent port. - Stream Wirings (
createStreamWirings): Builds the stream-based communication API (openStream,onOpenStreamChannel) on top of the endpoint runtime.
The following diagram illustrates the initialization flow within the DevTools panel.
This diagram shows the setup process inside the DevTools script, leading to the exported API.
Sources: src/devtools.ts:1-12
Connection to Background Script
The connection to the background script is established using browser.runtime.connect. A unique port name is generated to identify the specific DevTools panel instance. The name is formatted as devtools@<tabId>, where <tabId> is the ID of the inspected window's tab.
// src/devtools.ts:5
const port = createPersistentPort(`devtools@${browser.devtools.inspectedWindow.tabId}`)
This naming convention allows the background script to identify the origin of messages and route replies or new messages back to the correct DevTools panel. The background script maintains a map of all active connections (connMap) keyed by these unique endpoint names.
Sources: src/devtools.ts:5, src/background.ts:22, 245-251
The createPersistentPort function ensures this connection is resilient. If the background service worker is terminated and restarted, the port will automatically attempt to reconnect and sync its state, re-queuing any undelivered messages.
Sources: src/internal/persistent-port.ts:21-25, 120-134
Message Flow
All messages sent from the DevTools panel are routed through the background script. The background script acts as a central hub, forwarding the message to its final destination.
Sending a Message
When sendMessage is called from the DevTools panel, the following sequence occurs:
- The
endpointRuntimein DevTools creates anInternalMessageobject, assigning a uniquetransactionId. - This message is passed to the
routeMessagefunction, which isport.postMessage. - The
persistent-portwraps the message in a{ type: 'deliver', message }object and sends it to the background script. - The background script's
onConnectlistener receives the message. It identifies the sender using the port's name (devtools@<tabId>). - The background script's
endpointRuntimeresolves the destination and forwards the message to the appropriate connection in itsconnMap. - A
deliveredstatus message is sent back to the originating DevTools port to confirm receipt by the background script.
The sequence diagram below visualizes this flow.
This diagram shows the full round-trip of a message initiated from the DevTools panel.
Sources: src/internal/endpoint-runtime.ts:182-211, src/internal/persistent-port.ts:140-145, src/background.ts:151-186, 303-311
Stream Communication
In addition to one-off messaging, the DevTools bridge supports persistent, duplex communication channels called Streams. The openStream and onOpenStreamChannel functions are available for this purpose.
| Function | Description |
|---|---|
openStream | Initiates a new stream channel to a specified destination. Returns a Stream object. |
onOpenStreamChannel | Registers a listener that fires when another context attempts to open a stream to the DevTools panel. |
Sources: src/devtools.ts:12, src/internal/stream.ts:140-161
Opening a Stream
To open a stream from DevTools to another context (e.g., the background script):
- The DevTools panel calls
openStream('my-channel', 'background'). - A
Streaminstance is created locally. - A special message with ID
__crx_bridge_stream_open__is sent to the destination. - The destination's
onOpenStreamChannellistener for'my-channel'is triggered. - The listener receives a
Streamobject, completing the connection. Both sides can now usestream.send()andstream.onMessage().
The following flowchart shows the stream initiation process.
This diagram shows the handshake process for establishing a stream between the DevTools panel and a destination.
Sources: src/internal/stream.ts:140-153
Exported API
The webext-bridge/devtools module exports a set of functions for immediate use.
| Export | Type | Description | Source File |
|---|---|---|---|
sendMessage | function | Sends a message and returns a Promise that resolves with the response. | src/internal/endpoint-runtime.ts |
onMessage | function | Registers a listener to handle incoming messages for a specific message ID. | src/internal/endpoint-runtime.ts |
openStream | function | Opens a persistent, named communication channel to another context. | src/internal/stream.ts |
onOpenStreamChannel | function | Listens for incoming stream requests on a specific channel name. | src/internal/stream.ts |
Sources: src/devtools.ts:11-12
This consistent API allows developers to write communication logic in the DevTools panel in the same way they would for a popup, options page, or content script, with webext-bridge handling the underlying transport details.