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 // see metrics.trackRetries on Configuration Reference
    timestamp: string // ISO 8601 timestamp at log creation
    pending?: boolean // true while the request is in-flight
    mocked?: boolean // true if the response was returned by a mock rule
    connectionId?: string // WebSocket: shared id for all events of one connection
    ttfb?: number | null // Time To First Byte in ms — see metrics.calculateTTFB
  }

  // 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/
│   │   ├── types.ts                 # NetworkDebuggerProps (as of 0.4.1) — imported by NetworkDebugger.vue and view/index.ts
│   │   ├── 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      # Standalone filter state (url/body/route, regex-aware; method, status, wsMessagesOnly, …) — NOT used by NetworkDebugger.vue itself
│   │   │   └── useHotkey.ts         # Standalone keyboard shortcut binding helper — NOT used by NetworkDebugger.vue itself
│   │   └── 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) — registers the client plugin inline via addPluginTemplate()
└── 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).

Utility exports ​

The package root also re-exports a handful of internal building blocks, intended for writing custom sanitization or formatting logic around the library rather than as the primary API:

  • Formatters — LogFormatter, HTTPFormatter, WebSocketFormatter (classes)
  • Store — LogStore (class), ILogStore (its type)
  • Size/serialization helpers — calculateSize, getDataType, safeStringify, getContentLength
  • General helpers — generateId, safeClone, truncate, isObject, formatBytes, getContentType, parseHeaders

These are stable, deliberate exports (not incidental), but most integrations never need to import them directly.

Bundle size & peer dependencies ​

Entry pointMinifiedGzipped
vue-network-dashboard.esm.js~264 KB~55 KB
vue-network-dashboard.umd.cjs~195 KB~47 KB
vue-network-dashboard.css~65 KB~10 KB

Peer dependencies: vue ^3.0.0 (required). @vue/devtools-api ≥ 6.5 is used by setupDevtools() but is not declared as a formal peer — install it yourself if you use that feature. engines.node is >=18 (build/dev time only, not enforced at runtime for consumers).

License ​

MIT