---
title: "Référence d'API — nodefony/client — realtime"
source: docs/api/core/client-realtime.md
url: https://nodefony.github.io/nodefony-core/docs/api/core/client-realtime/
---


[Documentation](../../../) › [Référence d'API](../../) › [`nodefony`](../) › client-realtime

> Générée depuis les déclarations de types publiées de `nodefony` **10.0.0-beta.6** : exactement ce que reçoit une application qui l'installe. Cette page n'existe dans aucun dépôt — pour la corriger, on corrige le TSDoc du code.

## `nodefony/client`

`import { … } from "nodefony/client"` — 58 symboles.

### Classes (3)

#### `AdaptiveRate`

```ts
class AdaptiveRate
```

- `constructor(options: AdaptiveRateOptions)`
- `current(): number` — Cadence courante (ms).
- `noteFrame(now: number): RateDecision | null` — À appeler à CHAQUE frame reçue.
- `checkStarvation(now: number): RateDecision | null` — Watchdog : à appeler périodiquement.

#### `BrowserWsTransport`

```ts
class BrowserWsTransport implements IRealtimeTransport
```

BrowserWsTransport — transport `IRealtimeTransport` pour le navigateur : wrap d'un `WebSocket` natif. Volontairement « bête » : il ouvre/envoie/ferme et relaie les events. L'orchestration (reconnect, backoff, heartbeat, state machine) vit AU-DESSUS dans `NodefonySocket` — qui crée un transport NEUF à chaque tentative.

- `constructor(url: string, protocols?: readonly string[])`
- `connect(): void` — Ouvre le transport (asynchrone — l'ouverture effective est signalée par `onOpen`).
- `send(raw: RealtimeOutboundData): void` — Envoie une frame brute (texte sérialisé ou octets).
- `close(code?: number, reason?: string): void` — Ferme le transport (déclenche `onClose`).
- `get readyState(): number` — État courant (0..3, cf `TransportState`).
- `get bufferedAmount(): number` — Octets que le navigateur n'a pas encore écoulés sur le réseau.
- `onOpen(cb: () => void): void` — Branche le handler d'ouverture (le owner relance subscribe/heartbeat).
- `onMessage(cb: (raw: RealtimeFrameData) => void): void` — Branche le pump entrant : appelé pour CHAQUE frame brute reçue, texte ou binaire — jamais filtrée ici (cf `RealtimeFrameData`).
- `onClose(cb: (code: number, reason: string) => void): void` — Branche la fermeture (le owner relance le backoff ou nettoie).
- `onError(cb: (err: unknown) => void): void` — Branche les erreurs transport (la fermeture qui suit gère le reconnect).

#### `NodefonySocket`

```ts
class NodefonySocket<Emit extends EventsMap = DefaultEventsMap, Listen extends EventsMap = DefaultEventsMap, Actions extends ActionsMap = DefaultActionsMap, Routes extends RoutesMap = RoutesMap> implements IRealtimeSocket<Emit, Listen>, IRealtimePeer<Emit, Actions>
```

Socket cliente de Nodefony : une connexion WebSocket JSON-RPC 2.0 vers le serveur temps réel de l'application, qui rétablit la liaison après une coupure.

- `constructor(opts?: NodefonySocketOptions, transportFactory?: RealtimeTransportFactory)`
- `static shared(opts?: NodefonySocketOptions): NodefonySocket` — Instance de connexion **partagée par URL** (résolue en absolu) sur `globalThis`.
- `static fromContract<C extends IRealtimeContract>(opts?: FromContractOptions, transportFactory?: RealtimeTransportFactory): NodefonySocket<ContractClientEmit<C>, ContractClientListen<C>, ContractClient …` — Socket typée par le contrat de l'application — la porte du client.
- `get state(): RealtimeState`
- `get reconnectAttempts(): number` — Nombre de tentatives de reconnexion depuis la dernière connexion STABLE — restée ouverte au moins 5 s.
- `get nextRetryAt(): number | null` — Timestamp (ms epoch) de la prochaine tentative de reconnexion planifiée, `null` hors backoff.
- `retryNow(): void` — Force une reconnexion **immédiate** (annule le backoff en cours).
- `connect(url?: string): Promise<void>` — Ouvre la connexion WS.
- `disconnect(): void`
- `on<K extends string>(event: K, handler: K extends EventNames<Listen> ? (payload: EventPayload<Listen, K>) => void : RealtimeHandler): () => void` — Pub/sub local — handler sur un event server-pushed (notification JSON-RPC).
- `off<K extends string>(event: K, handler: K extends EventNames<Listen> ? (payload: EventPayload<Listen, K>) => void : RealtimeHandler): void` — Retire un handler d'un canal.
- `onNotice(handler: (notice: NodefonyNotice) => void): () => void` — S'abonne aux **notices normalisées** émises par le client : criticités qui cassent le temps réel (close codes RFC 6455 interprétés via `closeCodeToNotice`), erreurs serveur poussées, rétablissement de …
- `onDenied(handler: (denied: IRealtimeDenied) => void): () => void` — S'abonne aux **refus de canal** poussés par le serveur (`realtime:denied`) : un `subscribe`/push vers un canal protégé sans droit suffisant.
- `onSubscribed(handler: (ack: IRealtimeSubscribed) => void): () => void` — S'abonne aux **acquittements d'abonnement** poussés par le serveur (`realtime:subscribed`) : le canal est désormais actif sur la connexion courante.
- `onClosed(handler: (closed: IRealtimeClosed) => void): () => void` — S'abonne aux **fins d'abonnement** décidées par le serveur (`realtime:closed`) : le canal est terminé pour tous (`ended`), ou cette connexion en a été retirée (`evicted`).
- `whenSubscribed(channel: EventNames<Listen> | (string & {})): Promise<void>` — Attend que l'abonnement à `channel` soit EFFECTIF côté serveur — le signal qui manquait au patron « je recharge l'état, puis je suis le flux ».
- `emit<K extends string>(method: K, params?: K extends EventNames<Emit> ? EventPayload<Emit, K> : unknown): void` — Notification one-way client → server (pas de réponse attendue).
- `publish<K extends string>(channel: K, payload?: K extends EventNames<Emit> ? EventPayload<Emit, K> : object): void` — Émet sur un canal — verbe socket de `IRealtimeSocket.publish`.
- `subscribe(channel: EventNames<Listen> | (string & {})): void` — S'abonne à un canal pub/sub serveur (**ref-compté**).
- `unsubscribe(channel: EventNames<Listen> | (string & {})): void` — Désabonne un consommateur d'un canal (ref-compté) : émet `unsubscribe` au serveur seulement au **dernier** consommateur.
- `get subscribedChannels(): string[]` — Canaux DEMANDÉS (≥ 1 consommateur) — l'intention locale, pas un état confirmé par le serveur : l'abonnement effectif se lit sur `whenSubscribed` / `onSubscribed`.
- `get url(): string | null` — L'adresse du serveur temps réel, telle qu'elle a été donnée (ou résolue en absolu par `shared`).
- `get identity(): RealtimeIdentity | null` — Identité de la connexion, **annoncée par le serveur** au `realtime:welcome` (`RealtimeIdentity`).
- `get serverChannels(): readonly string[] | null` — Canaux pub/sub annoncés par le serveur au welcome (découverte).
- `get serverMethods(): readonly string[] | null` — Actions RPC annoncées par le serveur au welcome (découverte).
- `onIdentity(handler: (identity: RealtimeIdentity | null) => void): () => void` — S'abonne à l'identité résolue (event LOCAL `__identity__`, jamais réseau) : le handler est rappelé à chaque (re)welcome et au `disconnect()`.
- `onUser(handler: (payload: UserChannelPayload<Listen>) => void): () => void` — Reçoit les messages adressés à l'identité de CETTE connexion — `publishToUser(id, charge)` côté serveur (ADR-0022 §6, D1).
- `onState(handler: (state: RealtimeState) => void): () => void` — S'abonne à l'**état de la connexion** (event LOCAL `__state__`, jamais réseau) : le handler est rappelé à chaque transition (`connecting`, `connected`, `reconnecting`, `error`, `disconnected`), jamais …
- `onStats(handler: () => void): () => void` — S'abonne au **tick d'échantillonnage des statistiques** (event LOCAL `__stats__`, jamais réseau), émis une fois par seconde après recalcul des débits par canal.
- `onBinary(handler: (data: Uint8Array<ArrayBuffer>) => void): () => void` — Lit les trames BINAIRES reçues sur la socket — le point d'extension d'un protocole binaire écrit par l'application, à côté du JSON-RPC.
- `sendBinary(data: Uint8Array<ArrayBuffer>): boolean` — Émet une trame BINAIRE, sans la sérialiser — le pendant sortant de `onBinary`.
- `onReconnect(handler: (info: RealtimeReconnectInfo) => void): () => void` — S'abonne aux **tentatives de reconnexion programmées** (event LOCAL `__reconnect__`, jamais réseau) : numéro d'essai, délai retenu par le back-off, et échéance absolue.
- `channel(name: string): IRealtimeChannel` — Handle « socket-like » d'un canal (`IRealtimeChannel`) — fine liaison sur les primitives (`subscribe`/`on`/`publish`/`unsubscribe`), forme naturelle des canaux à état (SIP, bridge) et point d'accroche …
- `adaptiveChannel(base: string, handler: RealtimeHandler, options: BindAdaptiveOptions): AdaptiveChannelBinding` — S'abonne à un canal d'ÉTAT en **cadence adaptative** (AIMD client-driven) : la lib mesure la gigue d'arrivée et ré-abonne automatiquement à une cadence plus grossière en cas de famine, plus fine quand …
- `request<K extends string, T = unknown>(method: K, params?: ContractParams<Actions, K>, timeoutMs?: number): Promise<ContractResult<Actions, K, T>>` — Request/response JSON-RPC 2.0 — `Promise` résolue avec le `result`.
- `request<K extends ActionNames<Actions>>(method: K, params?: ActionParams<Actions, K>, timeoutMs?: number): Promise<ActionResult<Actions, K>>` — Request/response JSON-RPC 2.0 — `Promise` résolue avec le `result`.
- ``get<T = unknown, P extends `/${string}` = `/${string}`>(path: P, ...options: BridgeReadArgs<ContractRouteQuery<Routes, `GET ${P}`>, ContractRouteParams<Routes, `GET ${P}`, P>>): Promise<ContractRouteR …`` — Lit une route par le pont `api.request` — la MÊME action contrôleur que le `GET` HTTP, par la socket.
- ``post<T = unknown, P extends `/${string}` = `/${string}`>(path: P, ...args: BridgeWriteArgs<Routes, `POST ${P}`, P>): Promise<ContractRouteResult<Routes, `POST ${P}`, T>>`` — Écrit par le pont `api.request` : la route `POST` de même chemin, par la socket.
- ``put<T = unknown, P extends `/${string}` = `/${string}`>(path: P, ...args: BridgeWriteArgs<Routes, `PUT ${P}`, P>): Promise<ContractRouteResult<Routes, `PUT ${P}`, T>>`` — Remplace par le pont (`PUT`) — mêmes règles que `post`.
- ``patch<T = unknown, P extends `/${string}` = `/${string}`>(path: P, ...args: BridgeWriteArgs<Routes, `PATCH ${P}`, P>): Promise<ContractRouteResult<Routes, `PATCH ${P}`, T>>`` — Modifie par le pont (`PATCH`) — mêmes règles que `post`.
- ``delete<T = unknown, P extends `/${string}` = `/${string}`>(path: P, ...args: BridgeWriteArgs<Routes, `DELETE ${P}`, P>): Promise<ContractRouteResult<Routes, `DELETE ${P}`, T>>`` — Supprime par le pont (`DELETE`) — mêmes règles que `post`.
- ``call<T = unknown>(path: `/${string}`, init?: ICallInit): Promise<IApiCallResult<T>>`` — Appel API par la socket rendant l'**enveloppe complète** — le résultat ET la méta serveur — là où `get`/`post` ne rendent que la valeur (forme courante, contrat « snapshot ≡ GET REST »).
- `ping(timeoutMs?: number): Promise<KernelPingResult & { rtt: number; }>` — Mesure le round-trip WS via la méthode RPC standard `nodefony:kernel:ping` — helper RÉUTILISABLE par tout consommateur (topbar Studio, debug bar, app user) : la mesure du RTT et la convention `nodefon …
- `notify<K extends EventNames<Emit>>(method: K, params?: EventPayload<Emit, K>): void` — Notification SORTANTE typée (pas de réponse).
- `register<K extends ActionNames<Actions>>(method: K, handler: TypedRpcActionHandler<Actions, K>): void` — Expose une action appelable PAR LE PAIR (requête entrante serveur→client).
- `unregister(method: ActionNames<Actions>): void` — Retire une action exposée.
- `get methods(): string[]` — Actions exposées par CE client (découverte).
- `receive(frame: unknown, size?: number, binary?: boolean): JsonRpcFrameKind` — Ingestion d'une frame ENTRANTE déjà parsée → log + classification/route par le moteur.
- `wireStats(): Readonly<IWireStats>` — Compteurs du fil de cette socket (trames, tailles, temps de décodage), armés au PREMIER appel : avant, aucun compte n'est tenu et une trame ne paie qu'un test.
- `dispose(reason?: string): void` — Annule les requêtes sortantes en attente (fermeture transport / logout).
- `get framesReceived(): number` — Total de notifications reçues, tous canaux confondus (welcome inclus).
- `get framesUnsent(): number` — Total de frames qui n'ont **pas** pu partir depuis la création du client (transport fermé au moment de l'émission).
- `get framesDropped(): number` — Total de frames JETÉES par la contre-pression depuis la création du client (file d'envoi au-delà de `maxBufferedAmount`).
- `get binaryFramesDiscarded(): number` — Total de trames BINAIRES reçues puis écartées, faute de lecteur (`onBinary`).
- `get malformedFramesDiscarded(): number` — Total de trames TEXTE reçues puis écartées parce qu'elles ne sont pas du JSON.
- `get lastFrameAt(): number | null` — Timestamp (ms) de la dernière notification reçue.
- `get lastFrameMethod(): string | null` — `method`/canal de la dernière notification reçue.
- `get codec(): string` — Sous-protocole du codec en vigueur sur la connexion — `nodefony.jsonrpc.v1` tant que l'accueil n'en a pas annoncé un autre, et de nouveau après une coupure, jusqu'à l'accueil suivant (ADR-0022 §2).
- `getStats(): MessageStats[]` — Snapshot des stats par canal (msgCount/rate/series).
- `getChannelStats(method: string): MessageStats` — Stats d'un canal précis (== method JSON-RPC) ou `undefined`.
- `get frameLogSince(): number | null` — Depuis quand le journal retient (ms epoch), `null` s'il est éteint — les trames antérieures n'y sont pas.
- `get frameLog(): readonly RealtimeFrame[]` — Log protocole : les `FRAME_LOG_MAX` dernières frames JSON-RPC (redactées).
- `clearFrameLog(): void` — Purge le log protocole.

### Fonctions (21)

#### `adaptiveRebindKey`

```ts
function adaptiveRebindKey(base: string, desiredMs: number, enabled?: boolean): string
```

Clé de **re-liaison** d'un canal en cadence adaptative.

#### `bindAdaptiveChannel`

```ts
function bindAdaptiveChannel(socket: IRealtimeSocket, base: string, handler: RealtimeHandler, options: BindAdaptiveOptions): AdaptiveChannelBinding
```

Câble un `AdaptiveRate` à une socket réelle : abonne `base` à sa cadence désirée, mesure la gigue d'arrivée, et **ré-abonne** automatiquement à une cadence plus grossière en cas de famine (MD) puis plus fine quand c'est sain (AI). Les frames continuent d'être livrées à `handler` à travers les changements de cadence.

#### `closeCodeToNotice`

```ts
function closeCodeToNotice(code: number, reason?: string): NodefonyNotice | null
```

Traduit un **code de fermeture WebSocket** (RFC 6455 §7.4) en `NodefonyNotice` — pendant CLIENT du `toWsCloseCode` serveur (`@nodefony/http`). Pur, sans état, donc trivialement testable et réutilisable.

#### `connectShared`

```ts
function connectShared(opts: ConnectSharedOptions): SharedConnection
```

Résout la socket partagée d'une adresse — ou adopte celle qu'on lui donne — et rend de quoi la démarrer sans jamais la couper.

#### `describeCodec`

```ts
function describeCodec(protocol: string): string
```

Le format des frames d'une connexion, mis en mots — la MÊME phrase dans la console, la vignette d'une page, la barre de debug et le diagnostic du noyau.

#### `describeSocket`

```ts
function describeSocket(snapshot: SocketSnapshot, now?: number): SocketDetailRow[]
```

Ce que le client sait de SA socket, mis en mots — la même description pour le tableau de la console du navigateur et pour la vignette qu'une page affiche.

#### `isLocalEvent`

```ts
function isLocalEvent(event: string): event is LocalEvent
```

Vrai si `event` est un événement local du client (jamais un canal réseau).

#### `observeAdaptiveChannel`

```ts
function observeAdaptiveChannel<L extends EventsMap, K extends EventNames<L>>(client: ChannelSocket<L>, base: K, emit: Emit<ChannelPayload<L, K>>, desiredMs: number, options?: AdaptiveObserveOptions): AdaptiveChannelBinding
```

Observe un canal d'ÉTAT en **cadence adaptative** (AIMD piloté par le client) : la cadence recule sous famine et remonte quand c'est sain, sans changement serveur. `emit` reçoit chaque frame à travers les changements de cadence.

#### `observeChannel`

```ts
function observeChannel<L extends EventsMap, K extends EventNames<L>>(client: ChannelSocket<L>, channel: K, emit: Emit<ChannelPayload<L, K>>): Dispose
```

Observe un canal pub/sub : `emit` est appelé pour chaque message reçu.

#### `observeChannelData`

```ts
function observeChannelData<L extends EventsMap, K extends EventNames<L>>(client: ChannelSocket<L>, channel: K, emit: Emit<ChannelPayload<L, K> | null>, initial?: ChannelPayload<L, K> | null): Dispose
```

Observe la **dernière valeur** reçue sur un canal — le cas le plus courant (dernière mesure d'un flux d'état). `emit` reçoit `initial` immédiatement, puis chaque nouvelle valeur : dernier arrivé gagne.

#### `observeChannelStats`

```ts
function observeChannelStats(client: ObservableClient, channel: string, emit: Emit<MessageStats | null>): Dispose
```

Observe les **statistiques** d'un canal (débit, série du VU-mètre, total), rafraîchies par l'échantillonneur du client une fois par seconde. `emit` reçoit l'instantané courant immédiatement, puis à chaque échantillon.

#### `observeIdentity`

```ts
function observeIdentity(client: ObservableClient, emit: Emit<RealtimeIdentity | null>): Dispose
```

Observe l'identité résolue par le serveur au welcome (`null` tant qu'aucun welcome n'est arrivé, et après un `disconnect()` volontaire). `emit` reçoit la valeur courante immédiatement, puis à chaque (re)welcome.

#### `observeKernelIdentity`

```ts
function observeKernelIdentity(kernel: INodefonyKernel, emit: Emit<NodefonyKernelIdentity | null>): Dispose
```

Observe l'identité DÉCLARÉE au noyau par l'application (`setIdentity`) — `null` hors session. `emit` reçoit la valeur courante immédiatement, puis à chaque changement de COMPTE.

#### `observeKernelState`

```ts
function observeKernelState(kernel: INodefonyKernel, emit: Emit<NodefonyKernelState>): Dispose
```

Observe l'état du noyau client (`created` → `booting` → `ready` → `terminated`). `emit` reçoit l'état courant **immédiatement**, puis à chaque transition.

#### `observeNoticeLog`

```ts
function observeNoticeLog(client: ObservableClient, emit: Emit<NodefonyNotice[]>, opts?: ObserveNoticeLogOptions): Dispose
```

Observe un **historique borné** des dernières notices, filtrable par source : un journal léger des incidents temps réel, distinct des notifications éphémères. `emit` reçoit le tableau complet à chaque changement.

#### `observeNotices`

```ts
function observeNotices(client: ObservableClient, emit: Emit<NodefonyNotice>): Dispose
```

Observe les **notices normalisées** du client : criticités qui cassent le temps réel (codes de fermeture RFC 6455 interprétés), erreurs poussées par le serveur, rétablissement de connexion. `emit` est appelé pour CHAQUE notice — de quoi brancher un centre de notifications.

#### `observeReconnect`

```ts
function observeReconnect(client: ObservableClient, emit: Emit<RealtimeReconnectInfo>): Dispose
```

Observe les **tentatives de reconnexion** programmées par le back-off : numéro d'essai, délai retenu, échéance absolue. De quoi rendre un compte à rebours plutôt qu'un « déconnecté » muet.

#### `observeSnapshot`

```ts
function observeSnapshot(client: ObservableClient, emit: Emit<SocketSnapshot>): Dispose
```

Observe l'instantané : `emit` reçoit la valeur courante immédiatement, puis à chaque échantillon du client (une fois par seconde), à chaque changement d'état et à chaque accueil qui change l'identité — les seuls moments où il peut avoir bougé de façon visible.

#### `observeState`

```ts
function observeState(client: ObservableClient, emit: Emit<RealtimeState>): Dispose
```

Observe l'état de la connexion. `emit` reçoit l'état courant **immédiatement**, puis à chaque transition — une liaison n'a donc rien à initialiser à part.

#### `observeSyslog`

```ts
function observeSyslog(client: ObservableClient, emit: Emit<unknown[]>, opts?: ObserveSyslogOptions): Dispose
```

Observe le **journal du serveur** : anneau borné, filtre de sévérité, et surtout le format **coalescé** du canal (`{ logs: Pdu[], dropped }`) autant que l'entrée unique. `emit` reçoit le tableau complet à chaque changement — une nouvelle référence, directement affichable.

#### `socketSnapshot`

```ts
function socketSnapshot(client: SnapshotSource): SocketSnapshot
```

Lit l'instantané courant. Purement local : aucune trame n'est émise, rien n'est demandé au serveur — afficher cet état ne coûte donc rien au réseau.

### Constantes (1)

#### `LOCAL_EVENTS`

```ts
const LOCAL_EVENTS: { readonly state: "__state__"; readonly identity: "__identity__"; readonly stats: "__stats__"; readonly notice: "__notice__"; readonly denied: "__denied__"; readonly subscribed: "__subscribed__"; readonly closed: "__closed__"; readonly reconnect: "__reconnect__"; readonly frame: "__frame__"; }
```

Événements locaux du `NodefonySocket` — jamais émis ni reçus par le réseau.

### Interfaces (21)

#### `AdaptiveChannelBinding`

```ts
interface AdaptiveChannelBinding
```

Poignée du canal adaptatif — cadence courante + coupure.

- `readonly intervalMs: number` — Cadence courante (ms).
- `readonly channel: string` — Canal effectivement abonné (`base` ou `base:<ms>`).
- `dispose(): void` — Coupe tout : watchdog + handler + `unsubscribe`.

#### `AdaptiveRateOptions`

```ts
interface AdaptiveRateOptions
```

Réglages de la cadence adaptative. Seul `intervalMs` est requis.

- `readonly intervalMs: number` — Cadence désirée la plus fine (ms) = bas de l'échelle.
- `readonly defaultMs?: number` — Cadence par défaut serveur du canal (le canal nu la vaut).
- `readonly ladder?: number[]` — Échelle de cadences (ms, croissante).
- `readonly starvationFactor?: number` — Famine : `gap observé > k × cadence courante` ⇒ décélère.
- `readonly healthyFactor?: number` — Sain : `gap ≤ k × cadence` compte comme bon échantillon.
- `readonly recoveryWindow?: number` — Nb d'échantillons sains consécutifs avant d'accélérer (AI).
- `readonly maxMs?: number` — Plafond de l'échelle dérivée (ms).

#### `AdaptiveScheduler`

```ts
interface AdaptiveScheduler
```

Planificateur du watchdog — injectable pour des tests déterministes (défaut : globals).

- `set(cb: () => void, ms: number): unknown`
- `clear(handle: unknown): void`

#### `BindAdaptiveOptions`

```ts
interface BindAdaptiveOptions extends AdaptiveRateOptions
```

Réglages du câblage adaptatif = `AdaptiveRateOptions` + crochets/injection.

- `enabled?: boolean` — Active l'AIMD.
- `onRate?: (intervalMs: number, reason: RateChangeReason) => void` — Notifié à chaque cadence effective (incl.
- `clock?: () => number` — Horloge (ms).
- `scheduler?: AdaptiveScheduler` — Planificateur du watchdog.

#### `ConnectSharedOptions`

```ts
interface ConnectSharedOptions
```

Options de `connectShared` — le noyau, la socket déjà construite, ou l'adresse.

- `kernel?: INodefonyKernel | null` — Le noyau client de l'application — la voie COMPOSÉE.
- `url?: string` — Adresse du serveur temps réel — la voie SIMPLE.
- `client?: ObservableClient` — Socket déjà construite — la voie AVANCÉE, quand l'application possède son cycle de connexion (c'est le cas de la console d'administration, qui re-négocie la socket sur changement d'identité).

#### `FromContractOptions`

```ts
interface FromContractOptions extends NodefonySocketOptions
```

Options de `NodefonySocket.fromContract` : celles du constructeur, plus le choix de la socket PARTAGÉE de la page.

- `shared?: boolean` — Rendre la socket partagée de la page pour cette adresse (`NodefonySocket.shared`), vue à travers le contrat, au lieu d'en fabriquer une neuve.

#### `IApiCallResult`

```ts
interface IApiCallResult<T = unknown>
```

Enveloppe d'un appel `NodefonySocket.call` : la valeur rendue par la route, et l'identifiant du profil serveur de cette frame (dev — `null` en production, où le serveur n'émet aucune méta).

- `result: T`
- `requestId: string | null`

#### `IBridgeReadOptions`

```ts
interface IBridgeReadOptions<Q = unknown, PR = unknown>
```

Options d'une lecture par le pont (`get`).

- `query?: Q` — Query, sérialisée dans le chemin (`?a=1&b=2`, une clé répétée par élément d'un tableau).
- `params?: PR` — Valeurs des variables du gabarit (`/chat/messages/{id}` → `{ id }`), chacune encodée pour tenir dans UN segment.
- `timeoutMs?: number` — Délai avant rejet, en ms (défaut 30 s).

#### `IBridgeWriteOptions`

```ts
interface IBridgeWriteOptions<Q = unknown, PR = unknown> extends IBridgeReadOptions<Q, PR>
```

Options d'une écriture par le pont (`post`, `put`, `patch`, `delete`).

- `idempotencyKey?: string` — Clé d'idempotence — générée par défaut, une par appel.

#### `IWireStats`

```ts
interface IWireStats
```

Compteurs du fil d'une socket : trames et tailles dans chaque sens, temps passé à décoder. Cumulés depuis le premier appel de `NodefonySocket.wireStats` — un débit ou une moyenne se calcule par différence entre deux lectures.

- `framesIn: number` — Trames reçues puis décodées par le codec de la connexion.
- `framesOut: number` — Trames écrites sur le transport.
- `sizeIn: number` — Taille cumulée des trames reçues.
- `sizeOut: number` — Taille cumulée des trames écrites.
- `binaryIn: number` — Trames binaires parmi les reçues.
- `binaryOut: number` — Trames binaires parmi les écrites.
- `decodeMs: number` — Temps cumulé passé à décoder les trames reçues, en millisecondes.

#### `KernelPingResult`

```ts
interface KernelPingResult
```

Réponse de la méthode RPC standard `nodefony:kernel:ping` — CONVENTION Nodefony : tout endpoint realtime (Studio aujourd'hui, `RealtimeService` en P13.4) y répond. Sert de liveness + base de mesure du round-trip (cf `NodefonySocket.ping`).

- `pong: true`
- `ts: number`
- `uptime: number` — uptime process serveur (s).
- `pid: number`
- `version?: string`

#### `NodefonyNotice`

```ts
interface NodefonyNotice
```

Notice normalisée prête à afficher (snackbar / centre de notifications).

- `level: NoticeLevel` — Sévérité d'affichage.
- `title?: string` — Titre court (gras), optionnel.
- `message: string` — Message lisible (déjà localisé FR).
- `source: "realtime" | "api" | "server"` — Origine — `realtime` (transport WS), `api` (data plane HTTP), `server` (push).
- `code?: number` — Code corrélé : close code WS, status HTTP ou code d'erreur JSON-RPC.
- `ts: number` — Timestamp (ms epoch) de production.

#### `NodefonySocketOptions`

```ts
interface NodefonySocketOptions
```

- `url?: string`
- `token?: string | null`
- `autoReconnect?: boolean` — Reconnexion auto.
- `reconnectDelay?: number` — Délai initial entre tentatives (ms).
- `reconnectDelayMax?: number` — Délai max entre tentatives (ms).
- `connectTimeout?: number` — Délai d'ouverture (ms) : une poignée de main qui n'aboutit pas dans ce délai est abandonnée, `connect()` rejette et la reconnexion prend le relais.
- `heartbeatInterval?: number` — Heartbeat ping interval (ms).
- `probe?: RealtimeProbe | false` — Sonde d'un échec d'ouverture.
- `banner?: boolean` — Annoncer le framework dans la console du navigateur ?
- `maxBufferedAmount?: number` — Seuil (octets) de la file d'envoi du navigateur (`WebSocket.bufferedAmount`) au-delà duquel une frame sortante est JETÉE au lieu d'être mise en file — `emit`, `request` et `sendBinary` rendent alors ` …
- `backpressureCloseAfterDrops?: number` — Solde de frames jetées (+1 par frame jetée, −1 par frame partie) au-delà duquel le client FERME sa socket en `4007` (`BACKPRESSURE_CLOSE_CODE`) puis se reconnecte comme après toute coupure : une file …
- `codec?: IFrameCodec` — Codec BINAIRE à offrir au serveur — `CBOR_FRAME_CODEC`, importé de `nodefony/cbor` (ADR-0022 §2).

#### `ObserveNoticeLogOptions`

```ts
interface ObserveNoticeLogOptions
```

Options de `observeNoticeLog`.

- `max?: number` — Taille max de l'anneau (les plus anciennes notices sont évincées).
- `sources?: NodefonyNotice["source"][]` — Ne garder que ces sources (ex.

#### `ObserveSyslogOptions`

```ts
interface ObserveSyslogOptions
```

Options de `observeSyslog`.

- `max?: number` — Taille max de l'anneau (les plus anciennes lignes sont évincées).
- `severities?: string[]` — Ne garder que ces sévérités (ex.
- `channel?: string` — Canal source.

#### `RateDecision`

```ts
interface RateDecision
```

Décision de la boucle AIMD : nouvelle cadence + pourquoi. `null` = ne rien changer.

- `readonly intervalMs: number` — Cadence cible (ms).
- `readonly reason: RateChangeReason` — Cause du changement.

#### `RealtimeFrame`

```ts
interface RealtimeFrame
```

Une frame du protocole temps réel (JSON-RPC 2.0) — pour le log/inspecteur.

- `ts: number` — Timestamp (ms epoch).
- `dir: "in" | "out"` — Sens : `out` = client→serveur, `in` = serveur→client.
- `kind: string` — Méthode (notification/requête) ou `response`/`error`/`stream`.
- `id?: number` — id JSON-RPC (requêtes/réponses), si présent.
- `channel?: string` — Canal pub/sub (`params.channel`), si présent.
- `payload: unknown` — Payload affichable — champs sensibles **redactés** (token/secret…), octets résumés en `[binary N B]` (jamais vidés).
- `size: number` — Taille sur le fil : caractères d'une trame texte, octets d'une trame binaire ; `0` si inconnue.
- `binary: boolean` — Trame binaire (codec binaire de la connexion), sinon trame texte.

#### `RealtimeReconnectInfo`

```ts
interface RealtimeReconnectInfo
```

Tentative de reconnexion programmée par le back-off — charge utile de `NodefonySocket.onReconnect`.

- `attempt: number` — Numéro de la tentative depuis la dernière connexion réussie (1 = la première).
- `delay: number` — Délai retenu avant cette tentative (ms), plafonné par `reconnectDelayMax`.
- `nextRetryAt: number` — Échéance absolue de la tentative (ms epoch) — pour un compte à rebours.

#### `SharedConnection`

```ts
interface SharedConnection
```

Résultat de `connectShared` : la socket, à qui elle appartient, et comment la démarrer.

- `socket: ObservableClient` — La socket à donner aux observateurs.
- `owned: boolean` — `true` si c'est nous qui l'avons obtenue depuis l'URL — donc à nous de la connecter.
- `start(): void` — Ouvre la connexion si elle nous appartient, sinon ne fait rien.

#### `SocketDetailRow`

```ts
interface SocketDetailRow
```

Une ligne de la description d'une socket : ce qu'on lit, et pourquoi ça compte.

- `label: string` — Libellé affiché.
- `value: string` — Valeur, déjà mise en mots pour un humain.
- `hint: string` — Une phrase qui dit ce que la valeur signifie, ou ce qu'elle garantit.

#### `SocketSnapshot`

```ts
interface SocketSnapshot
```

Ce que le client sait de sa PROPRE socket, à un instant donné.

- `url: string | null` — L'adresse du serveur temps réel — de QUELLE socket cet instantané parle.
- `state: RealtimeState` — État de la connexion.
- `codec: string` — Sous-protocole du codec en vigueur — `nodefony.jsonrpc.v1` tant que l'accueil n'en annonce pas d'autre.
- `channels: readonly string[]` — Canaux effectivement tenus par cette connexion.
- `frames: number` — Notifications reçues depuis l'ouverture (accueil compris) — les réponses aux appels n'y entrent pas.
- `unsent: number` — Trames perdues faute de transport ouvert — un silence qui se compte.
- `dropped: number` — Trames jetées par la contre-pression du client (`maxBufferedAmount`) — `0` sans borne.
- `binaryDiscarded: number` — Trames binaires reçues puis écartées, faute de lecteur.
- `malformedDiscarded: number` — Trames texte reçues puis écartées parce qu'elles ne sont pas du JSON.
- `frameLogSince: number | null` — Depuis quand le journal des trames retient (ms epoch), `null` s'il est éteint.
- `lastFrame: { method: string | null; at: number | null; }` — Méthode et horodatage de la dernière notification reçue (`null` si aucune).
- `reconnectAttempts: number` — Tentatives de reconnexion depuis la dernière connexion réussie.
- `nextRetryAt: number | null` — Échéance de la prochaine tentative (ms epoch), `null` hors reconnexion.
- `identity: RealtimeIdentity | null` — Identité résolue par le serveur, `null` avant le premier welcome.
- `serverChannels: readonly string[] | null` — Canaux que le serveur annonce à l'accueil, `null` avant le premier welcome.
- `serverMethods: readonly string[] | null` — Actions que le serveur annonce à l'accueil, `null` avant le premier welcome.

### Types (12)

#### `AdaptiveObserveOptions`

```ts
type AdaptiveObserveOptions = Omit<BindAdaptiveOptions, "intervalMs">
```

Options de `observeAdaptiveChannel` — la cadence désirée est passée à part.

#### `ChannelHandler`

```ts
type ChannelHandler = (payload: unknown) => void
```

Gestionnaire d'un message de canal, tel que le reçoit une liaison.

#### `ChannelPayload`

```ts
type ChannelPayload<L extends EventsMap, K extends string> = K extends keyof L ? L[K] : unknown
```

Charge reçue sur le canal `K` d'une socket qui écoute `L` — telle que la socket la livre à `on(K, …)` (lue par `Jsonify` sous un contrat). Un nom absent de la carte, possible seulement sur une socket non paramétrée, reste `unknown`.

#### `ChannelSocket`

```ts
type ChannelSocket<L extends EventsMap> = NodefonySocket<EventsMap, L, ActionsMap>
```

Socket qui ÉCOUTE la carte `L` — n'importe quel paramétrage de `NodefonySocket`, dont celui que rend `NodefonySocket.fromContract<C>()`.

#### `Dispose`

```ts
type Dispose = () => void
```

Libération d'une souscription. Idempotente chez tous les observateurs de ce module.

#### `Emit`

```ts
type Emit<T> = (value: T) => void
```

Rappel d'une liaison de vue : reçoit la valeur courante.

#### `LocalEvent`

```ts
type LocalEvent = (typeof LOCAL_EVENTS)[keyof typeof LOCAL_EVENTS]
```

Un des noms d'événement local de la table `LOCAL_EVENTS`.

#### `MessageStats`

```ts
type MessageStats = IChannelStats
```

Stats d'un canal — alias historique de `IChannelStats` (le contrat isomorphe `IRealtimeSocket`). Conservé pour les consommateurs qui importent `MessageStats`.

#### `NoticeLevel`

```ts
type NoticeLevel = "success" | "info" | "warning" | "error"
```

Sévérité d'affichage — alignée sur les niveaux snackbar usuels.

#### `ObservableClient`

```ts
type ObservableClient = NodefonySocket
```

Socket sur laquelle un observateur travaille. Volontairement le client NON paramétré : une liaison de vue ne connaît pas les cartes d'événements typées de l'application.

#### `RateChangeReason`

```ts
type RateChangeReason = "init" | "decrease" | "increase"
```

Raison d'un changement de cadence (pour un badge UI).

#### `RealtimeState`

```ts
type RealtimeState = "disconnected" | "connecting" | "connected" | "reconnecting" | "error"
```

---

[← Toutes les références d'API](../../)
