Skip to content

Proxy Integration

This document describes how Helium integrates with the proxy stack to implement content script injection, request interception, and navigation event tracking. Helium requires no direct UV/Scramjet hooks or configuration — all integration flows through Reflux (content injection) and a modified BareMux worker (network interception).

Previous designs considered using UV/Scramjet-specific features like config.inject arrays or handler event hooks. These were dropped because:

  1. Scramjet does not support config.inject or equivalent hook points
  2. Proxy coupling limits portability — Helium should work with any BareMux-compatible SW proxy
  3. Reflux already provides @browser injection that works across proxy implementations
  4. BareMux worker is already modified for premium systems and provides a clean network middleware entrypoint
┌─────────────────────────────────────────────────────────────────┐
│ Browser │
│ │
│ Page makes fetch/XHR/navigation request │
└─────────────────────┬───────────────────────────────────────────┘
┌─────────────────────▼───────────────────────────────────────────┐
│ Service Worker │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ UV/Scramjet Handler │ │
│ │ │ │
│ │ 1. Intercept fetch event │ │
│ │ 2. Pass to BareMux transport layer │ │
│ │ 3. Receive response │ │
│ │ 4. Rewrite HTML/JS/CSS content │ │
│ │ 5. Return rewritten response │ │
│ │ │ │
│ │ Helium SW addition: │ │
│ │ - Serve /helium-ext/<id>/<path> from virtual FS │ │
│ │ (This is a fetch handler, not a proxy hook) │ │
│ └──────────────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼──────────────────────────────────┐ │
│ │ BareMux Worker (modified) │ │
│ │ │ │
│ │ Network middleware: │ │
│ │ ├── Helium webRequest plugin (onBeforeRequest, etc.) │ │
│ │ ├── Helium DNR plugin (declarativeNetRequest rules) │ │
│ │ ├── Helium cookie interceptor (Set-Cookie capture) │ │
│ │ └── Other middleware │ │
│ │ │ │
│ │ → Transport fetch (Epoxy/Libcurl) │ │
│ │ │ │
│ │ Response middleware: │ │
│ │ ├── Helium webRequest plugin (onHeadersReceived, etc.) │ │
│ │ ├── Helium cookie interceptor (cookie jar sync) │ │
│ │ └── Other middleware │ │
│ └──────────────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼──────────────────────────────────┐ │
│ │ Reflux MiddlewareTransport │ │
│ │ │ │
│ │ Content injection (response middleware): │ │
│ │ ├── Evaluate URL against content script match patterns │ │
│ │ ├── @browser inject: Helium bootstrap script │ │
│ │ ├── @browser inject: Matching content script CSS │ │
│ │ └── @browser inject: Matching content script JS │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Reflux’s @browser injection mechanism inserts scripts and styles into HTML responses at the middleware transport level. When the response passes through Reflux, Helium’s injection plugin evaluates the target URL against all registered content script match patterns and injects the appropriate code.

