Usage: Options Page
Relevant source files
The following files were used as context for generating this wiki page:
The webext-bridge library provides a dedicated module for use within an extension's options page. This module simplifies communication between the options page and other extension contexts, primarily the background script. It abstracts the complexities of runtime.connect and message routing, offering a consistent API for sending messages and establishing continuous data streams.
The options page entry point is explicitly defined in the project's package.json, making it available for import as webext-bridge/options. This ensures that the correct, context-aware implementation of the bridge is used.
Sources: README.md:14-16, src/options.ts, package.json:30-33
Architecture and Initialization
The options page module is initialized by importing from webext-bridge/options. This import sets up the necessary components to establish and manage communication. The core logic resides in src/options.ts, which orchestrates three key internal modules.
Sources: src/options.ts:1-12
The initialization process involves these main steps:
createPersistentPort('options'): A persistent connection to the background script is established. This port is designed to automatically reconnect if the background service worker is terminated, which is a common occurrence in Manifest V3 extensions.createEndpointRuntime('options', ...): A runtime environment for the'options'context is created. It is responsible for managing message transactions, routing outgoing messages through the persistent port, and dispatching incoming messages to the correct listeners.createStreamWirings(endpointRuntime): This enhances the endpoint runtime with stream capabilities, allowing for the creation of long-lived, namespaced communication channels.
The following diagram illustrates the initialization flow within the options page script.
Communication with Background Script
Communication from the options page to other parts of the extension is funneled through the background script. The createPersistentPort function is central to this process.
Sources: src/options.ts:5, src/internal/persistent-port.ts
Persistent Port Connection
The createPersistentPort utility creates a wrapper around browser.runtime.connect. It is given the name 'options' to identify itself to the background script. Its key feature is persistence: if the port disconnects (e.g., due to the background service worker being terminated), it automatically attempts to reconnect. This ensures that the communication channel remains available without manual intervention.
Upon connection, the port sends a sync message to the background script to synchronize the state of any undelivered messages or pending responses.
The sequence diagram below shows how the options page establishes its connection with the background script.
Message Handling
Message handling is managed by the EndpointRuntime, which provides the sendMessage and onMessage APIs.
Sources: src/options.ts:6-9, src/internal/endpoint-runtime.ts
Outgoing Messages
When sendMessage is called from the options page, the EndpointRuntime creates an InternalMessage object. This object contains the payload, destination, a unique transaction ID, and origin information. The message is then passed to the routeMessage function, which, for the options context, is a wrapper around port.postMessage. The message is sent through the persistent port to the background script for routing.
Incoming Messages
The persistent port listens for messages from the background script via port.onMessage. When a message arrives, it is passed to endpointRuntime.handleMessage. The runtime checks if the message's destination is the 'options' context. If so, it finds the corresponding listener registered with onMessage and executes its callback. If the message was a request expecting a reply, the return value of the callback is packaged into a reply message and sent back to the original sender.
The following flowchart details how the EndpointRuntime processes an incoming message.
Exposed API
The webext-bridge/options module exports four main functions for developers to use.
| Function | Description | Source File |
|---|---|---|
sendMessage | Sends a message to a specific destination and returns a Promise that resolves with the response. | src/internal/endpoint-runtime.ts |
onMessage | Registers a callback function to handle incoming messages with a specific ID. Returns an unsubscribe function. | src/internal/endpoint-runtime.ts |
openStream | Establishes a long-lived, namespaced communication channel (a Stream) with another endpoint. | src/internal/stream.ts |
onOpenStreamChannel | Registers a callback to accept incoming stream requests on a specific channel name. | src/internal/stream.ts |
Sources: src/options.ts:12, src/internal/endpoint-runtime.ts:138-163, src/internal/stream.ts:149-166
Stream Communication
For continuous, two-way communication, webext-bridge provides Streams. The openStream and onOpenStreamChannel functions, created by createStreamWirings, facilitate this.
A stream is initiated by calling openStream with a channel name and a destination. This sends a special __crx_bridge_stream_open__ message. The receiving context must have a listener registered via onOpenStreamChannel for the same channel name to accept the connection and establish the stream. Once established, both sides can use the stream.send() and stream.onMessage() methods to communicate.
This diagram shows the process of opening a stream from the options page to the devtools page.
Sources: src/internal/stream.ts:124-166
Summary
The webext-bridge/options module provides a robust and developer-friendly way to handle communication from an extension's options page. By leveraging a persistent port for Manifest V3 compatibility and a unified runtime for message and stream handling, it abstracts away the underlying browser APIs. This allows developers to focus on application logic, using a simple, promise-based API (sendMessage, onMessage) and a powerful streaming system (openStream) to communicate with other parts of the extension.
Sources: src/options.ts, README.md:14-16