Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

set -eu

echo "Running lint..."
npm run lint

echo "Running typecheck..."
npm run typecheck
54 changes: 53 additions & 1 deletion .github/workflows/pr-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- '**'

jobs:
lint-and-test:
lint:
runs-on: ubuntu-latest

steps:
Expand All @@ -25,8 +25,60 @@ jobs:
- name: Lint
run: npm run lint

typecheck:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Typecheck
run: npm run typecheck

test:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Test
run: npm run test:run

build:
runs-on: ubuntu-latest
needs: [lint, typecheck, test]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build
186 changes: 117 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,130 +2,178 @@

# Signal Trace

Signal Trace is a browser-based WebSocket traffic inspector for real-time IoT debugging.
It helps you connect to a WebSocket endpoint, inspect inbound/outbound messages, validate payloads against a simple schema, and replay/export traffic timelines.
Signal Trace is a browser-based WebSocket traffic inspector for real-time IoT debugging. It helps you connect to raw WebSocket or Socket.IO endpoints, inspect inbound and outbound frames, validate outgoing JSON against a lightweight schema, and replay or export captured traffic.

## Tech Stack

- React 19
- TypeScript
- Vite
- Vitest
- Aegis Design System

## Features
- Live WebSocket connect/disconnect workflow
- Protocol decode modes (`auto`, `raw`, `socket.io`)
- Traffic timeline with direction, namespace, event, payload, bytes, and latency
- Search (in timeline header) and namespace filtering
- Visual Schema Guard constructor (modal) for outgoing payload validation
- Timeline import/export (`JSON` and `NDJSON`)
- Timeline replay with speed controls
- Demo mode for local experimentation

- Live connect and disconnect workflow for WebSocket endpoints
- Protocol decode modes: `auto`, `raw`, and `socketio`
- Socket.IO handshake support with configurable path, namespace, auth JSON, and event name
- Timeline inspection with direction, namespace, event, payload, byte size, and latency
- Search and namespace filtering for narrowing noisy traffic
- Outbound payload helpers for JSON formatting and auto-refreshing `id` / `timestamp`
- Schema Guard modal for validating outgoing JSON before send
- Timeline import and export in `JSON` and `NDJSON`
- Replay controls with adjustable playback speed
- Demo mode for synthetic traffic generation without a backend
- Theme toggle in the app shell

## Requirements
- Node.js 20+ (recommended current LTS)

- Node.js 20+
- npm 10+

## Getting Started

1. Install dependencies:

```bash
npm install
```
2. Start development server:

2. Start the development server:

```bash
npm run dev
```
3. Open the local URL shown in terminal (typically `http://localhost:5173`).

## Available Scripts
- `npm run dev` - Start Vite dev server
- `npm run build` - Type-check and build production assets
- `npm run preview` - Preview the production build locally
- `npm run test` - Run tests in watch mode
- `npm run test:run` - Run all tests once
3. Open the local URL printed by Vite, usually `http://localhost:5173`.

## Scripts

- `npm run dev` - start the Vite dev server
- `npm run typecheck` - run the TypeScript project build without bundling
- `npm run build` - run type-checking and build production assets
- `npm run preview` - preview the production build locally
- `npm run lint` - run ESLint
- `npm run lint:fix` - run ESLint with fixes
- `npm run test` - run Vitest in watch mode
- `npm run test:run` - run the full test suite once

## Basic Usage
1. Set WebSocket URL (default: `ws://localhost:8080`).
2. Choose protocol mode (`auto` is recommended initially).
3. Click **Connect**.
4. Inspect incoming/outgoing traffic in the timeline.
5. Use timeline search and namespace filters to narrow results.
6. Optionally validate outgoing JSON payloads with the schema panel.
7. Export or replay timeline data as needed.

### Socket.IO Auth Handshake
If your backend uses Socket.IO namespaces/auth:
- Enable **Socket.IO Handshake**.
- Set **Socket.IO Path** (commonly `/socket.io` or `/ws`).
- Set **Socket.IO Namespace** (for example `/devices` or `/frontend`).
- Provide **Socket.IO Auth JSON** when required (for example `{"serial":"...","token":"..."}`).
- Use protocol mode `socketio` to send event frames, and set **Socket.IO Event** if you need an event name other than `trace`.
- Signal Trace waits for namespace connection before allowing Socket.IO sends.
- Engine.IO ping (`2`) is handled automatically with pong (`3`) keepalive replies.

### Schema Guard Builder
- Open **Schema Guard** from the sidebar and click **Open Schema Builder**.
- Add fields with type (`string`, `number`, `boolean`, `object`, `array`).
- Use the **Required** checkbox next to each field to mark it required.
- Leave all fields empty to disable schema validation.

1. Enter a WebSocket endpoint such as `ws://localhost:8080`.
2. Choose a protocol decode mode. Start with `auto` unless you know the framing.
3. Click `Connect`.
4. Inspect incoming and outgoing traffic in the timeline.
5. Use search and namespace filters to isolate the frames you care about.
6. Open `Schema Builder` if you want to validate outgoing JSON before sending.
7. Use replay, import, and export controls from the timeline toolbar as needed.

## Sending Frames