// Reflux plugin for content script injection
const heliumInjectionPlugin = {
name: 'helium-content-injection',
version: '1.0.0',
match: { url: '*' },
responseMiddleware: async (response, request, context) => {
// Only process HTML responses
const contentType = response.headers?.['content-type'] || '';
if (!contentType.includes('text/html')) return response;
const url = request.url;
const isMainFrame = context.destination === 'document';
// Get matching content scripts for this URL
const plans = contentScriptInjector.getMatchingScripts(url, isMainFrame);
if (plans.length === 0 && !needsBootstrap(url)) return response;
// Build injection payloads
const injections = await contentScriptInjector.buildInjections(plans);
// Inject via Reflux's @browser mechanism
// Bootstrap is always injected first (document_start)
context.injectBrowser(injections.bootstrap);
// CSS is always injected at document_start
for (const css of injections.css) {
context.injectBrowser(css);
}
// JS injected according to run_at timing
for (const js of injections.js) {
context.injectBrowser(js);
}
return response;
},
};
class ContentScriptInjector {
private registry: RegisteredContentScript[] = [];
/**
* Determine which content scripts to inject for a given URL.
*/
getMatchingScripts(url: string, isMainFrame: boolean): InjectionPlan[] {
const plans: InjectionPlan[] = [];
for (const script of this.registry) {
// 1. Check URL matches
if (!script.matches.matches(url)) continue;
if (script.excludeMatches.matches(url)) continue;
// 2. Check glob patterns
if (script.includeGlobs.size > 0 && !script.includeGlobs.matches(url)) continue;
if (script.excludeGlobs.matches(url)) continue;
// 3. Check frame eligibility
if (!isMainFrame && !script.allFrames) continue;
// 4. Check about:blank handling
if (url === 'about:blank' && !script.matchAboutBlank) continue;
plans.push({
extensionId: script.extensionId,
js: script.js,
css: script.css,
runAt: script.runAt,
world: script.world,
});
}
// Sort by extension ID for deterministic injection order
plans.sort((a, b) => a.extensionId.localeCompare(b.extensionId));
return plans;
}
/**
* Build the actual injection payloads for Reflux @browser injection.
*/
async buildInjections(plans: InjectionPlan[]): Promise<InjectionPayload> {
const result: InjectionPayload = {
bootstrap: this.buildBootstrapScript(plans),
css: [],
js: [],
};
for (const plan of plans) {
// CSS is always injected at document_start (matching Chrome behavior)
for (const cssPath of plan.css) {
const cssContent = await this.readExtensionFile(plan.extensionId, cssPath);
result.css.push({
type: 'style',
content: cssContent,
attributes: {
'data-helium-css': plan.extensionId,
'data-helium-path': cssPath,
},
});
}
// JS injection
for (const jsPath of plan.js) {
const jsContent = await this.readExtensionFile(plan.extensionId, jsPath);
const wrapped = this.wrapContentScript(plan, jsContent);
result.js.push({
type: 'script',
content: wrapped,
runAt: plan.runAt,
attributes: {
'data-helium-cs': plan.extensionId,
'data-helium-world': plan.world || 'ISOLATED',
},
});
}
}
return result;
}
/**
* Wrap a content script for isolated world execution.
*
* IMPORTANT: The wrapped code is NOT injected as a separate <script> tag.
* It is inlined into the bootstrap IIFE (appended at the end) so that it
* can access the closure-scoped `__helium_cs_factory__` variable. Injecting
* it as a separate <script> tag would break scoping — the factory is NOT
* on `window` (by design, to prevent page script access).
*
* The `buildInjections()` method above concatenates all wrapped content
* scripts into the bootstrap script's IIFE body.
*/
private wrapContentScript(plan: InjectionPlan, code: string): string {
if (plan.world === 'MAIN') {
// MAIN world: run directly in page context, no isolation
return code;
}
// ISOLATED world: wrap with Proxy Membrane sandbox
// See EXECUTION-CONTEXTS.md "Isolated World Emulation (Proxy Membrane Sandbox)"
return `(function(chrome, window, document, secureGlobals, undefined) {
'use strict';
var JSON = secureGlobals.JSON;
var Promise = secureGlobals.Promise;
var Map = secureGlobals.Map;
var Set = secureGlobals.Set;
var WeakMap = secureGlobals.WeakMap;
var Reflect = secureGlobals.Reflect;
${code}
})(
__helium_cs_factory__['${plan.extensionId}'].createChrome(),
__helium_cs_factory__['${plan.extensionId}'].membrane(window),
__helium_cs_factory__['${plan.extensionId}'].membrane(document),
__helium_cs_factory__['${plan.extensionId}'].secureGlobals
);`;
}
}

The bootstrap script is injected into every page that has at least one matching content script. It sets up the content script runtime environment:

