# Signal — `@sonordev/site-kit/signal`

Real-time A/B experiments, behavior tracking, and dynamic configuration from Signal AI. Requires `full_signal` plan.

## Usage

Auto-included by `SiteKitLayout` when `signal` prop is enabled:

```tsx
<SiteKitLayout signal>{children}</SiteKitLayout>
```

For standalone use:

```tsx
'use client'
import { SignalBridge } from '@sonordev/site-kit/signal'

export default function Providers({ children }) {
  return <SignalBridge>{children}</SignalBridge>
}
```

## A/B Experiments

### Declarative

```tsx
import { SignalExperiment } from '@sonordev/site-kit/signal'

<SignalExperiment
  experimentId="hero-cta"
  variants={{
    control: <Button>Get Started</Button>,
    variant_a: <Button>Start Free Trial</Button>,
  }}
  trackImpression
  fallback={<Button>Default</Button>}
/>
```

### Hook-Based

```tsx
import { useSignalExperiment } from '@sonordev/site-kit/signal'

function HeroCTA() {
  const { variant, isControl } = useSignalExperiment('hero-cta')
  return isControl ? <Button>Get Started</Button> : <Button>Start Free Trial</Button>
}
```

### Conversion Tracking

```tsx
import { ExperimentConversion } from '@sonordev/site-kit/signal'

<ExperimentConversion experimentId="hero-cta" conversionType="click">
  <Button>Sign Up</Button>
</ExperimentConversion>
```

## Hooks

```ts
useSignal()                    // Full context: config, loading, trackEvent, trackOutcome
useSignalConfig()              // Just the config object
useSignalEvent()               // Returns trackEvent function
useSignalOutcome()             // Returns trackOutcome function
useSignalExperiment(id)        // Returns { assignment, variant, isControl }
```

## SignalBridge Props

```ts
interface SignalBridgeProps {
  enabled?: boolean              // Default: true
  realtime?: boolean             // SSE real-time updates (default: true)
  experiments?: boolean          // Participate in A/B tests (default: true)
  behaviorTracking?: boolean     // Scroll, clicks, time-on-page (default: true)
  children: React.ReactNode
}
```

## What It Does

1. Fetches config from `GET /api/public/signal/config`
2. Opens SSE stream for real-time `config_update` and `experiment_update` events
3. Assigns experiment variants per visitor (cached)
4. Batches behavioral events (scroll depth, click count, time-on-page) and flushes on debounce
5. Tracks outcomes/conversions via POST

## Key Types

```ts
interface ExperimentConfig {
  id: string; name: string;
  status: 'draft' | 'running' | 'paused' | 'completed';
  variants: ExperimentVariant[];
  traffic_allocation: number;    // 0-1
  goal: string;
  winner?: string;
}

interface ExperimentVariant {
  key: string; name: string; weight: number; description?: string;
}

interface SignalEvent {
  event_type: string; event_name: string; event_data?: object;
  page_url: string; page_title: string;
  engagement: { time_on_page: number; scroll_depth: number; click_count: number };
  experiments: Array<{ id: string; variant: string }>;
}
```
