> ## 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 - API Reference

> Every public method, signal, and token exported by the Angular SDK.

Every public symbol exported by `@westyx-nexus/sdk-angular`. All read methods are synchronous (cache-backed); only the lifecycle methods touch the network.

## Bootstrap

### `provideNexus(config)`

Returns an `EnvironmentProviders[]` array suitable for the `providers: []` array of an `ApplicationConfig` (standalone apps).

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

export const appConfig: ApplicationConfig = {
  providers: [
    provideNexus({ baseUrl: '...', apiKey: 'wxp_...' }),
  ],
};
```

Internally registers an `APP_INITIALIZER` that performs the blocking initial sync and instantiates the singleton client.

### `NexusModule.forRoot(config)`

Equivalent for NgModule-based apps:

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

@NgModule({
  imports: [NexusModule.forRoot({ baseUrl: '...', apiKey: 'wxp_...' })],
})
export class AppModule {}
```

### `injectNexus()` and `NEXUS_CLIENT`

Two equivalent ways to get the singleton client inside a component or service:

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

const a = injectNexus();         // convenience helper
const b = inject(NEXUS_CLIENT);  // raw token - same instance
```

## NexusClient public surface

### Configs

```ts theme={null}
nexus.getConfig(key: string): unknown;
nexus.getConfigAs<T>(key: string): T | undefined;
nexus.getAllConfigs(): Map<string, unknown>;
```

`getConfig` returns the raw decoded JSON value. `getConfigAs<T>` is a thin generic wrapper for callers who know the expected type and want it cast.

public-key clients only see configs where `is_public: true`.

### Feature flags

```ts theme={null}
nexus.getFlag(key: string, defaultValue?: boolean): boolean;
nexus.getFlagSignal(key: string, defaultValue?: boolean): Signal<boolean>;
nexus.getAllFlags(): Map<string, boolean>;
```

`getFlag` returns the current boolean from the in-memory cache (synchronous, one-shot read).

`getFlagSignal` returns a reactive Angular `Signal<boolean>` that re-evaluates automatically after every cache refresh - both TTL polls and SSE push events. This is the recommended method for template bindings that should reflect live flag changes without manual subscription. *(v0.6.1)*

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

Returns `defaultValue` (default `false`) when the key is absent.

### AB Testing

Batch evaluation of AB-Testing flags against the Nexus backend. Unlike `getFlag`, these methods always perform a fresh HTTP request - results are user-scoped and depend on per-call attributes, so they are intentionally not cached. *(v0.3.0)*

#### `evaluateAB(keys, userId, attributes)` - Observable variant

```ts theme={null}
nexus.evaluateAB(
  keys:       string[],
  userId:     string,
  attributes: Record<string, unknown>,
): Observable<Record<string, boolean>>;
```

Returns a cold RxJS `Observable` that emits the `flag-key -> boolean` map exactly once and completes.

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

@Component({ ... })
export class CheckoutComponent implements OnDestroy {
  private nexus = injectNexus();
  private sub?: Subscription;

  showCheckoutV2 = false;

  ngOnInit(): void {
    this.sub = this.nexus
      .evaluateAB(['checkout-v2'], 'user-abc', { plan: 'pro', country: 'HU' })
      .subscribe({
        next:  (results) => { this.showCheckoutV2 = results['checkout-v2'] ?? false; },
        error: (err)     => { /* see error cases below */ },
      });
  }

  ngOnDestroy(): void {
    this.sub?.unsubscribe();
  }
}
```

#### `evaluateABPromise(keys, userId, attributes)` - Promise variant

```ts theme={null}
nexus.evaluateABPromise(
  keys:       string[],
  userId:     string,
  attributes: Record<string, unknown>,
): Promise<Record<string, boolean>>;
```

Same request and error mapping as `evaluateAB`, exposed as a `Promise` for `async/await` call sites.

#### Error cases

| Error                           | Status | When                                                |
| ------------------------------- | ------ | --------------------------------------------------- |
| `NexusAbAddonNotAvailableError` | `403`  | The AB Testing add-on is not active for the tenant. |
| `NexusUnauthorizedError`        | `401`  | Invalid API key or Double-Gate slug mismatch.       |
| `NexusBillingError`             | `402`  | The tenant has overdue invoices.                    |
| `NexusNotFoundError`            | `404`  | Unknown subdomain or endpoint.                      |

### Secrets

```ts theme={null}
nexus.getSecret(key: string): string;
```

Browser SDKs use public keys, which never have access to secrets. Calling `getSecret(...)` throws `NexusPublicKeyError` synchronously. The method exists for API symmetry across SDKs; in practice you never invoke it from browser code.

### Metadata

| Property          | Type           | Description                                                                                                                                    |
| ----------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `keyType`         | `'sk' \| 'pk'` | Detected from the configured `apiKey`. Browser SDKs always report `'pk'`.                                                                      |
| `syncedAt`        | `Date`         | Timestamp of the last successful sync.                                                                                                         |
| `streamConnected` | `boolean`      | `true` while the SSE stream is connected and pushing events.                                                                                   |
| `kind`            | `string`       | The service kind reported by the backend: `"frontend"`, `"backend"`, or `""` if not yet known. *(v0.2.0)*                                      |
| `billingOverdue`  | `boolean`      | `true` after a 402 Payment Required; `false` once a subsequent sync succeeds. While true the SDK halts the background refresh loop. *(v0.2.0)* |

### Sync / lifecycle

```ts theme={null}
await nexus.sync();           // force a sync now, bypassing the TTL
nexus.connectStream();        // start SSE (idempotent)
nexus.disconnectStream();     // stop SSE
nexus.subscribe(listener);    // listener called on every snapshot replacement
```

The SDK calls `connectStream()` automatically after the initial sync. Disconnect explicitly only if you want to stop receiving live updates without disposing the whole client.

`subscribe()` returns an unsubscribe function. The callback runs on the Angular zone (so signals / change detection work without `ngZone.run()` boilerplate).

## Error types

```ts theme={null}
import {
  NexusError,                       // base class
  NexusBillingError,                // 402 - tenant has overdue invoices (v0.2.0)
  NexusServiceKindMismatchError,    // getSecret on kind=frontend (v0.2.0)
  NexusAbAddonNotAvailableError,    // evaluateAB on tenant without AB add-on (v0.3.0)
  NexusInitError,                   // initial sync failure (cause carries detail)
  NexusUnauthorizedError,           // HTTP 401
  NexusNotFoundError,               // HTTP 404
  NexusPublicKeyError,              // getSecret() with public key
  NexusSecretNotFoundError,         // unknown secret key
} from '@westyx-nexus/sdk-angular';
```

## Type helpers

```ts theme={null}
import {
  PublicApiKey,        // branded string type - narrows public keys at compile time
  assertPublicKey,     // runtime guard - throws if key is not wxp_
} from '@westyx-nexus/sdk-angular';
```

```ts theme={null}
const raw: string = environment.nexusApiKey;
assertPublicKey(raw);  // raw is now PublicApiKey

provideNexus({ baseUrl: '...', apiKey: raw });
```