function buildBootstrapScript(plans: InjectionPlan[], tabId: number): string {
// Pre-compute extension IDs that need chrome API instances
const extensionIds = [...new Set(plans.map(p => p.extensionId))];
// Generate one-time registration tokens per planned content script injection
// The SharedWorker will only accept registrations carrying a valid token
const tokenMap = Object.fromEntries(
extensionIds.map(id => [id, crypto.randomUUID()])
);
return `
(function(__helium_tabId) {
// tabId is injected as a closure parameter — NOT accessible from window
// ============================================================
// PROTOTYPE SNAPSHOT (Layer 1 of Proxy Membrane Sandbox)
// Must execute at document_start, BEFORE any page scripts run.
// ============================================================
var pristine = {
ObjectProto: Object.getPrototypeOf({}),
ArrayProto: Object.getPrototypeOf([]),
FunctionProto: Object.getPrototypeOf(function() {}),
defineProperty: Object.defineProperty,
getOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,
getPrototypeOf: Object.getPrototypeOf,
keys: Object.keys,
assign: Object.assign,
freeze: Object.freeze,
create: Object.create,
Map: Map, Set: Set, WeakMap: WeakMap, WeakRef: WeakRef,
Promise: Promise, Proxy: Proxy, Reflect: Reflect,
JSON: { parse: JSON.parse, stringify: JSON.stringify },
ArrayFrom: Array.from, ArrayIsArray: Array.isArray,
};
for (var k of Object.keys(pristine)) {
try { Object.freeze(pristine[k]); } catch(e) {}
}
Object.freeze(pristine);
// ============================================================
// MEMBRANE FACTORY (Layer 2 — closure-scoped, NOT on window)
// ============================================================
function createMembrane(target) {
var seen = new pristine.WeakMap();
function wrap(value) {
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return value;
if (seen.has(value)) return seen.get(value);
var proxy = new pristine.Proxy(value, {
get: function(t, p) {
var desc = pristine.getOwnPropertyDescriptor(t, p);
if (desc && desc.get) return wrap(desc.get.call(t));
return wrap(pristine.Reflect.get(t, p, t));
},
set: function(t, p, v) { return pristine.Reflect.set(t, p, v, t); },
defineProperty: function(t, p, d) { return pristine.defineProperty(t, p, d); },
getPrototypeOf: function(t) { return pristine.getPrototypeOf(t); },
has: function(t, p) { return pristine.Reflect.has(t, p); },
});
seen.set(value, proxy);
return proxy;
}
return wrap(target);
}
// Secure globals (Layer 3)
var secureGlobals = pristine.freeze({
JSON: pristine.JSON, Promise: pristine.Promise,
Map: pristine.Map, Set: pristine.Set,
WeakMap: pristine.WeakMap, WeakRef: pristine.WeakRef,
Reflect: pristine.Reflect, Proxy: pristine.Proxy,
});
// ============================================================
// SHARED WORKER CONNECTION
// ============================================================
var sw = new SharedWorker('/helium/router.worker.js');
var routerPort = sw.port;
routerPort.start();
// ============================================================
// REGISTRATION TOKENS
// These tokens are pre-shared with the SharedWorker during
// the injection plan delivery. Page scripts cannot guess them.
// ============================================================
var registrationTokens = ${JSON.stringify(tokenMap)};
// ============================================================
// CONTENT SCRIPT FACTORY (closure-scoped — NOT on window)
// Each extension's content scripts access this via the wrapper.
// ============================================================
var __helium_cs_factory__ = {};
${extensionIds.map(extId => `
__helium_cs_factory__['${extId}'] = {
createChrome: function() {
var contextId = 'ctx-cs-${extId}-' + Math.random().toString(36).slice(2);
// Register with SharedWorker using one-time token
// NOTE: tabId is injected as a closure parameter (see below),
// NOT read from window.__helium_tabId__ which would be page-accessible.
routerPort.postMessage({
type: '__helium_register',
contextId: contextId,
contextType: 'CONTENT_SCRIPT',
extensionId: '${extId}',
tabId: __helium_tabId,
frameId: 0,
url: location.href,
registrationToken: registrationTokens['${extId}'],
});
// Consume the token (one-time use)
delete registrationTokens['${extId}'];
return {
runtime: {
id: '${extId}',
sendMessage: function(extId, msg, opts, cb) { /* route through routerPort */ },
onMessage: new ChromeEvent(),
connect: function(extId, info) { /* create port */ },
onConnect: new ChromeEvent(),
getURL: function(path) { return '/helium-ext/${extId}/' + path; },
getManifest: function() { /* cached manifest */ },
lastError: null,
},
storage: {
local: new StorageArea(/* ... */),
sync: new StorageArea(/* ... */),
session: new StorageArea(/* ... */),
onChanged: new ChromeEvent(),
},
i18n: {
getMessage: function(name, subs) { /* ... */ },
getUILanguage: function() { return navigator.language; },
getAcceptLanguages: function(cb) { cb(Array.from(navigator.languages)); },
},
extension: {
getURL: function(path) { return '/helium-ext/${extId}/' + path; },
},
};
},
membrane: createMembrane,
secureGlobals: secureGlobals,
};
`).join('')}
// Handle incoming messages from SharedWorker
routerPort.onmessage = function(event) {
var msg = event.data;
// Route to appropriate content script chrome instance
};
// Report page metadata for tab registry
routerPort.postMessage({
type: '__helium_page_info',
url: location.href,
title: document.title,
});
// Track title changes
new MutationObserver(function() {
routerPort.postMessage({
type: '__helium_page_info',
url: location.href,
title: document.title,
});
}).observe(document.querySelector('title') || document.head, {
childList: true, subtree: true, characterData: true
});
// Report DOM lifecycle events for webNavigation
document.addEventListener('DOMContentLoaded', function() {
routerPort.postMessage({
type: '__helium_lifecycle',
event: 'DOMContentLoaded',
url: location.href,
});
});
window.addEventListener('load', function() {
routerPort.postMessage({
type: '__helium_lifecycle',
event: 'load',
url: location.href,
});
});
// Track pushState/replaceState for webNavigation.onHistoryStateUpdated
var origPushState = history.pushState;
var origReplaceState = history.replaceState;
history.pushState = function() {
origPushState.apply(this, arguments);
routerPort.postMessage({
type: '__helium_history_state',
url: location.href,
});
};
history.replaceState = function() {
origReplaceState.apply(this, arguments);
routerPort.postMessage({
type: '__helium_history_state',
url: location.href,
});
};
})(${tabId});
`;
}

Content scripts have three injection timing modes. Reflux’s @browser injection handles these:

