or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-web-features.mdbrowser-page-control.mdcore-debugging.mddevice-testing.mddom-styling.mdindex.mdnetwork-performance.mdstorage-data.md
tile.json

core-debugging.mddocs/

Core JavaScript Debugging

Essential debugging capabilities for JavaScript execution, memory analysis, and performance profiling. This encompasses the core domains that provide debugging functionality for JavaScript code running in Chrome and other Chromium-based browsers.

Capabilities

Console Domain (Deprecated)

Console message handling and logging functionality. Note: This domain is deprecated - use Runtime or Log instead.

namespace Protocol.Console {
  export const enum ConsoleMessageSource {
    XML = 'xml',
    Javascript = 'javascript',
    Network = 'network',
    ConsoleAPI = 'console-api',
    Storage = 'storage',
    Appcache = 'appcache',
    Rendering = 'rendering',
    Security = 'security',
    Other = 'other',
    Deprecation = 'deprecation',
    Worker = 'worker',
  }

  export const enum ConsoleMessageLevel {
    Log = 'log',
    Warning = 'warning',
    Error = 'error',
    Debug = 'debug',
    Info = 'info',
  }

  interface ConsoleMessage {
    source: ('xml' | 'javascript' | 'network' | 'console-api' | 'storage' | 'appcache' | 'rendering' | 'security' | 'other' | 'deprecation' | 'worker');
    level: ('log' | 'warning' | 'error' | 'debug' | 'info');
    text: string;
    url?: string;
    line?: integer;
    column?: integer;
  }

  interface MessageAddedEvent {
    message: ConsoleMessage;
  }
}

Debugger Domain

JavaScript debugging capabilities including breakpoints, stepping through execution, and exploring stack traces.

namespace Protocol.Debugger {
  type BreakpointId = string;
  type CallFrameId = string;

  interface Location {
    scriptId: Runtime.ScriptId;
    lineNumber: integer;
    columnNumber?: integer;
  }

  interface ScriptPosition {
    lineNumber: integer;
    columnNumber: integer;
  }

  interface CallFrame {
    callFrameId: CallFrameId;
    functionName: string;
    functionLocation?: Location;
    location: Location;
    url: string;
    scopeChain: Scope[];
    this: Runtime.RemoteObject;
    returnValue?: Runtime.RemoteObject;
    canBeRestarted?: boolean;
  }

  interface Scope {
    type: ('global' | 'local' | 'with' | 'closure' | 'catch' | 'block' | 'script' | 'eval' | 'module' | 'wasm-expression-stack');
    object: Runtime.RemoteObject;
    name?: string;
    startLocation?: Location;
    endLocation?: Location;
  }

  interface SetBreakpointByUrlRequest {
    lineNumber: integer;
    url?: string;
    urlRegex?: string;
    scriptHash?: string;
    columnNumber?: integer;
    condition?: string;
  }

  interface SetBreakpointByUrlResponse {
    breakpointId: BreakpointId;
    locations: Location[];
  }

  interface PausedEvent {
    callFrames: CallFrame[];
    reason: ('ambiguous' | 'assert' | 'CSPViolation' | 'debugCommand' | 'DOM' | 'EventListener' | 'exception' | 'instrumentation' | 'OOM' | 'other' | 'promiseRejection' | 'XHR' | 'step');
    data?: Record<string, any>;
    hitBreakpoints?: string[];
    asyncStackTrace?: Runtime.StackTrace;
    asyncStackTraceId?: Runtime.StackTraceId;
    asyncCallStackTraceId?: Runtime.StackTraceId;
  }

  interface ResumedEvent {}

  interface ScriptParsedEvent {
    scriptId: Runtime.ScriptId;
    url: string;
    startLine: integer;
    startColumn: integer;
    endLine: integer;
    endColumn: integer;
    executionContextId: Runtime.ExecutionContextId;
    hash: string;
    executionContextAuxData?: Record<string, any>;
    isLiveEdit?: boolean;
    sourceMapURL?: string;
    hasSourceURL?: boolean;
    isModule?: boolean;
    length?: integer;
    stackTrace?: Runtime.StackTrace;
    codeOffset?: integer;
    scriptLanguage?: Debugger.ScriptLanguage;
    debugSymbols?: Debugger.DebugSymbols;
    embedderName?: string;
  }

  interface ScriptFailedToParseEvent {
    scriptId: Runtime.ScriptId;
    url: string;
    startLine: integer;
    startColumn: integer;
    endLine: integer;
    endColumn: integer;
    executionContextId: Runtime.ExecutionContextId;
    hash: string;
    executionContextAuxData?: Record<string, any>;
    sourceMapURL?: string;
    hasSourceURL?: boolean;
    isModule?: boolean;
    length?: integer;
    stackTrace?: Runtime.StackTrace;
    codeOffset?: integer;
    scriptLanguage?: Debugger.ScriptLanguage;
    embedderName?: string;
  }
}

