> ## Documentation Index
> Fetch the complete documentation index at: https://docs.westyx.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Angular SDK - SSE Live Updates

> How SSE live propagation works in the Angular SDK, including NgZone re-entry and 429 handling.

The SDK opens a persistent `fetch`-based SSE connection to `GET <baseUrl>/v1/stream`. The API key is sent as the `X-Nexus-API-Key` request header - the same header used by all other endpoints. The `?key=` query parameter is no longer used.

After the initial sync completes, whenever the Nexus backend emits a change event (`config.updated`, `flag.toggled`, `resync`, ...), the SDK triggers an immediate full re-sync - so the in-memory cache is updated within milliseconds of a change, instead of waiting for the next TTL tick.

## Authentication

The Angular SDK sends the API key as the `X-Nexus-API-Key` header on the stream connection. Unlike `EventSource`, the `fetch` API supports custom request headers on streaming responses, so no query parameter workaround is needed.

<Info>
  Secret keys (`wxs_…`) are rejected at `NexusClient.create()` time. Only public keys (`wxp_…`) may be used with browser SDKs.
</Info>

## Angular zone integration

Stream events are processed outside Angular's zone. The SDK automatically re-enters the zone (via `NgZone.run(...)`) before calling observer callbacks, so component bindings and signals update correctly. This is handled by `provideNexus()` and `NexusModule.forRoot()` - no extra configuration is needed.

## Reconnect and error handling

After a transport failure the SDK schedules a reconnect with exponential backoff (1 s → 30 s capped). After 3 consecutive failures, the SDK falls back to TTL polling and emits `FALLBACK_REASON_MAX_ERRORS`. The SDK then automatically schedules an SSE reconnect using the `sseReconnectCooldown` schedule (default: 5 → 10 → 20 → 40 → 60 min). When the timer fires, the failure counter resets and `connectStream()` is called automatically. *(v0.6.0)*

## 429 Rate limiting and quarantine

If the server responds with HTTP 429, the SDK checks the response body:

* `{"error":"quarantined"}` → fires `onQuarantined(reason, expiresAt)` and reconnects after the quarantine window.
* Any other 429 → fires `onFallback("rate-limited")`. If `Retry-After` is present, reconnects after the indicated value (clamped to 5–300 s). If absent, falls back to TTL polling and schedules reconnect via the `sseReconnectCooldown` schedule. *(v0.6.0)*

## Reactive flag signals *(v0.6.1)*

Use `getFlagSignal()` to get a `Signal<boolean>` that updates automatically whenever the cache refreshes after an SSE event or TTL poll:

```ts theme={null}
import { Component } from '@angular/core';
import { injectNexus } from '@westyx-nexus/sdk-angular';

@Component({
  template: `@if (showBanner()) { <app-banner /> }`,
})
export class BannerComponent {
  private nexus = injectNexus();
  readonly showBanner = this.nexus.getFlagSignal('feature.banner', false);
}
```

The signal reads from an internal `_snapshotVersion` counter that the SDK bumps inside `NgZone` after every snapshot replacement. No manual `subscribe()`, `effect()`, or change-detection calls needed - Angular handles re-rendering automatically.

The equivalent for config values will follow in a future release.

## Disabling SSE

The SDK calls `connectStream()` automatically. To opt out at runtime:

```ts theme={null}
import { Component, OnInit } from '@angular/core';
import { injectNexus } from '@westyx-nexus/sdk-angular';

@Component({ ... })
export class AppComponent implements OnInit {
  private nexus = injectNexus();

  ngOnInit(): void {
    if (someCondition) {
      this.nexus.disconnectStream();
    }
  }
}
```

## What events trigger a sync

| Event                                                 | Received by public keys |
| ----------------------------------------------------- | ----------------------- |
| `resync`                                              | yes                     |
| `config.created` / `.updated` / `.deleted`            | yes                     |
| `flag.created` / `.updated` / `.toggled` / `.deleted` | yes                     |
| `secret.*`                                            | filtered server-side    |

## Lifecycle

Stream connection is automatic; teardown is also automatic when the Angular application is destroyed (the SDK listens for `DestroyRef`). Manual `disconnectStream()` is available but rarely needed in single-page apps.