run_atWhenInjection Strategy
document_startBefore any page scriptsInjected at top of <head> via @browser
document_endAfter DOM parsed, before subresourcesInjected at end of <body> or wrapped in DOMContentLoaded listener
document_idleAfter page load or after timeoutWrapped in load event listener with idle detection
function wrapForTiming(code: string, runAt: string): string {
switch (runAt) {
case 'document_start':
return code; // Injected at head, runs immediately
case 'document_end':
return `
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { ${code} }, {once: true});
} else {
${code}
}`;
case 'document_idle':
return `
(function() {
function runIdle() { ${code} }
if (document.readyState === 'complete') {
runIdle();
} else {
window.addEventListener('load', function() {
// Match Chrome's idle behavior: run after load or after 200ms, whichever first
setTimeout(runIdle, 0);
}, {once: true});
}
})();`;
default:
return code;
}
}

When extensions call chrome.scripting.registerContentScripts() at runtime, the new scripts need to be available for future page loads. The registration flows from Helium core to the Reflux injection plugin:

Extension calls chrome.scripting.registerContentScripts(scripts)
→ Helium core validates and stores registration
→ Posts update to SharedWorker
→ SharedWorker broadcasts to Reflux injection plugin
→ Plugin updates its internal registry
→ Future page loads evaluate the new match patterns

For the Reflux plugin to receive updates, it maintains a dedicated MessagePort bridge to the SharedWorker (see BareMux ↔ SharedWorker Communication).

Extension files (JS, HTML, CSS, images, etc.) are served by a fetch handler in the service worker that intercepts requests to the /helium-ext/ path prefix. This is NOT a proxy hook — it’s a standard fetch event handler registered alongside (or within) the proxy’s SW:

// In service worker (registered alongside UV/Scramjet):
self.addEventListener('fetch', (event: FetchEvent) => {
const url = new URL(event.request.url);
// Check if this is a Helium extension resource request
if (url.pathname.startsWith('/helium-ext/')) {
event.respondWith(serveExtensionResource(event.request));
return;
}
// Otherwise, let UV/Scramjet handle it
});
async function serveExtensionResource(request: Request): Promise<Response> {
const url = new URL(request.url);
const pathMatch = url.pathname.match(/^\/helium-ext\/([a-p]{32})\/(.+)$/);
if (!pathMatch) {
return new Response('Not found', { status: 404 });
}
const extensionId = pathMatch[1];
const resourcePath = pathMatch[2];
// 1. Check if the resource is web-accessible
const referer = request.headers.get('Referer') || '';
const isExtensionContext = referer.includes('/helium-ext/' + extensionId);
if (!isExtensionContext) {
const manifest = await getExtensionManifest(extensionId);
if (!isWebAccessible(manifest, resourcePath, referer)) {
return new Response('Forbidden', { status: 403 });
}
}
// 2. Read file from virtual filesystem (IndexedDB/OPFS)
const fileContent = await extensionFS.readFile(extensionId, resourcePath);
if (!fileContent) {
return new Response('Not found', { status: 404 });
}
// 3. Determine MIME type and return
const mimeType = getMimeType(resourcePath);
return new Response(fileContent, {
status: 200,
headers: {
'Content-Type': mimeType,
'Content-Length': fileContent.byteLength.toString(),
'Cache-Control': 'no-cache',
'X-Content-Type-Options': 'nosniff',
},
});
}
function getMimeType(path: string): string {
const ext = path.split('.').pop()?.toLowerCase();
const types: Record<string, string> = {
'html': 'text/html; charset=utf-8',
'js': 'application/javascript; charset=utf-8',
'mjs': 'application/javascript; charset=utf-8',
'css': 'text/css; charset=utf-8',
'json': 'application/json; charset=utf-8',
'png': 'image/png',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'gif': 'image/gif',
'svg': 'image/svg+xml',
'ico': 'image/x-icon',
'woff': 'font/woff',
'woff2': 'font/woff2',
'ttf': 'font/ttf',
'otf': 'font/otf',
'wasm': 'application/wasm',
'map': 'application/json',
};
return types[ext || ''] || 'application/octet-stream';
}

The modified BareMux worker provides the entrypoint for all network-level chrome API functionality. This replaces the previous design of using Reflux plugins for webRequest/DNR.

  • BareMux sits below Reflux in the stack, giving access to all requests including those Reflux might not see
  • The BareMux worker is already modified for premium systems, making it a natural extension point
  • Network interception (blocking, redirecting, header modification) is fundamentally a transport-level concern
  • Reflux’s plugin system is better suited for higher-level middleware (like content injection) rather than low-level request manipulation