- The transmit panel defaults to the `/telemetry` namespace and a JSON payload.
- `Format JSON` prettifies valid JSON and emits a system event if the payload is invalid.
- `Auto-refresh id/timestamp` updates those fields before send when they already exist in the payload.
- If no correlation id is present, Signal Trace injects a `requestId` automatically before sending.

## Socket.IO Handshake

If your backend uses Socket.IO namespaces or auth:

- Enable `Socket.IO Handshake`.
- Set `Socket.IO Path`, typically `/socket.io`.
- Set `Socket.IO Namespace`, for example `/devices`.
- Provide `Socket.IO Auth JSON` when your server expects auth in the namespace connect payload.
- Switch protocol mode to `socketio` for outbound event frames.
- Optionally set `Socket.IO Event`; the default event name is `trace`.
- Signal Trace waits for namespace readiness before allowing Socket.IO sends.
- Engine.IO ping frames (`2`) are answered automatically with pong (`3`).

## Schema Guard

- Open the schema builder from the transmit panel.
- Add fields with type `string`, `number`, `boolean`, `object`, or `array`.
- Mark fields as required when needed.
- Leave the schema empty to disable validation.
- Schema parse or validation failures are written to the system timeline instead of being swallowed.

## Timeline Import, Export, and Replay

- Export captured traffic as formatted `JSON` or line-delimited `NDJSON`.
- Import previously captured files in either format.
- Invalid or empty imports produce a system event instead of silently failing.
- Replay replays imported or captured messages in timestamp order with adjustable speed.
- Demo mode stops replay before starting synthetic traffic.

## Testing

Stack: **Vitest** + **@testing-library/react** + **@testing-library/user-event** + **@testing-library/jest-dom**. Test files live next to their implementation files.
Signal Trace uses Vitest with Testing Library and `@testing-library/jest-dom`.

Run the full test suite once:

Run all tests once:
```bash
npm run test:run
```

Run in watch mode:
Run tests in watch mode:

```bash
npm run test
```

Coverage areas:
- `src/lib/` — pure utility unit tests (frame decoding, schema validation, Socket.IO URL/auth/namespace helpers)
- `src/hooks/` — `renderHook` + `act` tests for `useTimeline`, `useConnection`, `useSchemaGuard`
- `src/components/` — render + user-event tests for every component
- `src/App.test.tsx` — integration tests: schema modal, validation errors, Socket.IO handshake lifecycle
Coverage is organized around the current source layout:

- `src/lib/*.test.ts` for pure utility helpers
- `src/hooks/*.test.ts` for hook behavior via `renderHook`
- `src/components/*.test.tsx` for component rendering and user flows
- `src/App.test.tsx` for integration coverage across hooks and UI

## Project Structure

```text
src/
App.tsx # Thin orchestrator — wires hooks + components
App.tsx # Thin orchestrator for hooks and top-level actions
App.test.tsx # Integration tests
types.ts # Shared domain types
main.tsx
styles.css
hooks/
useTimeline.ts # Messages, filtering, search, metrics, demo mode, replay, import/export
useTimeline.ts # Timeline state, demo mode, replay, import/export
useTimeline.test.ts
useConnection.ts # WebSocket lifecycle, Socket.IO handshake, protocol decode, RTT tracking
useConnection.ts # WebSocket lifecycle, Socket.IO handshake, RTT tracking
useConnection.test.ts
useSchemaGuard.ts # Schema builder state, parsedSchema memo, Esc key listener
useSchemaGuard.ts # Schema builder state and parsed schema
useSchemaGuard.test.ts
components/
ConnectionPanel.tsx # Connection settings form
ConnectionPanel.tsx
ConnectionPanel.test.tsx
NamespaceFilter.tsx # Namespace toggle buttons
MessageRow.tsx
MessageRow.test.tsx
NamespaceFilter.tsx
NamespaceFilter.test.tsx
TransmitPanel.tsx # Send form with local state
TransmitPanel.test.tsx
SchemaGuardModal.tsx # Schema builder modal
SchemaGuardModal.tsx
SchemaGuardModal.test.tsx
MessageRow.tsx # Single message row with expand/copy
MessageRow.test.tsx
TimelinePanel.tsx # Right-panel shell composing MessageRow list
TimelinePanel.tsx
TimelinePanel.test.tsx
TransmitPanel.tsx
TransmitPanel.test.tsx
lib/
trace-utils.ts # Pure: frame decoding, schema validation, hex preview, safeJson
trace-utils.test.ts
socketio-utils.ts # Pure: URL building, namespace/path normalization, auth parsing
socketio-utils.ts
socketio-utils.test.ts
vitest.setup.ts # @testing-library/jest-dom setup
trace-utils.ts
trace-utils.test.ts
vitest.setup.ts
vite.config.ts
index.html
package.json
AGENTS.md # Architecture and development guidelines
AGENTS.md
```

## Verification

- Type check: `npm run typecheck`
- Build check: `npm run build`
- Test check: `npm run test:run`

## Notes
- If your endpoint is unavailable, use Demo mode to test the UI behavior.

- Use Demo mode when the target endpoint is unavailable and you still want to exercise the UI.
- Imported traffic and incoming frames are treated as untrusted input and normalized before use.
Loading
Loading