---
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.5** : 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"` — 34 symboles.

### Classes (2)

#### `JsonRpcPeer`

```ts
class JsonRpcPeer<Emit extends EventsMap = DefaultEventsMap, Listen extends EventsMap = DefaultEventsMap, Actions extends ActionsMap = DefaultActionsMap> implements IRealtimePeer<Emit, Actions>
```

- `constructor(opts: JsonRpcPeerOptions<Emit, Listen, Actions>)`
- `register<K extends ActionNames<Actions>>(method: K, handler: TypedRpcActionHandler<Actions, K>): void` — Expose une action (requête entrante `method`+`id` → `result`).
- `unregister(method: ActionNames<Actions>): void` — Retire une action.
- `get methods(): string[]` — Liste des actions exposées (pour annoncer au handshake, découverte côté pair).
- `request<K extends ActionNames<Actions>>(method: K, params?: ActionParams<Actions, K>, timeoutMs?: number): Promise<ActionResult<Actions, K>>` — Requête SORTANTE — `Promise` résolue avec le `result` (rejette sur `error`/timeout).
- `requestAs<A extends ActionsMap, K extends ActionNames<A>>(method: K, params?: ActionParams<A, K>, timeoutMs?: number): Promise<ActionResult<A, K>>` — Requête SORTANTE typée par un contrat que l'APPELANT déclare — pour qui tient ce pair sous son contrat effacé et connaît celui de son interlocuteur.
- `requestTraced<K extends ActionNames<Actions>>(method: K, params?: ActionParams<Actions, K>, timeoutMs?: number): Promise<RpcTracedResult<ActionResult<Actions, K>>>` — Requête SORTANTE **tracée** — rend `{ result, meta }` au lieu du `result` nu.
- `static buildNotification(method: string, params?: unknown): JsonRpcNotification` — Frame d'une notification sortante — **source unique** de sa forme.
- `notify<K extends EventNames<Emit>>(method: K, params?: EventPayload<Emit, K>): boolean` — Notification SORTANTE (pas de réponse attendue).
- `receive(msg: unknown): JsonRpcFrameKind` — Ingestion d'une frame ENTRANTE déjà parsée → classe (request/notification/ response) et route.
- `dispose(reason?: string): void` — Annule tous les pending (fermeture du transport).

#### `RpcError`

```ts
class RpcError extends Error
```

Erreur RPC **applicative** — l'exception VOLONTAIRE au principe « throw → `-32603` générique » : un handler qui rejette avec une `RpcError` choisit explicitement d'exposer `code`/`message`/`data` au pair (404 d'un path invoqué, 403 d'un voter…). Tout autre throw reste opaque (Zero Trust).

- `readonly name = "RpcError"`
- `readonly data?: unknown`
- `constructor(message: string, code?: number, data?: unknown)`

### Fonctions (4)

#### `isPlatformChannel`

```ts
function isPlatformChannel(name: string): boolean
```

Le nom désigne-t-il une surface de la plateforme (canal OU méthode) ?

#### `isRateChannel`

```ts
function isRateChannel(channel: string, base: string): boolean
```

Vrai si `channel` est le canal de base nu OU une de ses variantes cadencées `base:<ms>`.

#### `parseRate`

```ts
function parseRate(channel: string, base: string, bounds: RateBounds): number
```

Résout la cadence (ms) d'un canal cadencé connu, côté serveur. Le serveur connaît la `base` qu'il vient de matcher ; ce helper en extrait le suffixe `:<ms>`, **borne** dans `bounds` et retombe sur `bounds.default` pour le canal de base nu ou un suffixe invalide.

#### `rateChannel`

```ts
function rateChannel(base: string, intervalMs?: number, defaultMs?: number): string
```

Construit le nom d'un canal cadencé à partir de sa base et de la cadence demandée.

### Constantes (6)

#### `NODEFONY_CHANNEL_NAMESPACE`

```ts
const NODEFONY_CHANNEL_NAMESPACE = "nodefony:"
```

Marque des surfaces de plateforme sur la socket. Un canal qui commence par ce préfixe décrit le serveur, jamais le métier de l'application.

#### `PLATFORM_CHANNELS`

```ts
const PLATFORM_CHANNELS: { readonly syslog: "nodefony:syslog"; readonly audit: "nodefony:audit"; readonly dashboard: "nodefony:dashboard"; readonly supervision: "nodefony:supervision"; readonly debugbar: "nodefony:debugbar"; readonly socket: "nodefony:socket"; readonly ormHealth: "nodefony:orm:health"; readonly ormFlow: "nodefony:orm:flow"; readonly ormRich: "nodefony:orm:rich"; readonly scaffoldJ …
```