// Inside the BareMux worker:
interface WebRequestMiddleware {
onRequest(request: BareMuxRequest, context: RequestContext): Promise<BareMuxRequest | BlockedResponse>;
onResponse(response: BareMuxResponse, request: BareMuxRequest, context: RequestContext): Promise<BareMuxResponse>;
}
const heliumWebRequest: WebRequestMiddleware = {
async onRequest(request, context) {
const details = buildWebRequestDetails(request, context);
// --- onBeforeRequest ---
const beforeResult = await emitWebRequestEvent(
'onBeforeRequest', details, { blocking: true }
);
if (beforeResult.cancel) {
return { blocked: true, reason: 'extension' };
}
if (beforeResult.redirectUrl) {
request.url = beforeResult.redirectUrl;
}
// --- onBeforeSendHeaders ---
const headerResult = await emitWebRequestEvent(
'onBeforeSendHeaders', details, { blocking: true }
);
if (headerResult.requestHeaders) {
request.headers = headerResult.requestHeaders;
}
// --- onSendHeaders (informational only) ---
emitWebRequestEvent('onSendHeaders', details, { blocking: false });
return request;
},
async onResponse(response, request, context) {
const details = buildWebResponseDetails(response, request, context);
// --- onHeadersReceived ---
const headerResult = await emitWebRequestEvent(
'onHeadersReceived', details, { blocking: true }
);
if (headerResult.responseHeaders) {
response.headers = headerResult.responseHeaders;
}
if (headerResult.redirectUrl) {
return { redirect: headerResult.redirectUrl };
}
// --- onResponseStarted (informational) ---
emitWebRequestEvent('onResponseStarted', details, { blocking: false });
// --- onCompleted (informational) ---
emitWebRequestEvent('onCompleted', details, { blocking: false });
return response;
},
};
/**
* Emit a webRequest event to all extensions that have listeners.
* For blocking events, waits for all listeners to respond.
*
* Communication from BareMux worker to extension contexts goes through
* the SharedWorker message backbone.
*/
async function emitWebRequestEvent(
eventName: string,
details: WebRequestDetails,
options: { blocking: boolean }
): Promise<WebRequestResult> {
const listeners = getWebRequestListeners(eventName);
const results: WebRequestResult[] = [];
for (const listener of listeners) {
// Check URL filter
if (!listener.filter.urls.matches(details.url)) continue;
// Check type filter
if (listener.filter.types && !listener.filter.types.includes(details.type)) continue;
// Check tab filter
if (listener.filter.tabId !== undefined && listener.filter.tabId !== details.tabId) continue;
// Check window filter
if (listener.filter.windowId !== undefined && listener.filter.windowId !== details.windowId) continue;
if (options.blocking && listener.extraInfoSpec?.includes('blocking')) {
// MV2 blocking: send to extension and wait for response
const result = await sendBlockingWebRequestEvent(
listener.extensionId, eventName, details
);
results.push(result);
} else {
// Non-blocking: fire and forget
sendWebRequestEvent(listener.extensionId, eventName, details);
}
}
// Merge results (first cancel wins, first redirect wins)
return mergeWebRequestResults(results);
}
interface WebRequestDetails {
requestId: string;
url: string;
method: string;
frameId: number;
parentFrameId: number;
tabId: number;
type: ResourceType;
timeStamp: number;
originUrl?: string;
documentUrl?: string;
initiator?: string;
requestBody?: {
error?: string;
formData?: Record<string, string[]>;
raw?: Array<{ bytes?: ArrayBuffer; file?: string }>;
};
requestHeaders?: HttpHeader[];
responseHeaders?: HttpHeader[];
statusCode?: number;
statusLine?: string;
ip?: string;
fromCache?: boolean;
}
type ResourceType =
| 'main_frame' | 'sub_frame' | 'stylesheet' | 'script'
| 'image' | 'font' | 'object' | 'xmlhttprequest' | 'ping'
| 'csp_report' | 'media' | 'websocket' | 'webtransport'
| 'webbundle' | 'other';

DNR rules are evaluated in the BareMux worker alongside webRequest:

