A transport is the channel expose() talks over. osra accepts the platform objects below directly; anything else can be wrapped in a plain { emit, receive } pair.
Transports are either structured-clone (Worker, Window, MessagePort, SharedWorker) or JSON (WebSocket, web extension messaging, custom transports with isJson: true). JSON mode forces JSON-safe boxing: values that depend on structured clone (RegExp, SharedArrayBuffer, ImageBitmap, …) are rejected at the type level, while everything with a dedicated revivable module (Date, Map, ArrayBuffer via base64, functions, streams, …) still works. osra only stringifies envelopes itself on WebSocket; custom function emitters handle their own serialization. See JSON vs clone for exactly what degrades, and supported types for the full matrix.
WebExtension runtime / Port / onConnect / onMessage
JSON
runtime/onConnect are identity-matched against the browser/chrome global; Port/onMessage are detected purely structurally and work without the global (lookalike objects can misclassify as these).
Pass the Worker on the page side and globalThis (the DedicatedWorkerGlobalScope) inside the worker — the worker scope isn’t part of the Transport type union, so cast it:
message events fire on the window that receives them, so each side pairs the other window for emit with its own window for receive. origin is applied in both directions: outbound it is the postMessagetargetOrigin, inbound it drops events whose event.origin differs. Set it whenever you talk across origins — see security for the trust model and the one announce-beacon exception.
// parent
const
constiframe:HTMLIFrameElement
iframe=
var document:Document
window.document returns a reference to the document contained in the window.
Pass the SharedWorker instance directly on the page side; osra rides its .port internally. Inside the worker, expose per connected port:
// page
const
constsharedWorker:SharedWorker
sharedWorker=new
var SharedWorker:new (scriptURL:string|URL, options?:string|WorkerOptions) =>SharedWorker
The SharedWorker interface represents a specific kind of worker that can be accessed from several browsing contexts, such as several windows, iframes or even workers.
JSON mode. You can expose() while the socket is still CONNECTING; outbound envelopes queue until open. The other end is anything that relays frames to a peer also running osra:
const
constsocket:WebSocket
socket=new
var WebSocket:new (url:string|URL, protocols?:string|string[]) =>WebSocket
The WebSocket object provides the API for creating and managing a WebSocket connection to a server, as well as for sending and receiving data on the connection.
A ServiceWorker can only emit and a ServiceWorkerContainer can only receive, so combine them as a custom pair:
const
constregistration:ServiceWorkerRegistration
registration=await
var navigator:Navigator
The Window.navigator read-only property returns a reference to the Navigator object, which has methods and properties about the application running the script.
The serviceWorker read-only property of the Navigator interface returns the ServiceWorkerContainer object for the associated document, which provides access to registration, removal, upgrade, and communication with the ServiceWorker.
Available only in secure contexts.
The Window.navigator read-only property returns a reference to the Navigator object, which has methods and properties about the application running the script.
The serviceWorker read-only property of the Navigator interface returns the ServiceWorkerContainer object for the associated document, which provides access to registration, removal, upgrade, and communication with the ServiceWorker.
Available only in secure contexts.
JSON mode. runtime.Port, the runtime itself (sendMessage/onMessage), onConnect, and onMessage are all accepted:
// content script
const
constport:Runtime.Port
port=
constbrowser:Browser
browser.
Browser.Browser.runtime: Runtime.Static
Use the browser.runtime API to retrieve the background page, return details about the manifest,
and listen for and respond to events in the app or extension lifecycle. You can also use this API to convert the
relative path of URLs to fully-qualified URLs.
Attempts to connect to connect listeners within an extension/app (such as the background page), or other extensions/apps.
This is useful for content scripts connecting to their extension processes, inter-app/extension communication,
and $(topic:manifest/externally_connectable)[web messaging]. Note that this does not connect to any listeners in a
content script. Extensions may connect to content scripts embedded in tabs via $(ref:tabs.connect).
@param ― extensionId Optional. The ID of the extension or app to connect to. If omitted,
a connection will be attempted with your own extension. Required if sending messages from a web page for
$(topic:manifest/externally_connectable)[web messaging].
@param ― connectInfo Optional.
@returns ― Port through which messages can be sent and received. The port's $(ref:runtime.Port.onDisconnect)
event is fired if the extension/app does not exist.
Use the browser.runtime API to retrieve the background page, return details about the manifest,
and listen for and respond to events in the app or extension lifecycle. You can also use this API to convert the
relative path of URLs to fully-qualified URLs.