Canaux de **diffusion** de la plateforme (le serveur pousse, les écrans regardent).

#### `PLATFORM_EVENTS`

```ts
const PLATFORM_EVENTS: { readonly hmr: "nodefony:hmr"; readonly debugbarSelect: "nodefony:debugbar:select"; }
```

Événements **DOM** de la plateforme (`window`), dans le même espace de nommage.

#### `PLATFORM_INBOUND`

```ts
const PLATFORM_INBOUND: { readonly syslogUplink: "nodefony:syslog:uplink"; }
```

Canaux **MONTANTS** de la plateforme (le navigateur pousse, le pod reçoit).

#### `PLATFORM_METHODS`

```ts
const PLATFORM_METHODS: { readonly ping: "nodefony:kernel:ping"; readonly gc: "nodefony:kernel:gc"; readonly scaffoldPreview: "nodefony:scaffold:preview"; readonly scaffoldRun: "nodefony:scaffold:run"; readonly scaffoldCancel: "nodefony:scaffold:cancel"; }
```

Méthodes **RPC** de la plateforme (le client demande, le serveur répond).

#### `TransportState`

```ts
const TransportState: { readonly CONNECTING: 0; readonly OPEN: 1; readonly CLOSING: 2; readonly CLOSED: 3; }
```

États d'un transport — alignés sur les constantes `WebSocket`.

### Interfaces (11)

#### `IChannelStats`

```ts
interface IChannelStats
```