const heliumDNR: WebRequestMiddleware = {
async onRequest(request, context) {
const url = request.url;
const resourceType = determineResourceType(request);
const initiator = request.headers?.['Origin'] || '';
// 1. Collect ALL matching rules across all extensions
const matchingRules: Array<{ rule: DNRRule; extensionId: string }> = [];
for (const [extensionId, rulesets] of dnrRuleStore) {
for (const ruleset of rulesets) {
if (!ruleset.enabled) continue;
for (const rule of ruleset.rules) {
if (matchesDNRRule(rule, url, resourceType, initiator)) {
matchingRules.push({ rule, extensionId });
}
}
}
}
if (matchingRules.length === 0) return request;
// 2. Sort by priority (descending), then by Chrome's action precedence
// Chrome action precedence (at same priority level):
// allow > allowAllRequests > block > redirect > upgradeScheme > modifyHeaders
const ACTION_PRECEDENCE: Record<string, number> = {
'allow': 6,
'allowAllRequests': 5,
'block': 4,
'redirect': 3,
'upgradeScheme': 2,
'modifyHeaders': 1,
};
matchingRules.sort((a, b) => {
const priorityDiff = (b.rule.priority ?? 1) - (a.rule.priority ?? 1);
if (priorityDiff !== 0) return priorityDiff;
return (ACTION_PRECEDENCE[b.rule.action.type] ?? 0) -
(ACTION_PRECEDENCE[a.rule.action.type] ?? 0);
});
// 3. Apply the highest-priority winning action
const winner = matchingRules[0];
const result = applyDNRAction(winner.rule.action, request);
// 4. Also apply any modifyHeaders rules at the same priority level
// (modifyHeaders rules are cumulative, not exclusive)
const winnerPriority = winner.rule.priority ?? 1;
for (const { rule } of matchingRules) {
if ((rule.priority ?? 1) === winnerPriority &&
rule.action.type === 'modifyHeaders' &&
rule.action.requestHeaders) {
for (const mod of rule.action.requestHeaders) {
applyHeaderModification(request.headers, mod);
}
}
}
return result.blocked || result.redirect ? result : request;
},
async onResponse(response, request, context) {
// DNR response header modification
for (const [extensionId, rulesets] of dnrRuleStore) {
for (const ruleset of rulesets) {
if (!ruleset.enabled) continue;
for (const rule of ruleset.rules) {
if (rule.action.type === 'modifyHeaders' && rule.action.responseHeaders) {
if (matchesDNRRule(rule, request.url, determineResourceType(request), '')) {
for (const mod of rule.action.responseHeaders) {
applyHeaderModification(response.headers, mod);
}
}
}
}
}
}
return response;
},
};
function matchesDNRRule(rule: DNRRule, url: string, type: string, initiator: string): boolean {
const condition = rule.condition;
if (condition.urlFilter && !matchesUrlFilter(url, condition.urlFilter)) return false;
if (condition.regexFilter && !new RegExp(condition.regexFilter).test(url)) return false;
if (condition.resourceTypes && !condition.resourceTypes.includes(type)) return false;
if (condition.excludedResourceTypes && condition.excludedResourceTypes.includes(type)) return false;
if (condition.domains && !condition.domains.some(d => matchesDomain(initiator, d))) return false;
if (condition.excludedDomains && condition.excludedDomains.some(d => matchesDomain(initiator, d))) return false;
if (condition.requestMethods && !condition.requestMethods.includes(rule.method)) return false;
return true;
}
function applyDNRAction(action: DNRAction, request: any): any {
switch (action.type) {
case 'block':
return { blocked: true };
case 'redirect':
if (action.redirect?.url) {
request.url = action.redirect.url;
return { redirect: action.redirect.url };
}
if (action.redirect?.regexSubstitution) {
// Apply regex substitution
}
return request;
case 'allow':
return request;
case 'upgradeScheme':
request.url = request.url.replace('http://', 'https://');
return request;
case 'modifyHeaders':
if (action.requestHeaders) {
for (const mod of action.requestHeaders) {
applyHeaderModification(request.headers, mod);
}
}
return request;
case 'allowAllRequests':
return request;
default:
return request;
}
}

BareMux ↔ SharedWorker Communication (Dedicated MessagePort Bridge)

Section titled “BareMux ↔ SharedWorker Communication (Dedicated MessagePort Bridge)”

The BareMux worker communicates with extension contexts through the SharedWorker via a dedicated MessagePort (not BroadcastChannel). This provides reliable request-response semantics required for blocking webRequest events.

Initialization: During startup, the main thread creates a MessageChannel and transfers one port to the BareMux worker and the other to the SharedWorker (same pattern as MV3 worker bridge — see EXECUTION-CONTEXTS.md):

// Main thread (during initialization sequence, step 2):
const bareMuxBridge = new MessageChannel();
// Transfer port1 to BareMux worker
bareMuxWorker.postMessage(
{ type: '__helium_router_port', port: bareMuxBridge.port1 },
[bareMuxBridge.port1]
);
// Transfer port2 to SharedWorker
sharedWorker.port.postMessage(
{ type: '__helium_baremux_bridge', port: bareMuxBridge.port2 },
[bareMuxBridge.port2]
);

BareMux worker side:

// In BareMux worker:
let heliumPort: MessagePort;
self.addEventListener('message', (event) => {
if (event.data?.type === '__helium_router_port') {
heliumPort = event.data.port;
heliumPort.start();
heliumPort.onmessage = (event) => {
const msg = event.data;
switch (msg.type) {
case 'webRequest.addListener':
addWebRequestListener(msg.extensionId, msg.eventName, msg.filter, msg.extraInfoSpec);
break;
case 'webRequest.removeListener':
removeWebRequestListener(msg.extensionId, msg.eventName, msg.listenerId);
break;
case 'dnr.updateRules':
updateDNRRules(msg.extensionId, msg.rulesets);
break;
case 'contentScript.updateRegistry':
updateContentScriptRegistry(msg.scripts);
break;
// Response from extension for blocking webRequest events
case 'webRequest.blockingResponse':
resolveBlockingRequest(msg.requestId, msg.response);
break;
}
};
}
});
// --- Request-Response for Blocking webRequest Events ---
const pendingBlockingRequests = new Map<string, {
resolve: (response: BlockingResponse) => void;
timer: ReturnType<typeof setTimeout>;
}>();
/**
* Send a blocking webRequest event and WAIT for the extension's decision.
* Used by onBeforeRequest, onBeforeSendHeaders, and onHeadersReceived
* when the extension has 'blocking' in extraInfoSpec.
*/
async function sendBlockingWebRequestEvent(
extensionId: string,
eventName: string,
details: WebRequestDetails
): Promise<BlockingResponse> {
const requestId = crypto.randomUUID();
return new Promise<BlockingResponse>((resolve) => {
// Set 5-second timeout: fail-open (allow the request) if no response
const timer = setTimeout(() => {
pendingBlockingRequests.delete(requestId);
console.warn(
`[Helium] Blocking webRequest ${eventName} timed out after 5s for ` +
`extension ${extensionId}, auto-allowing request`
);
resolve({}); // Empty response = allow the request unchanged
}, 5000);
pendingBlockingRequests.set(requestId, { resolve, timer });
heliumPort.postMessage({
type: 'webRequest.blockingEvent',
requestId,
extensionId,
eventName,
details,
});
});
}
function resolveBlockingRequest(requestId: string, response: BlockingResponse): void {
const pending = pendingBlockingRequests.get(requestId);
if (pending) {
clearTimeout(pending.timer);
pendingBlockingRequests.delete(requestId);
pending.resolve(response);
}
}
// Non-blocking events use fire-and-forget (no requestId needed)
function sendWebRequestEvent(extensionId: string, eventName: string, details: WebRequestDetails): void {
heliumPort.postMessage({
type: 'webRequest.event',
extensionId,
eventName,
details,
});
}

Extension cookie access is implemented through two mechanisms:

Section titled “1. BareMux Cookie Interceptor (Real Cookies)”

The BareMux worker intercepts Set-Cookie response headers and Cookie request headers to maintain a cookie jar that mirrors the actual cookies for proxied domains:

const cookieInterceptor: WebRequestMiddleware = {
async onRequest(request, context) {
// Inject cookies from our jar into the request
const cookies = await cookieStore.getCookiesForUrl(request.url);
if (cookies.length > 0) {
const cookieHeader = cookies.map(c => `${c.name}=${c.value}`).join('; ');
request.headers['Cookie'] = cookieHeader;
}
return request;
},
async onResponse(response, request, context) {
// Capture Set-Cookie headers into our jar
const setCookies = response.headers['set-cookie'];
if (setCookies) {
const parsed = Array.isArray(setCookies) ? setCookies : [setCookies];
for (const raw of parsed) {
const cookie = parseCookie(raw, request.url);
await cookieStore.set(cookie);
// Emit chrome.cookies.onChanged to extensions
heliumPort.postMessage({
type: 'cookies.onChanged',
changeInfo: {
removed: false,
cookie: cookieToChrome(cookie),
cause: 'overwrite',
},
});
}
}
return response;
},
};

The chrome.cookies API reads from and writes to an IndexedDB-backed store that is synced with the BareMux interceptor:

class CookieIntegration {
async getCookies(details: {
url: string; name?: string; domain?: string; storeId?: string;
}): Promise<Cookie[]> {
const url = new URL(details.url);
const cookies = await cookieStore.getAll({
domain: details.domain || url.hostname,
name: details.name,
});
return cookies.map(c => ({
name: c.name,
value: c.value,
domain: c.domain,
hostOnly: !c.domain.startsWith('.'),
path: c.path,
secure: c.secure,
httpOnly: c.httpOnly,
sameSite: c.sameSite,
session: !c.expires,
expirationDate: c.expires ? c.expires.getTime() / 1000 : undefined,
storeId: '0',
}));
}
async setCookie(details: {
url: string; name: string; value: string;
domain?: string; path?: string; secure?: boolean;
httpOnly?: boolean; sameSite?: string; expirationDate?: number;
}): Promise<Cookie> {
const cookie = {
name: details.name,
value: details.value,
domain: details.domain || new URL(details.url).hostname,
path: details.path || '/',
secure: details.secure || false,
httpOnly: details.httpOnly || false,
sameSite: details.sameSite || 'lax',
expires: details.expirationDate ? new Date(details.expirationDate * 1000) : undefined,
};
await cookieStore.set(cookie);
// Notify BareMux worker to include this cookie in future requests
heliumPort.postMessage({
type: 'cookies.set',
cookie,
});
// Fire chrome.cookies.onChanged
this.emitCookieChange('explicit', cookie);
return cookieToChrome(cookie);
}
}

chrome.webNavigation events are tracked by combining information from multiple sources:

class NavigationTracker {
// Source 1: BareMux sees document-type requests
onDocumentRequest(request: BareMuxRequest, tabId: number): void {
this.emitToExtensions('webNavigation.onBeforeNavigate', {
tabId,
url: request.url,
frameId: 0,
parentFrameId: -1,
timeStamp: Date.now(),
processId: -1,
});
}
// Source 2: Host application navigation callbacks
onTabNavigationCommitted(tabId: number, url: string, transitionType: string): void {
this.emitToExtensions('webNavigation.onCommitted', {
tabId,
url,
frameId: 0,
timeStamp: Date.now(),
transitionType,
transitionQualifiers: [],
processId: -1,
});
}
// Source 3: Content script bootstrap reports DOMContentLoaded
onContentScriptDOMContentLoaded(tabId: number, url: string, frameId: number): void {
this.emitToExtensions('webNavigation.onDOMContentLoaded', {
tabId,
url,
frameId,
timeStamp: Date.now(),
processId: -1,
});
}
// Source 4: Content script bootstrap reports load complete
onContentScriptLoadComplete(tabId: number, url: string, frameId: number): void {
this.emitToExtensions('webNavigation.onCompleted', {
tabId,
url,
frameId,
timeStamp: Date.now(),
processId: -1,
});
}
// Source 5: Content script detects pushState/replaceState
onHistoryStateUpdated(tabId: number, url: string, frameId: number, transitionType: string): void {
this.emitToExtensions('webNavigation.onHistoryStateUpdated', {
tabId,
url,
frameId,
timeStamp: Date.now(),
transitionType,
transitionQualifiers: [],
processId: -1,
});
}
}

Dynamic Script Injection (chrome.scripting / chrome.tabs.executeScript)

Section titled “Dynamic Script Injection (chrome.scripting / chrome.tabs.executeScript)”

When an extension calls chrome.scripting.executeScript() at runtime (not via manifest content scripts), Helium needs to inject code into an already-loaded page. This does NOT go through Reflux — it uses the SharedWorker to send an injection command to the target tab’s content script bootstrap:

async function executeScriptInTab(
extensionId: string,
tabId: number,
injection: {
func?: Function;
files?: string[];
args?: any[];
target: { tabId: number; frameIds?: number[]; allFrames?: boolean };
world?: 'ISOLATED' | 'MAIN';
}
): Promise<any[]> {
// 1. Build the code to inject
let code: string;
if (injection.func) {
const args = injection.args ? JSON.stringify(injection.args) : '[]';
code = `(${injection.func.toString()}).apply(null, ${args})`;
} else if (injection.files) {
const scripts = await Promise.all(
injection.files.map(f => extensionFS.readFile(extensionId, f))
);
code = scripts.map(s => new TextDecoder().decode(s!)).join(';\n');
} else {
throw new Error('Either func or files must be specified');
}
// 2. Send injection request to the bootstrap in the target tab
// via SharedWorker message routing
const result = await sendToContentScript(tabId, {
type: '__helium_inject',
extensionId,
code,
world: injection.world || 'ISOLATED',
frameIds: injection.target.frameIds,
allFrames: injection.target.allFrames,
});
return result;
}

The content script bootstrap handles __helium_inject messages by creating and executing a <script> element (for MAIN world) or evaluating within the content script’s scope (for ISOLATED world).

When the host application starts up:

1. Service Worker registers (UV/Scramjet)
- Helium fetch handler registered for /helium-ext/ paths
- No proxy configuration changes required
2. BareMux worker initializes:
a. Helium network middleware registers (webRequest, DNR, cookies)
b. Waits for dedicated MessagePort from main thread (see step 3b)
c. Loads persisted DNR rules and webRequest listener state
3. Main page loads:
a. Clean up orphaned extension staging areas (see MANIFEST-PARSER.md)
b. SharedWorker starts (message router)
- Recovers tab registry from IndexedDB snapshot (if available)
- Broadcasts re-registration request to live contexts
c. Create dedicated MessagePort bridges:
- BareMux worker ↔ SharedWorker (for webRequest events)
- Each MV3 DedicatedWorker ↔ SharedWorker (for background messaging)
d. Helium core initializes
e. Host application (DaydreamX) registers API bindings
- Bindings not registered use default fallback handlers (Graceful Degradation)
f. For each installed extension:
- Recover storage via WAL replay (if uncommitted entries exist)
- Create background context (Layer 2)
- Fire chrome.runtime.onStartup
g. Push content script registrations to Reflux injection plugin
h. Push webRequest listener state to BareMux worker (via MessagePort)
4. User navigates to a proxied page:
a. Request flows: SW → BareMux (webRequest events via MessagePort) → Transport
b. Response flows: Transport → BareMux (cookie capture, webRequest) → Reflux
c. Reflux evaluates content script matches for the URL
d. Reflux injects bootstrap + content scripts via @browser
- Bootstrap captures pristine prototypes (Proxy Membrane Layer 1)
- Registration tokens pre-shared with SharedWorker
e. Response returns to SW for rewriting
f. Browser renders the page
g. Bootstrap executes, connects to SharedWorker
- Content script factory created (closure-scoped, NOT on window)
h. Content scripts execute in proxy-membrane-isolated scopes
i. Extensions receive tabs.onUpdated, webNavigation events