The ScramjetServiceWorker class handles request interception in the service worker context. It routes proxy requests, manages configuration, and handles the core logic for proxying.
Constructor
Creates a new ScramjetServiceWorker instance.
new ScramjetServiceWorker()
Example
const { ScramjetServiceWorker } = $scramjetLoadWorker();
const scramjet = new ScramjetServiceWorker();
self.addEventListener("fetch", async (ev) => {
await scramjet.loadConfig();
if (scramjet.route(ev)) {
ev.respondWith(scramjet.fetch(ev));
}
});
Properties
client
BareClient instance to fetch requests under a chosen proxy transport.
config
Current ScramjetConfig saved in memory.
cookieStore
Scramjet’s cookie jar for cookie emulation through other storage means.
serviceWorkers
Fake service worker registrations for sites that require service worker support.
serviceWorkers: FakeServiceWorker[]
This will eventually be replaced with a NestedSW feature under a flag, but will remain for stability.
syncPool
Recorded sync messages in the message queue.
syncPool: Record<number, (val?: any) => void>
synctoken
Current sync token for collected messages in the queue.
Methods
loadConfig()
Persists the current Scramjet config from IndexedDB into memory.
async loadConfig(): Promise<void>
You must call loadConfig() before using route() or fetch() to ensure the configuration is loaded.
Example
self.addEventListener("fetch", async (ev) => {
await scramjet.loadConfig();
if (scramjet.route(ev)) {
ev.respondWith(scramjet.fetch(ev));
}
});
The Scramjet config can be dynamically updated via the ScramjetController APIs, which is why it needs to be loaded from IndexedDB.
route()
Determines whether to route a request from a FetchEvent in Scramjet.
route({ request }: FetchEvent): boolean
The fetch request from the FetchEvent
Returns
true if the request should be handled by Scramjet, false otherwise.
Example
self.addEventListener("fetch", async (ev) => {
await scramjet.loadConfig();
if (scramjet.route(ev)) {
ev.respondWith(scramjet.fetch(ev));
}
});
fetch()
Handles a FetchEvent to be routed in Scramjet. This is the heart of adding Scramjet support to your web proxy.
async fetch({ request, clientId }: FetchEvent): Promise<Response>
The fetch request from the FetchEvent
The client ID from the FetchEvent
Returns
A Promise that resolves to the proxied Response.
Example
self.addEventListener("fetch", async (ev) => {
await scramjet.loadConfig();
if (scramjet.route(ev)) {
ev.respondWith(scramjet.fetch(ev));
}
});
dispatch()
Dispatches a message in the message queues.
async dispatch(client: Client, data: MessageW2C): Promise<MessageC2W>
The client to send the message to
Returns
A Promise that resolves to the response message from the client.
This method is used internally for communication between the service worker and clients.
Message types
The service worker communicates with clients using typed messages.
MessageC2W
Message types sent from the client to the service worker.
type MessageC2W = MessageCommon & (
| RegisterServiceWorkerMessage
| CookieMessage
| ConfigMessage
);
type MessageCommon = {
scramjet$token?: number;
};
MessageW2C
Message types sent from the service worker to the client.
type MessageW2C = MessageCommon & (
| CookieMessage
| DownloadMessage
);
RegisterServiceWorkerMessage
type RegisterServiceWorkerMessage = {
scramjet$type: "registerServiceWorker";
port: MessagePort;
origin: string;
};
CookieMessage
type CookieMessage = {
scramjet$type: "cookie";
cookie: string;
url: string;
};
ConfigMessage
type ConfigMessage = {
scramjet$type: "loadConfig";
config: ScramjetConfig;
};
DownloadMessage
type DownloadMessage = {
scramjet$type: "download";
download: ScramjetDownload;
};
Complete example
// service-worker.js
const { ScramjetServiceWorker } = $scramjetLoadWorker();
const scramjet = new ScramjetServiceWorker();
self.addEventListener("fetch", async (event) => {
// Load config from IndexedDB
await scramjet.loadConfig();
// Check if this request should be handled by Scramjet
if (scramjet.route(event)) {
// Handle the request through Scramjet
event.respondWith(scramjet.fetch(event));
}
});