Compteurs d'un canal — **génériques**, calculés au point d'arrivée des frames donc fiables et réutilisables par toute app. (`NodefonySocket.MessageStats` en est l'alias.)

- `method: string` — Méthode JSON-RPC == nom du canal pub/sub.
- `msgCount: number` — Total de notifications reçues sur ce canal.
- `lastMessage: number | null` — Timestamp (ms) de la dernière notification, `null` si aucune.
- `rate: number` — Débit instantané (msg/s), échantillonné 1×/s.
- `series: number[]` — Historique du débit (VU-mètre) — fenêtre glissante.

#### `IRealtimeChannel`

```ts
interface IRealtimeChannel
```

Handle d'UN canal — vue par-canal d'un sous-flux duplex multiplexé sur la `IRealtimeSocket`. Forme naturelle des canaux à état (un appel SIP, une connexion bridgée) : il porte son nom, sa nature et son cycle de vie. C'est le **point d'accroche** des couches à venir (codec de protocole, cadence AIMD, politique `drop|coalesce|batch`) — elles enrichiront ce handle SANS retoucher la socket.

- `readonly name: string` — Nom du canal (clé de multiplexage == method JSON-RPC des notifications).
- `readonly kind?: string` — Nature du backing serveur (`pubsub` | `protocol` | `bridge` | `proxy` | …), annoncée par le serveur.
- `on(handler: RealtimeHandler): () => void` — Branche un handler de réception sur ce canal.
- `send(payload?: unknown): void` — Émet sur ce canal (duplex, one-way).
- `open(): void` — Ouvre le flux : `subscribe` ref-compté (demande au pair de pousser).
- `close(): void` — Ferme : `unsubscribe` ref-compté + retire les handlers branchés via ce handle.

#### `IRealtimeDenied`

```ts
interface IRealtimeDenied
```

Payload de la notification système `realtime:denied` — poussée par le serveur quand une frame `subscribe`/inbound est REFUSÉE par le verrou d'autorisation (P6). Rend le refus OBSERVABLE côté client (une notification, contrairement à une requête, serait sinon droppée en silence → le client resterait aveugle).

- `channel: string` — Canal (ou méthode inbound) refusé(e).
- `reason: RealtimeDeniedReason` — Motif générique (cf `RealtimeDeniedReason`) — jamais le détail de la policy.
- `detail?: string` — Ce qui s'est passé, en clair — **hors production UNIQUEMENT**.

#### `IRealtimePeer`

```ts
interface IRealtimePeer<Emit extends EventsMap = DefaultEventsMap, Actions extends ActionsMap = DefaultActionsMap>
```

- `request<K extends ActionNames<Actions>>(method: K, params?: ActionParams<Actions, K>, timeoutMs?: number): Promise<ActionResult<Actions, K>>` — Requête sortante → `Promise` du `result` (rejette sur `error`/timeout).
- `notify<K extends EventNames<Emit>>(method: K, params?: EventPayload<Emit, K>): void` — Notification sortante (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 → `result`).
- `unregister(method: ActionNames<Actions>): void` — Retire une action.
- `receive(frame: unknown): JsonRpcFrameKind` — Ingestion d'une frame ENTRANTE (déjà parsée) → classe + route.
- `readonly methods: string[]` — Actions exposées (découverte).
- `dispose(reason?: string): void` — Annule les requêtes en attente (fermeture transport).

#### `IRealtimeSocket`

```ts
interface IRealtimeSocket<Emit extends EventsMap = DefaultEventsMap, Listen extends EventsMap = DefaultEventsMap>
```

Contrat de « la socket Nodefony » — voir le bloc de tête du fichier. Implémenté par `NodefonySocket` (front) et, à terme, par une façade serveur au-dessus du hub.

- `subscribe(channel: EventNames<Listen> | (string & {})): void` — S'abonne à un canal (ref-compté) : émet la demande au pair UNIQUEMENT au 1ᵉʳ consommateur ; ré-émise automatiquement à chaque (re)connexion.
- `unsubscribe(channel: EventNames<Listen> | (string & {})): void` — Désabonne un consommateur (ref-compté) : coupe le flux réseau au DERNIER.
- `on<K extends string>(channel: K, handler: K extends EventNames<Listen> ? (payload: EventPayload<Listen, K>) => void : RealtimeHandler): () => void` — Branche un handler sur un canal (réception).
- `off<K extends string>(channel: K, handler: K extends EventNames<Listen> ? (payload: EventPayload<Listen, K>) => void : RealtimeHandler): void` — Retire un handler d'un canal.
- `publish<K extends string>(channel: K, payload?: K extends EventNames<Emit> ? EventPayload<Emit, K> : unknown): void` — Émet sur un canal (one-way, pas de réponse).
- `channel(name: string): IRealtimeChannel` — Vue par-canal — voir `IRealtimeChannel`.
- `getStats(): IChannelStats[]` — Snapshot des compteurs par canal (refs internes — à LIRE, pas à muter).
- `getChannelStats(channel: string): IChannelStats` — Compteurs d'un canal précis (== method JSON-RPC) ou `undefined`.
- `readonly subscribedChannels: string[]` — Canaux actuellement abonnés (≥ 1 consommateur).

#### `IRealtimeSubscribed`

```ts
interface IRealtimeSubscribed
```

Payload de la notification système `realtime:subscribed` — poussée par le serveur quand un `subscribe` est ACCEPTÉ, y compris pour un canal que la connexion suivait déjà (sans quoi un `subscribe` réémis attendrait un acquittement qui ne vient jamais).

- `channel: string` — Canal dont l'abonnement est désormais effectif sur cette connexion.

#### `IRealtimeTransport`

```ts
interface IRealtimeTransport
```

- `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`).
- `readonly readyState: number` — État courant (0..3, cf `TransportState`).
- `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).

#### `IRealtimeWelcome`

```ts
interface IRealtimeWelcome
```

Payload de la notification système `realtime:welcome` — **1ʳᵉ frame** poussée par le serveur juste après le handshake. Annonce le protocole, les canaux/actions **découvrables** de l'endpoint et l'`RealtimeIdentity` résolue de la connexion. Cold path (1×/connexion).

- `ts: number` — Timestamp serveur (ms epoch).
- `protocol: string` — Étiquette de protocole (`"jsonrpc-2.0"`).
- `channels: string[]` — Canaux pub/sub annoncés par l'endpoint (découverte).
- `methods: string[]` — Actions RPC exposées par l'endpoint (découverte).
- `identity: RealtimeIdentity` — Identité résolue de CETTE connexion (cf `RealtimeIdentity`).
- `env?: string` — Mode d'exécution du serveur — **posé UNIQUEMENT hors production**.
- `subscriptionAcks?: boolean` — Le serveur ACQUITTE chaque abonnement accepté (`realtime:subscribed`, cf `IRealtimeSubscribed`).

#### `JsonRpcPeerOptions`

```ts
interface JsonRpcPeerOptions<Emit extends EventsMap = DefaultEventsMap, Listen extends EventsMap = DefaultEventsMap, Actions extends ActionsMap = DefaultActionsMap>
```

- `send: (frame: unknown) => boolean | void` — Envoie une frame sérialisable sur le transport (le peer ignore le transport).
- `onNotification?: RpcNotificationHandler<Listen>` — Notifications entrantes (`method` sans `id`) : pub/sub côté client, subscribe/unsubscribe côté serveur.
- `onError?: (context: string, err: unknown) => void` — Erreur interne d'un handler — détail JAMAIS renvoyé au pair (loggé ici).
- `beforeDispatch?: (frame: unknown, peer: IRealtimePeer<Emit, Actions>) => boolean` — **Seam sécurité 1/5 (P13 → P6)** — gate `beforeDispatch` appelé AVANT le dispatch d'une frame entrante (request ET notification — pas les responses, passives).
- `onFrameAudit?: (reason: FrameAuditReason, frame: unknown, peer: IRealtimePeer<Emit, Actions>) => void` — **Seam audit 5/5 (P13 → P6.14)** — fire-and-forget sur évènements protocolaires notables (cf `FrameAuditReason`).

#### `RateBounds`

```ts
interface RateBounds
```

Bornes de cadence d'un canal cadencé (toutes en millisecondes).

- `readonly default: number` — Cadence par défaut — celle du canal de base nu (sans suffixe).
- `readonly min: number` — Borne basse (cadence minimale autorisée, anti-DoS event-loop).
- `readonly max: number` — Borne haute (cadence maximale autorisée).

#### `RealtimeIdentity`

```ts
interface RealtimeIdentity
```

Identité d'une connexion temps réel, telle que **résolue par le serveur au handshake** (token neutre `IRealtimeToken` côté back) et **annoncée au client** dans la notification système `realtime:welcome`.

- `type: string` — Type de token résolu (`"anonymous"`, `"session"`, `"jwt"`, …) — discriminator.
- `authenticated: boolean` — `false` pour un visiteur anonyme (Zero Trust : toujours présent, jamais `null`).
- `userIdentifier: string` — Identifiant logique du porteur (`"anonymous"`, `"user-42"`, …).
- `roles: string[]` — Rôles **plats** (RBAC, sans hiérarchie résolue) — `["ROLE_ANONYMOUS"]` si anonyme.
- `scopes: string[]` — Scopes accordés (clés API / OAuth) — `[]` en session BFF web.

### Types (11)

#### `JsonRpcErrorObject`

```ts
type JsonRpcErrorObject = IJsonRpcErrorObject
```

Erreur JSON-RPC 2.0 (objet `error` d'une réponse).

#### `PlatformChannel`

```ts
type PlatformChannel = (typeof PLATFORM_CHANNELS)[keyof typeof PLATFORM_CHANNELS]
```

Nom d'un canal de plateforme (valeur de `PLATFORM_CHANNELS`).

#### `PlatformInboundChannel`

```ts
type PlatformInboundChannel = (typeof PLATFORM_INBOUND)[keyof typeof PLATFORM_INBOUND]
```

Nom d'un canal montant de plateforme (valeur de `PLATFORM_INBOUND`).

#### `PlatformMethod`

```ts
type PlatformMethod = (typeof PLATFORM_METHODS)[keyof typeof PLATFORM_METHODS]
```

Nom d'une méthode RPC de plateforme (valeur de `PLATFORM_METHODS`).

#### `RealtimeFrameData`

```ts
type RealtimeFrameData = string | Uint8Array<ArrayBuffer>
```

Une frame brute telle que le transport la reçoit : du texte, ou des octets.

#### `RealtimeHandler`

```ts
type RealtimeHandler = { handle(...args: unknown[]): void; }["handle"]
```

Handler d'un canal pub/sub — reçoit le `params` de la notification (ou `(method, params)` sur `"*"`).

#### `RealtimeOutboundData`

```ts
type RealtimeOutboundData = RealtimeFrameData
```

Ce qu'un transport accepte d'émettre : une frame texte déjà sérialisée, ou des octets tels quels — le même type qu'en réception (cf `RealtimeFrameData`).

#### `RealtimeTransportFactory`

```ts
type RealtimeTransportFactory = (url: string) => IRealtimeTransport
```

Fabrique d'un transport pour une URL — injectable (tests, transports alternatifs).

#### `RpcActionHandler`

```ts
type RpcActionHandler = (params: unknown) => unknown
```

Handler d'une action (requête→réponse). Sync ou async ; throw → `-32603`.

#### `RpcNotificationHandler`

```ts
type RpcNotificationHandler<Listen extends EventsMap = DefaultEventsMap> = <K extends EventNames<Listen>>(method: K, params: EventPayload<Listen, K>) => void
```

Handler des notifications entrantes (pas de réponse). Paramétrable par `Listen` (map des notifications REÇUES par ce peer). Défaut permissif → comportement pré-types-partagés inchangé.

#### `TransportStateValue`

```ts
type TransportStateValue = (typeof TransportState)[keyof typeof TransportState]
```

---

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