# Pulse Relay

> **Real-time server engine — SFU, control plane, HTTP bridge, and durable queues, all over PLP.**
> One library. One port. One protocol.

[![Crates.io](https://img.shields.io/crates/v/sansavision-pulse)](https://crates.io/crates/sansavision-pulse)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../LICENSE)

---

## Overview

`pulse` is a high-performance **Selective Forwarding Unit (SFU)** with an embedded control plane and HTTP bridge. It speaks the **Pulse Link Protocol (PLP)** — the only protocol your application needs.

```
┌─────────┐  QUIC/PLP   ┌──────────────────────────────────┐  QUIC/PLP   ┌─────────┐
│ Client A │────────────▸│                                  │◂────────────│ Client C │
└─────────┘             │         pulse server             │             └─────────┘
                        │    (SFU + Control + HTTP Bridge)  │
┌─────────┐  WS/PLP    │                                  │  QUIC/PLP   ┌─────────┐
│ Browser  │────────────▸│                                  │◂────────────│ Client D │
└─────────┘             └────────────┬─────────────────────┘             └─────────┘
                                     │
                    Outbound HTTP    │    Inbound HTTP (webhooks)
                    (conn.plpFetch)  │    (conn.webhook)
                                     │
                              ┌──────┴──────┐
                              │ External    │
                              │ APIs        │
                              │ (Stripe,    │
                              │  OpenAI,    │
                              │  etc.)      │
                              └─────────────┘
```

### Key Features

- **Zero-decode SFU routing** — forwards packets without touching media payloads
- **Dual transport** — QUIC/UDP for native SDKs + WebSocket for browsers
- **Embedded control plane** — session management, schemas, billing via PLP SERVICE_REQUEST
- **HTTP bridge** — outbound HTTP proxy and inbound webhook delivery, all over PLP
- **Edge WASM compute** — embedded [Wasmtime](https://wasmtime.dev) for in-flight transforms
- **Edge AI inference** — speech-to-text and computer vision at the edge
- **GPU-aware** — auto-detects NVIDIA, Apple Silicon/Metal, or CPU fallback
- **NAT traversal** — UDP hole-punching with symmetric NAT detection
- **Full observability** — Prometheus metrics, OpenTelemetry/Jaeger tracing
- **Three deployment modes** — standalone, relay, or control

---

## Quick Start

### Run with Docker

```bash
# Standalone mode (everything in one process)
docker run -d \
  --name pulse \
  -p 4001:4001/udp \
  -p 4001:4001/tcp \
  -e RUST_LOG=info \
  registry.onekube.dev/onekube/pulse:latest \
  --mode standalone --bind 0.0.0.0:4001
```

### Run with `pulse serve` (Unified CLI)

```bash
# Install the unified CLI
npm install -g @sansavision/pulse-cli

# Start in standalone mode
pulse serve
pulse serve --mode standalone --bind 0.0.0.0:4001

# Or start the full dev environment (relay + dashboard)
pulse dev
```

This starts Pulse in standalone mode:

| Service                | URL                      |
| ---------------------- | ------------------------ |
| Relay (QUIC/UDP)       | `localhost:4001`         |
| WebSocket (PLP)        | `ws://localhost:4001`    |
| Webhook hooks          | `http://localhost:4001/_hook/...` |
| Prometheus Metrics     | `http://localhost:9090`  |

### Build from Source

```bash
# Build the unified CLI (includes relay)
cargo build --release -p sansavision-pulse-cli
./target/release/pulse serve --mode standalone

# Or build the standalone relay binary (backward-compat)
cargo build --release -p sansavision-pulse
./target/release/pulse-relay --mode standalone --bind 0.0.0.0:4001
```

---

## Deployment Modes

### Standalone (Default)

Everything in one process: SFU + control services + HTTP bridge.

```bash
pulse serve --mode standalone --bind 0.0.0.0:4001
```

**Best for:** Self-hosted, small teams, development, Next.js integration.

### Relay

SFU + HTTP bridge only. Connects to an external control node.

```bash
pulse serve --mode relay --bind 0.0.0.0:4001 --control-url http://pulse-control:4002
```

**Best for:** Multi-region deployment with separate control nodes.

### Control

Control services only — session management, billing, schemas, mesh coordination. No SFU.

```bash
pulse serve --mode control --bind 0.0.0.0:4001
```

**Best for:** Central coordinator for a fleet of relay nodes.

---

## CLI Reference

```
pulse serve — Start the Pulse server

USAGE:
    pulse serve [OPTIONS]

OPTIONS:
        --mode <MODE>               Deployment mode [default: standalone]
                                    [possible values: standalone, relay, control]
    -b, --bind <ADDR>              Bind address [default: 0.0.0.0:4001]
    -p, --public-endpoint <ADDR>   Public endpoint for control plane [default: localhost:4001]
    -r, --region <REGION>          Region identifier [default: eu-west-1]
        --lat <LAT>                GPS latitude for geo-routing [default: 0.0]
        --lon <LON>                GPS longitude for geo-routing [default: 0.0]
        --control-url <URL>        Control plane URL (relay mode) [default: http://localhost:4002]
        --capacity <N>             Max concurrent connections [default: 100000]
        --stt-endpoint <URL>       AI speech-to-text endpoint
        --vision-endpoint <URL>    AI computer vision endpoint
    -h, --help                     Print help
    -V, --version                  Print version
```

### Environment Variables

| Variable             | Equivalent Flag       | Description                              |
| -------------------- | --------------------- | ---------------------------------------- |
| `AI_STT_ENDPOINT`   | `--stt-endpoint`      | Speech-to-text inference endpoint        |
| `AI_VISION_ENDPOINT`| `--vision-endpoint`   | Computer vision inference endpoint       |
| `PROMETHEUS_PORT`   | —                      | Prometheus metrics port (default: `9090`)|
| `RUST_LOG`          | —                      | Log level filter (e.g. `info`, `debug`)  |

---

## PLP: The Last Protocol

Pulse speaks PLP for everything. Your app never needs HTTP, REST, WebSocket wrappers, or any other protocol:

### Real-Time Streams
```typescript
const conn = await Pulse.connect('wss://pulse.example.com', { apiKey: 'pk_...' })
const chat = conn.stream('chat')
chat.send('hello')
```

### Control Plane (replaces HTTP REST API)
```typescript
const sessions = await conn.service('sessions', 'list')
const schema = await conn.service('schemas', 'register', {
    subject: 'ChatMessage',
    schema: '...',
})
```

### HTTP Proxy (replaces fetch/axios)
```typescript
const response = await conn.plpFetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer sk-...' },
    body: { model: 'gpt-4', messages: [{ role: 'user', content: 'hi' }] },
})
```

### Webhooks (replaces Express/Fastify)
```typescript
const stripe = await conn.webhook('/payments/stripe')
stripe.on('request', (req) => {
    const isValid = verifyStripeSignature(req.headers, req.body)
    req.respond(isValid ? 200 : 400, { received: isValid })
})
```

---

## Architecture

### Transport Layer

| Transport     | Protocol             | Wire Format               | Clients                          |
| ------------- | -------------------- | ------------------------- | -------------------------------- |
| **QUIC**      | PLP over QUIC streams| Binary PLP frames         | Rust, Swift, Kotlin, Go, Python  |
| **WebSocket** | PLP over WS binary   | Binary PLP frames in WS   | TypeScript / Browsers            |

### PLP Packet Types (20 types)

```
Classic (4-bit type, wire-compatible with v1):
  0x01  CONNECT            0x06  STREAM_CLOSE     0x0B  MIGRATE
  0x02  ACCEPT             0x07  STREAM_RESET     0x0C  MIGRATE_ACK
  0x03  REJECT             0x08  PING             0x0D  RELAY_FORWARD
  0x04  STREAM_OPEN        0x09  PONG             0x0E  PRIORITY
  0x05  STREAM_DATA        0x0A  METRICS          0x0F  GO_AWAY

Extended (extension byte, backward-compatible):
  0x10  SERVICE_REQUEST    0x12  HTTP_INBOUND     0x14  HTTP_RESPONSE
  0x11  SERVICE_RESPONSE   0x13  HTTP_OUTBOUND
```

### Project Structure

```
pulse-relay/src/
├── lib.rs             # pub run() — full server startup (called by pulse-cli)
├── main.rs            # Thin wrapper for backward-compat standalone binary
├── config.rs          # Configuration defaults
├── session.rs         # PLP session & stream handler
├── sfu.rs             # Selective Forwarding Unit routing core
├── ws_gateway.rs      # WebSocket → PLP bridge for browsers
├── service.rs         # Embedded control-plane service router
├── http_bridge.rs     # Outbound HTTP proxy (conn.plpFetch)
├── webhook.rs         # Inbound webhook registry
├── edge_wasm.rs       # Wasmtime WASM engine for edge transforms
├── media.rs           # Media processing pipeline (WASM chain)
├── ai_processor.rs    # Edge AI inference (STT, Vision)
├── gpu.rs             # GPU hardware detection & VRAM management
├── nat.rs             # NAT traversal / UDP hole-punching
├── telemetry.rs       # Per-connection metrics aggregation
├── observability.rs   # Prometheus + OpenTelemetry setup
├── transcode.rs       # Dual-mode codec transcoding bridge
├── record.rs          # Session recording / replay
├── ringbuf.rs         # Zero-copy ring buffer for packets
└── nic.rs             # NIC / XDP stats (Linux)
```

---

## Ports

| Port   | Protocol | Service                          |
| ------ | -------- | -------------------------------- |
| `4001` | UDP      | QUIC/PLP relay (native clients)  |
| `4001` | TCP      | WebSocket + HTTP webhook bridge  |
| `9090` | TCP      | Prometheus metrics endpoint      |

---

## Development

### Run Tests

```bash
cargo test -p sansavision-pulse
```

### Run Locally

```bash
# Via unified CLI (recommended)
cargo run -p sansavision-pulse-cli -- serve

# With explicit flags
cargo run -p sansavision-pulse-cli -- serve --mode standalone --bind 127.0.0.1:4001

# Via standalone relay binary (backward-compat)
cargo run -p sansavision-pulse -- --mode standalone --bind 127.0.0.1:4001
```

---

## License

MIT — see [LICENSE](../LICENSE) for details.
