Skip to content

Reference

Log Entry Structure

Every captured event, regardless of transport type, is stored as a UnifiedLogEntry:

typescript
interface UnifiedLogEntry {
  id: string // Unique UUID-like identifier
  type: 'http' | 'websocket' | 'sse'

  // Timing
  startTime: number // Unix timestamp at request start (ms)
  endTime: number | null // Unix timestamp at completion
  duration: number | null // endTime - startTime, milliseconds

  // Request identity
  url: string
  method: string // HTTP verb, or WebSocket/SSE event type

  // HTTP-specific (null for WebSocket / SSE)
  http: {
    status: number | null // e.g. 200, 404, 500
    statusText: string | null // e.g. "OK", "Not Found"
    protocol: string | null // e.g. "HTTP/1.1", "HTTP/2"
  } | null

  // WebSocket-specific (null for HTTP / SSE)
  websocket: {
    readyState: number // 0 CONNECTING | 1 OPEN | 2 CLOSING | 3 CLOSED
    eventType: 'connection' | 'open' | 'message' | 'error' | 'close'
    direction: 'incoming' | 'outgoing' | null
    code: number | null // Close code (1000 = normal, 1001 = going away, …)
    reason: string | null
    wasClean: boolean | null
  } | null

  // SSE-specific (null for HTTP / WebSocket)
  sse: {
    readyState: number // 0 CONNECTING | 1 OPEN | 2 CLOSED
    eventType: string | null // Named event type, or null for default "message"
    lastEventId: string | null
  } | null

  // Headers
  requestHeaders: Record<string, string> // Sanitized request headers
  responseHeaders: Record<string, string> // Sanitized response headers

  // Bodies
  request: {
    body: any | null // Parsed body (object, string, FormData, etc.)
    bodyRaw: string | null // Raw serialized body string
    bodySize: number | null // Size in bytes
    bodyType: string | null // MIME type derived from Content-Type
  }
  response: {
    body: any | null
    bodyRaw: string | null
    bodySize: number | null
    bodyType: string | null
  }

  // Errors
  error: {
    occurred: boolean
    message: string | null
    name: string | null // e.g. "TypeError", "NetworkError"
    stack: string | null
  }

  // Metadata
  metadata: {
    clientType: 'fetch' | 'xhr' | 'websocket' | 'eventsource'
    redirected: boolean
    retryCount: number
    timestamp: string // ISO 8601 timestamp at log creation
  }

  // Vue Router route path at the moment the request was initiated.
  // Populated only when `enrichWithRoute: true` is set in plugin options.
  route?: string
}

Statistics

getStats() returns a NetworkStats object:

typescript
interface NetworkStats {
  totalRequests: number
  totalErrors: number
  averageDuration: number // Mean response time in ms
  totalDataSent: number // Total request body bytes
  totalDataReceived: number // Total response body bytes

  requestsByMethod: Record<string, number> // { GET: 42, POST: 17, … }
  requestsByStatus: Record<string, number> // { '200': 55, '404': 3, '500': 1, … }

  slowestRequests: UnifiedLogEntry[] // Top 10 by duration (descending)
  largestRequests: UnifiedLogEntry[] // Top 10 by total body size (descending)
  sseEventCount: number // Total SSE events captured
}

getStatsSummary() returns the same data as a formatted multi-line string, useful for logging to the console.

Architecture

vue-network-dashboard/
├── src/
│   ├── core/
│   │   ├── NetworkDashboard.ts      # Orchestrator — interceptors, mock registry, breakpoints, lifecycle
│   │   ├── formatters.ts            # HTTPFormatter, WebSocketFormatter, SSEFormatter
│   │   ├── openApiParser.ts         # Parses OpenAPI 3.x / Swagger 2.x JSON → MockRule[]
│   │   └── types.ts                 # UnifiedLogEntry, MockRule, BreakpointRule, NetworkStats, …
│   ├── interceptors/
│   │   ├── fetchInterceptor.ts      # Patches window.fetch (pending state + mock support)
│   │   ├── xhrInterceptor.ts        # Patches XMLHttpRequest prototype (WeakMap + mock support)
│   │   ├── websocketInterceptor.ts  # Replaces window.WebSocket
│   │   └── sseInterceptor.ts        # Replaces window.EventSource
│   ├── store/
│   │   └── logStore.ts              # Vue reactive storage — addLog, updateLog, HAR/JSON/CSV export
│   ├── plugins/
│   │   └── vuePlugin.ts             # Vue 3 plugin + useNetworkDashboard composable + mock API
│   ├── adapters/
│   │   ├── sentry.ts                # createSentryAdapter — breadcrumbs + Sentry events
│   │   └── opentelemetry.ts         # createOpenTelemetryAdapter — OTel spans per request
│   ├── utils/
│   │   ├── sanitizer.ts             # Header redaction, field removal, PII masking
│   │   ├── helpers.ts               # generateId, formatBytes, getContentType
│   │   └── sizeCalculator.ts        # calculateSize, getDataType, safeStringify
│   ├── view/
│   │   ├── components/
│   │   │   ├── NetworkDebugger.vue  # Main draggable panel (logs / stats / timeline / mocks tabs)
│   │   │   ├── LogEntry.vue         # Single row — pending state, mocked badge, diff select
│   │   │   ├── FilterBar.vue        # Type tabs, URL, body, method, status, duration filters
│   │   │   ├── StatsPanel.vue       # Live statistics with distribution bars
│   │   │   ├── MockPanel.vue           # Mock rule editor — groups, conditions, transform, OpenAPI import
│   │   │   ├── BreakpointPanel.vue     # Breakpoint rules + paused-request cards with editable fields
│   │   │   ├── ReplayModal.vue         # Edit & Replay modal — URL, method, headers, body
│   │   │   ├── SessionComparePanel.vue # HAR diff view — two sessions side by side
│   │   │   ├── NetworkTimeline.vue  # Waterfall bar chart
│   │   │   └── DiffPanel.vue        # LCS-based header and body diff between two log entries
│   │   ├── composables/
│   │   │   ├── useLogFilter.ts      # Reactive filter state (url, body, method, status, …)
│   │   │   └── useHotkey.ts         # Keyboard shortcut binding helper
│   │   └── styles/
│   │       ├── variables.scss       # Design tokens (colours, spacing, typography)
│   │       └── debugger.scss        # All component styles
│   ├── devtools.ts                  # setupDevtools() — Vue DevTools inspector + timeline layer
│   ├── nuxt.ts                      # Nuxt 3 module (defineNuxtModule)
│   └── runtime/
│       └── nuxt-plugin.ts           # Nuxt client plugin — registered automatically by nuxt.ts
└── demo/                            # Demo app (Vite + Vue 3)

The plugin has no runtime dependencies besides Vue 3. It relies only on standard browser APIs (window.fetch, XMLHttpRequest, WebSocket, EventSource).

License

MIT