Usage Example:

import Protocol from "devtools-protocol/types/protocol";

// Set a breakpoint
const breakpointRequest: Protocol.Debugger.SetBreakpointByUrlRequest = {
  lineNumber: 42,
  url: "https://example.com/script.js",
  condition: "variable > 10"
};

// Handle debugger pause event
function onDebuggerPaused(event: Protocol.Debugger.PausedEvent) {
  console.log("Paused at:", event.callFrames[0].location);
  console.log("Reason:", event.reason);
  
  // Inspect call stack
  event.callFrames.forEach((frame, index) => {
    console.log(`Frame ${index}: ${frame.functionName} at ${frame.url}:${frame.location.lineNumber}`);
  });
}

Runtime Domain

JavaScript runtime evaluation, object inspection, and execution context management.

namespace Protocol.Runtime {
  type ScriptId = string;
  type ExecutionContextId = integer;
  type UnserializableValue = string;
  type StackTraceId = string;
  type UniqueDebuggerId = string;

  interface RemoteObject {
    type: ('object' | 'function' | 'undefined' | 'string' | 'number' | 'boolean' | 'symbol' | 'bigint');
    subtype?: ('array' | 'null' | 'node' | 'regexp' | 'date' | 'map' | 'set' | 'weakmap' | 'weakset' | 'iterator' | 'generator' | 'error' | 'proxy' | 'promise' | 'typedarray' | 'arraybuffer' | 'dataview' | 'webassemblymemory' | 'wasmvalue');
    className?: string;
    value?: any;
    unserializableValue?: UnserializableValue;
    description?: string;
    webDriverValue?: WebDriverValue;
    objectId?: RemoteObjectId;
    preview?: ObjectPreview;
    customPreview?: CustomPreview;
  }

  interface EvaluateRequest {
    expression: string;
    objectGroup?: string;
    includeCommandLineAPI?: boolean;
    silent?: boolean;
    contextId?: ExecutionContextId;
    returnByValue?: boolean;
    generatePreview?: boolean;
    userGesture?: boolean;
    awaitPromise?: boolean;
    throwOnSideEffect?: boolean;
    timeout?: TimeDelta;
    disableBreaks?: boolean;
    replMode?: boolean;
    allowUnsafeEvalBlockedByCSP?: boolean;
    uniqueContextId?: string;
  }

  interface EvaluateResponse {
    result: RemoteObject;
    exceptionDetails?: ExceptionDetails;
  }

  interface ConsoleAPICalledEvent {
    type: ('log' | 'debug' | 'info' | 'error' | 'warning' | 'dir' | 'dirxml' | 'table' | 'trace' | 'clear' | 'startGroup' | 'startGroupCollapsed' | 'endGroup' | 'assert' | 'profile' | 'profileEnd' | 'count' | 'timeEnd');
    args: RemoteObject[];
    executionContextId: ExecutionContextId;
    timestamp: Timestamp;
    stackTrace?: StackTrace;
    context?: string;
  }

  interface ExceptionThrownEvent {
    timestamp: Timestamp;
    exceptionDetails: ExceptionDetails;
  }

  interface StackTrace {
    description?: string;
    callFrames: CallFrame[];
    parent?: StackTrace;
    parentId?: StackTraceId;
  }

  interface CallFrame {
    functionName: string;
    scriptId: ScriptId;
    url: string;
    lineNumber: integer;
    columnNumber: integer;
  }

  interface ExceptionDetails {
    exceptionId: integer;
    text: string;
    lineNumber: integer;
    columnNumber: integer;
    scriptId?: ScriptId;
    url?: string;
    stackTrace?: StackTrace;
    exception?: RemoteObject;
    executionContextId?: ExecutionContextId;
    exceptionMetaData?: Record<string, any>;
  }
}

Usage Example:

import Protocol from "devtools-protocol/types/protocol";

// Evaluate JavaScript expression
const evaluateRequest: Protocol.Runtime.EvaluateRequest = {
  expression: "document.title",
  returnByValue: true,
  awaitPromise: true
};

// Handle console API calls
function onConsoleAPICall(event: Protocol.Runtime.ConsoleAPICalledEvent) {
  console.log(`Console ${event.type}:`, event.args.map(arg => arg.value));
}

// Handle exceptions
function onExceptionThrown(event: Protocol.Runtime.ExceptionThrownEvent) {
  const { exceptionDetails } = event;
  console.error(`Exception: ${exceptionDetails.text} at ${exceptionDetails.url}:${exceptionDetails.lineNumber}`);
}

HeapProfiler Domain

JavaScript heap profiling and memory analysis for performance optimization.

namespace Protocol.HeapProfiler {
  type HeapSnapshotObjectId = string;

  interface SamplingHeapProfileNode {
    callFrame: Runtime.CallFrame;
    selfSize: number;
    id: integer;
    children: SamplingHeapProfileNode[];
  }

