> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/mercuryworkshop/scramjet/llms.txt
> Use this file to discover all available pages before exploring further.

# ScramjetServiceWorker

> Service worker class for request interception

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.

```typescript theme={null}
new ScramjetServiceWorker()
```

### Example

```typescript theme={null}
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.

```typescript theme={null}
client: BareClient
```

### config

Current `ScramjetConfig` saved in memory.

```typescript theme={null}
config: ScramjetConfig
```

### cookieStore

Scramjet's cookie jar for cookie emulation through other storage means.

```typescript theme={null}
cookieStore: CookieStore
```

### serviceWorkers

Fake service worker registrations for sites that require service worker support.

```typescript theme={null}
serviceWorkers: FakeServiceWorker[]
```

<Info>
  This will eventually be replaced with a NestedSW feature under a flag, but will remain for stability.
</Info>

### syncPool

Recorded sync messages in the message queue.

```typescript theme={null}
syncPool: Record<number, (val?: any) => void>
```

### synctoken

Current sync token for collected messages in the queue.

```typescript theme={null}
synctoken: number
```

## Methods

### loadConfig()

Persists the current Scramjet config from IndexedDB into memory.

```typescript theme={null}
async loadConfig(): Promise<void>
```

<Warning>
  You must call `loadConfig()` before using `route()` or `fetch()` to ensure the configuration is loaded.
</Warning>

#### Example

```typescript theme={null}
self.addEventListener("fetch", async (ev) => {
  await scramjet.loadConfig();

  if (scramjet.route(ev)) {
    ev.respondWith(scramjet.fetch(ev));
  }
});
```

<Info>
  The Scramjet config can be dynamically updated via the `ScramjetController` APIs, which is why it needs to be loaded from IndexedDB.
</Info>

### route()

Determines whether to route a request from a `FetchEvent` in Scramjet.

```typescript theme={null}
route({ request }: FetchEvent): boolean
```

<ParamField path="request" type="Request" required>
  The fetch request from the FetchEvent
</ParamField>

#### Returns

`true` if the request should be handled by Scramjet, `false` otherwise.

#### Example

```typescript theme={null}
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.

```typescript theme={null}
async fetch({ request, clientId }: FetchEvent): Promise<Response>
```

<ParamField path="request" type="Request" required>
  The fetch request from the FetchEvent
</ParamField>

<ParamField path="clientId" type="string" required>
  The client ID from the FetchEvent
</ParamField>

#### Returns

A `Promise` that resolves to the proxied `Response`.

#### Example

```typescript theme={null}
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.

```typescript theme={null}
async dispatch(client: Client, data: MessageW2C): Promise<MessageC2W>
```

<ParamField path="client" type="Client" required>
  The client to send the message to
</ParamField>

<ParamField path="data" type="MessageW2C" required>
  The message data to send
</ParamField>

#### Returns

A `Promise` that resolves to the response message from the client.

<Info>
  This method is used internally for communication between the service worker and clients.
</Info>

## Message types

The service worker communicates with clients using typed messages.

### MessageC2W

Message types sent from the client to the service worker.

```typescript theme={null}
type MessageC2W = MessageCommon & (
  | RegisterServiceWorkerMessage
  | CookieMessage
  | ConfigMessage
);

type MessageCommon = {
  scramjet$token?: number;
};
```

### MessageW2C

Message types sent from the service worker to the client.

```typescript theme={null}
type MessageW2C = MessageCommon & (
  | CookieMessage
  | DownloadMessage
);
```

### RegisterServiceWorkerMessage

```typescript theme={null}
type RegisterServiceWorkerMessage = {
  scramjet$type: "registerServiceWorker";
  port: MessagePort;
  origin: string;
};
```

### CookieMessage

```typescript theme={null}
type CookieMessage = {
  scramjet$type: "cookie";
  cookie: string;
  url: string;
};
```

### ConfigMessage

```typescript theme={null}
type ConfigMessage = {
  scramjet$type: "loadConfig";
  config: ScramjetConfig;
};
```

### DownloadMessage

```typescript theme={null}
type DownloadMessage = {
  scramjet$type: "download";
  download: ScramjetDownload;
};
```

## Complete example

```typescript theme={null}
// 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));
  }
});
```
