Справочник
Структура записи лога
Каждое захваченное событие, независимо от типа транспорта, сохраняется как UnifiedLogEntry:
interface UnifiedLogEntry {
id: string // Уникальный UUID-подобный идентификатор
type: 'http' | 'websocket' | 'sse'
// Тайминг
startTime: number // Unix-таймстамп начала запроса (мс)
endTime: number | null // Unix-таймстамп завершения
duration: number | null // endTime - startTime, миллисекунды
// Идентичность запроса
url: string
method: string // HTTP-глагол, или тип события WebSocket/SSE
// Специфично для HTTP (null для WebSocket / SSE)
http: {
status: number | null // например 200, 404, 500
statusText: string | null // например "OK", "Not Found"
protocol: string | null // например "HTTP/1.1", "HTTP/2"
} | null
// Специфично для WebSocket (null для 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 // Код закрытия (1000 = обычное, 1001 = уход со страницы, …)
reason: string | null
wasClean: boolean | null
} | null
// Специфично для SSE (null для HTTP / WebSocket)
sse: {
readyState: number // 0 CONNECTING | 1 OPEN | 2 CLOSED
eventType: string | null // Именованный тип события, или null для стандартного "message"
lastEventId: string | null
} | null
// Заголовки
requestHeaders: Record<string, string> // Санитизированные заголовки запроса
responseHeaders: Record<string, string> // Санитизированные заголовки ответа
// Тела
request: {
body: any | null // Разобранное тело (объект, строка, FormData и т. д.)
bodyRaw: string | null // Сырая сериализованная строка тела
bodySize: number | null // Размер в байтах
bodyType: string | null // MIME-тип, выведенный из Content-Type
}
response: {
body: any | null
bodyRaw: string | null
bodySize: number | null
bodyType: string | null
}
// Ошибки
error: {
occurred: boolean
message: string | null
name: string | null // например "TypeError", "NetworkError"
stack: string | null
}
// Метаданные
metadata: {
clientType: 'fetch' | 'xhr' | 'websocket' | 'eventsource'
redirected: boolean
retryCount: number // см. metrics.trackRetries на странице Справочник конфигурации
timestamp: string // Таймстамп ISO 8601 в момент создания лога
pending?: boolean // true, пока запрос выполняется
mocked?: boolean // true, если ответ был возвращён правилом мока
connectionId?: string // WebSocket: общий id для всех событий одного соединения
ttfb?: number | null // Time To First Byte в мс — см. metrics.calculateTTFB
}
// Путь маршрута Vue Router в момент инициации запроса.
// Заполняется только когда в опциях плагина установлено `enrichWithRoute: true`.
route?: string
}Статистика
getStats() возвращает объект NetworkStats:
interface NetworkStats {
totalRequests: number
totalErrors: number
averageDuration: number // Среднее время ответа в мс
totalDataSent: number // Общий объём байт тела запроса
totalDataReceived: number // Общий объём байт тела ответа
requestsByMethod: Record<string, number> // { GET: 42, POST: 17, … }
requestsByStatus: Record<string, number> // { '200': 55, '404': 3, '500': 1, … }
slowestRequests: UnifiedLogEntry[] // Топ-10 по длительности (по убыванию)
largestRequests: UnifiedLogEntry[] // Топ-10 по общему размеру тела (по убыванию)
sseEventCount: number // Общее число захваченных событий SSE
}getStatsSummary() возвращает те же данные в виде отформатированной многострочной строки, полезной для логирования в консоль.
Архитектура
vue-network-dashboard/
├── src/
│ ├── core/
│ │ ├── NetworkDashboard.ts # Оркестратор — перехватчики, реестр моков, точки останова, жизненный цикл
│ │ ├── formatters.ts # HTTPFormatter, WebSocketFormatter, SSEFormatter
│ │ ├── openApiParser.ts # Парсит OpenAPI 3.x / Swagger 2.x JSON → MockRule[]
│ │ └── types.ts # UnifiedLogEntry, MockRule, BreakpointRule, NetworkStats, …
│ ├── interceptors/
│ │ ├── fetchInterceptor.ts # Патчит window.fetch (незавершённое состояние + поддержка моков)
│ │ ├── xhrInterceptor.ts # Патчит прототип XMLHttpRequest (WeakMap + поддержка моков)
│ │ ├── websocketInterceptor.ts # Заменяет window.WebSocket
│ │ └── sseInterceptor.ts # Заменяет window.EventSource
│ ├── store/
│ │ └── logStore.ts # Реактивное хранилище Vue — addLog, updateLog, экспорт HAR/JSON/CSV
│ ├── plugins/
│ │ └── vuePlugin.ts # Плагин Vue 3 + composable useNetworkDashboard + API моков
│ ├── adapters/
│ │ ├── sentry.ts # createSentryAdapter — breadcrumbs + события Sentry
│ │ └── opentelemetry.ts # createOpenTelemetryAdapter — OTel-спаны на каждый запрос
│ ├── utils/
│ │ ├── sanitizer.ts # Редактирование заголовков, удаление полей, маскирование PII
│ │ ├── helpers.ts # generateId, formatBytes, getContentType
│ │ └── sizeCalculator.ts # calculateSize, getDataType, safeStringify
│ ├── view/
│ │ ├── types.ts # NetworkDebuggerProps (начиная с 0.4.1) — импортируется NetworkDebugger.vue и view/index.ts
│ │ ├── components/
│ │ │ ├── NetworkDebugger.vue # Основная перетаскиваемая панель (вкладки logs / stats / timeline / mocks)
│ │ │ ├── LogEntry.vue # Одна строка — незавершённое состояние, бейдж мока, выбор для диффа
│ │ │ ├── FilterBar.vue # Вкладки типа, фильтры URL, тела, метода, статуса, длительности
│ │ │ ├── StatsPanel.vue # Живая статистика со столбцами распределения
│ │ │ ├── MockPanel.vue # Редактор правил моков — группы, условия, transform, импорт OpenAPI
│ │ │ ├── BreakpointPanel.vue # Правила точек останова + карточки приостановленных запросов с редактируемыми полями
│ │ │ ├── ReplayModal.vue # Модальное окно Edit & Replay — URL, метод, заголовки, тело
│ │ │ ├── SessionComparePanel.vue # Просмотр диффа HAR — две сессии бок о бок
│ │ │ ├── NetworkTimeline.vue # Waterfall-диаграмма
│ │ │ └── DiffPanel.vue # Дифф заголовков и тела между двумя записями лога на основе LCS
│ │ ├── composables/
│ │ │ ├── useLogFilter.ts # Автономное состояние фильтров (url/body/route с поддержкой regex; method, status, wsMessagesOnly, …) — НЕ используется самим NetworkDebugger.vue
│ │ │ └── useHotkey.ts # Автономный хелпер привязки клавиатурного шортката — НЕ используется самим NetworkDebugger.vue
│ │ └── styles/
│ │ ├── variables.scss # Дизайн-токены (цвета, отступы, типографика)
│ │ └── debugger.scss # Все стили компонентов
│ ├── devtools.ts # setupDevtools() — инспектор Vue DevTools + слой таймлайна
│ └── nuxt.ts # Модуль Nuxt 3 (defineNuxtModule) — регистрирует клиентский плагин инлайн через addPluginTemplate()
└── demo/ # Демо-приложение (Vite + Vue 3)Плагин не имеет runtime-зависимостей помимо Vue 3. Он полагается только на стандартные API браузера (window.fetch, XMLHttpRequest, WebSocket, EventSource).
Экспорты утилит
Корень пакета также реэкспортирует ряд внутренних строительных блоков — они предназначены для написания собственной логики санитизации или форматирования поверх библиотеки, а не как основной API:
- Форматтеры —
LogFormatter,HTTPFormatter,WebSocketFormatter(классы) - Хранилище —
LogStore(класс),ILogStore(его тип) - Хелперы размера/сериализации —
calculateSize,getDataType,safeStringify,getContentLength - Общие хелперы —
generateId,safeClone,truncate,isObject,formatBytes,getContentType,parseHeaders
Это стабильные, осознанные экспорты (не случайные), но большинству интеграций не нужно импортировать их напрямую.
Размер бандла и peer-зависимости
| Точка входа | Минифицировано | С gzip |
|---|---|---|
vue-network-dashboard.esm.js | ~264 КБ | ~55 КБ |
vue-network-dashboard.umd.cjs | ~195 КБ | ~47 КБ |
vue-network-dashboard.css | ~65 КБ | ~10 КБ |
Peer-зависимости: vue ^3.0.0 (обязательна). @vue/devtools-api ≥ 6.5 используется setupDevtools(), но не объявлена как формальная peer-зависимость — установите её сами, если используете эту функцию. engines.node — >=18 (только для сборки/разработки, не проверяется в рантайме у потребителей).
Лицензия
MIT