Skip to main content

Message Passing

Communication between Graytool's layers is handled through Chrome's message passing mechanism.

Message Types

type GrayToolMessage =
| ActivateMessage
| DeactivateMessage
| ConfigUpdatedMessage
| CheckUrlMessage
| GetConfigMessage
| PingMessage
| RequestPermissionMessage
| HasPermissionMessage
| GetConfiguredOriginsMessage;

Background → Content Script

ACTIVATE

Sent when the user navigates to a page where the extension should be active.

interface ActivateMessage {
type: "ACTIVATE";
matchedPatternId?: string; // ID of the matched URL pattern
}

Trigger: tabs.onUpdated — when a page loads Receiver: inject/index.ts Result: Content script activates, row processing begins

DEACTIVATE

Sent when the extension should be deactivated.

interface DeactivateMessage {
type: "DEACTIVATE";
}

Trigger: URL no longer matches any pattern Receiver: inject/index.ts Result: Observer stops, styles removed

CONFIG_UPDATED

Broadcast to all tabs when configuration changes.

interface ConfigUpdatedMessage {
type: "CONFIG_UPDATED";
}

Trigger: chrome.storage.onChanged — when settings change Receiver: Content scripts in all tabs Result: Content scripts reload configuration

Content Script → Background

CHECK_URL

Content script asks whether the current URL matches a pattern.

interface CheckUrlMessage {
type: "CHECK_URL";
}

Response: { isMatch: boolean, matchedPatternId?: string }

GET_CONFIG

Content script requests the full configuration.

interface GetConfigMessage {
type: "GET_CONFIG";
}

Response: GrayToolConfig object

PING

Connection health check.

interface PingMessage {
type: "PING";
}

Response: { pong: true }

REQUEST_PERMISSION

Permission request for a URL pattern.

interface RequestPermissionMessage {
type: "REQUEST_PERMISSION";
pattern: string;
}

Response: boolean — whether permission was granted

HAS_PERMISSION

Permission query for a specific URL.

interface HasPermissionMessage {
type: "HAS_PERMISSION";
url: string;
}

Response: boolean — whether permission exists

GET_CONFIGURED_ORIGINS

Requests all configured URL patterns.

interface GetConfiguredOriginsMessage {
type: "GET_CONFIGURED_ORIGINS";
}

Response: string[] — list of URL patterns

Custom Events

CustomEvent is used for intra-content-script communication:

graytool:open-detail

Communication from the message detail button to the JSON viewer:

document.dispatchEvent(new CustomEvent("graytool:open-detail", {
detail: {
fields: DiscoveredField[],
config: GrayToolConfig,
row: Element
}
}));

Communication Diagram

┌─────────────┐              ┌─────────────┐
│ Background │ │ Content │
│ Service │ ACTIVATE → │ Script │
│ Worker │ DEACTIVATE →│ (inject) │
│ │ CONFIG_UPD →│ │
│ │ │ │
│ │ ← CHECK_URL │ │
│ │ ← GET_CONFIG │ │
│ │ ← PING │ │
│ │ ← REQ_PERM │ │
│ │ ← HAS_PERM │ │
│ │ ← GET_ORIGINS│ │
└─────────────┘ └──────┬──────┘

CustomEvent

┌──────▼──────┐
│ JSON Viewer │
│ Search Hist │
└─────────────┘


┌─────────────┐
│ Options │ saveConfig() → chrome.storage.sync
│ Page │
│ (React) │ → storage.onChanged → background broadcasts
└─────────────┘

Error Handling

Connection Loss

Content scripts may lose connection to the background (service worker sleeps):

try {
const response = await chrome.runtime.sendMessage(message);
} catch (error) {
// Service worker is sleeping or extension was updated
// Silent failure — don't break Graylog
}