  interface SamplingHeapProfile {
    head: SamplingHeapProfileNode;
    samples: SamplingHeapProfileSample[];
  }

  interface SamplingHeapProfileSample {
    size: number;
    nodeId: integer;
    ordinal: number;
  }

  interface StartSamplingRequest {
    samplingInterval?: number;
    includeObjectsCollectedByMajorGC?: boolean;
    includeObjectsCollectedByMinorGC?: boolean;
  }

  interface GetSamplingProfileResponse {
    profile: SamplingHeapProfile;
  }

  interface AddHeapSnapshotChunkEvent {
    chunk: string;
  }

  interface HeapStatsUpdateEvent {
    statsUpdate: integer[];
  }

  interface LastSeenObjectIdEvent {
    lastSeenObjectId: integer;
    timestamp: number;
  }
}

Profiler Domain

JavaScript CPU profiling and performance analysis.

namespace Protocol.Profiler {
  interface ProfileNode {
    id: integer;
    callFrame: Runtime.CallFrame;
    hitCount?: integer;
    children?: integer[];
    deoptReason?: string;
    positionTicks?: PositionTickInfo[];
  }

  interface Profile {
    nodes: ProfileNode[];
    startTime: number;
    endTime: number;
    samples?: integer[];
    timeDeltas?: integer[];
  }

  interface PositionTickInfo {
    line: integer;
    ticks: integer;
  }

  interface StartRequest {
    callCount?: boolean;
    detailed?: boolean;
  }

  interface StopResponse {
    profile: Profile;
  }

  interface ConsoleProfileStartedEvent {
    id: string;
    location: Debugger.Location;
    title?: string;
  }

  interface ConsoleProfileFinishedEvent {
    id: string;
    location: Debugger.Location;
    profile: Profile;
    title?: string;
  }
}

Usage Example:

import Protocol from "devtools-protocol/types/protocol";

// Start CPU profiling
const startProfilerRequest: Protocol.Profiler.StartRequest = {
  callCount: true,
  detailed: true
};

// Start heap sampling
const startHeapSamplingRequest: Protocol.HeapProfiler.StartSamplingRequest = {
  samplingInterval: 32768,
  includeObjectsCollectedByMajorGC: true
};

// Process profiling results
function processProfile(profile: Protocol.Profiler.Profile) {
  console.log(`Profile duration: ${profile.endTime - profile.startTime}ms`);
  console.log(`Total nodes: ${profile.nodes.length}`);
  
  // Find hot spots
  const hotNodes = profile.nodes
    .filter(node => node.hitCount && node.hitCount > 10)
    .sort((a, b) => (b.hitCount || 0) - (a.hitCount || 0));
    
  console.log("Hot spots:");
  hotNodes.forEach(node => {
    console.log(`${node.callFrame.functionName}: ${node.hitCount} hits`);
  });
}

Schema Domain

Protocol schema introspection for understanding available domains and their capabilities.

namespace Protocol.Schema {
  interface Domain {
    name: string;
    version: string;
  }

  interface GetDomainsResponse {
    domains: Domain[];
  }
}

Common Usage Patterns

Debugging Session Setup

import Protocol from "devtools-protocol/types/protocol";
import { ProtocolMapping } from "devtools-protocol/types/protocol-mapping";

// Enable domains
const enableDebugger = {};
const enableRuntime = {};

// Set up event handlers
type Events = ProtocolMapping.Events;

function setupDebuggingSession() {
  // Handle script parsing
  function onScriptParsed(event: Events['Debugger.scriptParsed'][0]) {
    console.log(`Script parsed: ${event.url}`);
  }
  
  // Handle execution pauses
  function onPaused(event: Events['Debugger.paused'][0]) {
    console.log(`Execution paused: ${event.reason}`);
  }
  
  // Handle console output
  function onConsoleAPI(event: Events['Runtime.consoleAPICalled'][0]) {
    console.log(`Console ${event.type}:`, event.args);
  }
}

Memory Analysis

import Protocol from "devtools-protocol/types/protocol";

async function analyzeMemoryUsage() {
  // Start heap sampling
  const samplingRequest: Protocol.HeapProfiler.StartSamplingRequest = {
    samplingInterval: 16384
  };
  
  // Later, get the sampling profile
  function processSamplingProfile(response: Protocol.HeapProfiler.GetSamplingProfileResponse) {
    const { profile } = response;
    
    // Analyze heap allocations
    function analyzeNode(node: Protocol.HeapProfiler.SamplingHeapProfileNode, depth = 0) {
      const indent = "  ".repeat(depth);
      console.log(`${indent}${node.callFrame.functionName}: ${node.selfSize} bytes`);
      
      node.children.forEach(child => analyzeNode(child, depth + 1));
    }
    
    analyzeNode(profile.head);
  }
}