> ## 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.

# Module types

> Type definitions for Scramjet modules and proxying

Scramjet provides type definitions for modules, proxies, and traps used in the interception system.

## ScramjetModule

Interface for Scramjet modules that hook into browser APIs.

```typescript theme={null}
type ScramjetModule = {
  enabled?: (client: ScramjetClient) => boolean | undefined;
  disabled?: (client: ScramjetClient, self: typeof globalThis) => void | undefined;
  order?: number | undefined;
  default: (client: ScramjetClient, self: typeof globalThis) => void;
};
```

### Properties

<ParamField path="enabled" type="(client: ScramjetClient) => boolean | undefined">
  Optional function that returns whether the module should be enabled for the given client.

  <Expandable title="Example">
    ```typescript theme={null}
    enabled(client) {
      // Only enable for secure contexts
      return client.global.isSecureContext;
    }
    ```
  </Expandable>
</ParamField>

<ParamField path="disabled" type="(client: ScramjetClient, self: typeof globalThis) => void | undefined">
  Optional function called when the module is disabled.
</ParamField>

<ParamField path="order" type="number">
  Optional loading order. Lower numbers load first. Default: 0
</ParamField>

<ParamField path="default" type="(client: ScramjetClient, self: typeof globalThis) => void" required>
  The main module function that applies hooks and modifications.
</ParamField>

### Example

```typescript theme={null}
import { ScramjetModule } from "scramjet";

const fetchModule: ScramjetModule = {
  order: 1,
  enabled(client) {
    return typeof client.global.fetch === "function";
  },
  default(client, self) {
    client.Proxy("fetch", {
      apply(ctx) {
        // Rewrite URL before fetching
        ctx.args[0] = rewriteUrl(ctx.args[0]);
        return ctx.call();
      }
    });
  }
};
```

## Proxy

Handler type for proxying functions and constructors.

```typescript theme={null}
type Proxy = {
  construct?(ctx: ProxyCtx): any;
  apply?(ctx: ProxyCtx): any;
};
```

### Properties

<ParamField path="construct" type="(ctx: ProxyCtx) => any">
  Handler for constructor calls (when using `new`)
</ParamField>

<ParamField path="apply" type="(ctx: ProxyCtx) => any">
  Handler for function calls
</ParamField>

### Example

```typescript theme={null}
client.Proxy("XMLHttpRequest.prototype.open", {
  apply(ctx) {
    // ctx.args = [method, url, async, user, password]
    console.log("XHR opening:", ctx.args[1]);
    
    // Rewrite the URL (second argument)
    ctx.args[1] = rewriteUrl(ctx.args[1]);
    
    // Call the original function
    return ctx.call();
  }
});

client.Proxy("Worker", {
  construct(ctx) {
    // ctx.args = [scriptURL, options]
    console.log("Creating worker:", ctx.args[0]);
    
    // Rewrite the script URL
    ctx.args[0] = rewriteUrl(ctx.args[0]);
    
    // Call the original constructor
    return ctx.call();
  }
});
```

## ProxyCtx

Context object passed to proxy handlers.

```typescript theme={null}
type ProxyCtx = {
  fn: Function;
  this: any;
  args: any[];
  newTarget: Function;
  return: (r: any) => void;
  call: () => any;
};
```

### Properties

<ParamField path="fn" type="Function" required>
  The original function or constructor being called
</ParamField>

<ParamField path="this" type="any" required>
  The `this` context for the call
</ParamField>

<ParamField path="args" type="any[]" required>
  The arguments array. You can modify this before calling.
</ParamField>

<ParamField path="newTarget" type="Function" required>
  The constructor that was originally called (for construct handlers)
</ParamField>

<ParamField path="return" type="(r: any) => void" required>
  Function to return a value early without calling the original

  <Expandable title="Example">
    ```typescript theme={null}
    apply(ctx) {
      // Return a fake value without calling original
      ctx.return("fake response");
    }
    ```
  </Expandable>
</ParamField>

<ParamField path="call" type="() => any" required>
  Function to call the original function/constructor with the (possibly modified) arguments

  <Expandable title="Example">
    ```typescript theme={null}
    apply(ctx) {
      ctx.args[0] = rewriteUrl(ctx.args[0]);
      return ctx.call(); // Call with modified args
    }
    ```
  </Expandable>
</ParamField>

## Trap

Handler type for trapping property access.

```typescript theme={null}
type Trap<T> = {
  writable?: boolean;
  value?: any;
  enumerable?: boolean;
  configurable?: boolean;
  get?: (ctx: TrapCtx<T>) => T;
  set?: (ctx: TrapCtx<T>, v: T) => void;
};
```

### Properties

<ParamField path="writable" type="boolean">
  Whether the property is writable
</ParamField>

<ParamField path="value" type="any">
  Static value for the property
</ParamField>

<ParamField path="enumerable" type="boolean">
  Whether the property shows up in enumeration
</ParamField>

<ParamField path="configurable" type="boolean">
  Whether the property descriptor can be changed
</ParamField>

<ParamField path="get" type="(ctx: TrapCtx<T>) => T">
  Getter function for the property
</ParamField>

<ParamField path="set" type="(ctx: TrapCtx<T>, v: T) => void">
  Setter function for the property
</ParamField>

### Example

```typescript theme={null}
client.Trap("document.cookie", {
  get(ctx) {
    // Return cookies from Scramjet's cookie store
    return client.cookieStore.getCookies();
  },
  set(ctx, value) {
    // Store cookie in Scramjet's cookie store
    client.cookieStore.setCookie(value);
  }
});

client.Trap("window.origin", {
  get(ctx) {
    // Return the proxified origin instead of the real one
    return client.url.origin;
  }
});
```

## TrapCtx

Context object passed to trap handlers.

```typescript theme={null}
type TrapCtx<T> = {
  this: any;
  get: () => T;
  set: (v: T) => void;
};
```

### Properties

<ParamField path="this" type="any" required>
  The `this` context for the property access
</ParamField>

<ParamField path="get" type="() => T" required>
  Function to get the original property value

  <Expandable title="Example">
    ```typescript theme={null}
    get(ctx) {
      const original = ctx.get();
      return rewriteUrl(original);
    }
    ```
  </Expandable>
</ParamField>

<ParamField path="set" type="(v: T) => void" required>
  Function to set the original property value

  <Expandable title="Example">
    ```typescript theme={null}
    set(ctx, value) {
      const unrewritten = unrewriteUrl(value);
      ctx.set(unrewritten);
    }
    ```
  </Expandable>
</ParamField>

## Complete example

```typescript theme={null}
import { ScramjetClient, Proxy, Trap } from "scramjet";

// Example module that hooks fetch and location.href
const exampleModule = {
  order: 1,
  
  default(client: ScramjetClient, self: typeof globalThis) {
    // Proxy fetch function
    client.Proxy("fetch", {
      apply(ctx) {
        const url = ctx.args[0];
        console.log("Fetching:", url);
        
        // Rewrite the URL
        ctx.args[0] = rewriteUrl(url, client.meta);
        
        // Call original fetch
        return ctx.call();
      }
    });
    
    // Trap location.href property
    client.Trap("location.href", {
      get(ctx) {
        // Return proxified URL
        return client.url.href;
      },
      set(ctx, value) {
        // Handle navigation
        client.url = value;
      }
    });
    
    // Proxy Worker constructor
    client.Proxy("Worker", {
      construct(ctx) {
        // Rewrite worker script URL
        ctx.args[0] = rewriteUrl(ctx.args[0], client.meta);
        return ctx.call();
      }
    });
  }
};
```
