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


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

> Générée depuis les déclarations de types publiées de `@nodefony/realtime` **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/realtime`

`import { … } from "@nodefony/realtime"` — 28 symboles.

### Classes (6)

#### `ChannelFrame`

```ts
class ChannelFrame
```

Frame d'UNE publication diffusée à plusieurs abonnés, encodée **au plus une fois par codec** (ADR-0022 §2) : un canal suivi par des connexions texte et CBOR paie deux encodages, jamais un par connexion. L'encodage est paresseux — un codec qu'aucun abonné n'utilise ne coûte rien.

- `constructor(message: unknown)`
- `encodeFor(codec: IFrameCodec): RealtimeFrameData` — Rend la frame encodée pour un codec, en l'encodant à la première demande.
- `claimFailure(codec: IFrameCodec): boolean` — Réclame l'échec d'encodage de cette frame pour un codec : `true` au PREMIER abonné qui le demande, `false` ensuite.

#### `ContractRealtimeControllerBase`

```ts
abstract class ContractRealtimeControllerBase<C extends IRealtimeContract> extends RealtimeController<ContractServerEmit<C>, ContractServerActions<C>, ContractServerListen<C>>
```

Socle commun des deux formes de `ContractRealtimeController` : l'étiquette de contrat et les canaux annoncés. Les actions y gardent le défaut de la base (`{}`) — un contrat SANS `serverMethods` n'a rien à écrire.

- `readonly [contractType]?: C` — Étiquette de TYPE : relie la classe à son contrat pour que `@RealtimePolicy` le retrouve.
- `protected realtimeChannels(): EventNames<ContractServerEmit<C>>[]` — Canaux annoncés au handshake, contraints aux noms de `serverToClient`.

#### `ContractRealtimeControllerStrict`

```ts
abstract class ContractRealtimeControllerStrict<C extends IRealtimeContract> extends ContractRealtimeControllerBase<C>
```

Forme stricte de `ContractRealtimeController`, retenue quand le contrat déclare des `serverMethods` : `realtimeActions()` y devient ABSTRAITE et typée par le contrat — la seule construction qui fait d'une méthode OUBLIÉE une erreur de compilation (un décorateur ne voit jamais la classe entière).

- `protected abstract realtimeActions(): ContractRealtimeMethodHandlers<C>` — Les méthodes du contrat servies par ce contrôleur — toutes, et par cette table SEULE : une action servie ici ne se décore pas en plus de `@RealtimeAction` (handler fabriqué puis écrasé à chaque connex …

#### `RealtimeController`

```ts
abstract class RealtimeController<Emit extends EventsMap = DefaultEventsMap, Actions extends ActionsMap = DefaultActionsMap, Listen extends EventsMap = DefaultEventsMap> extends Controller implements IRealtimeController
```

RealtimeController — base d'un endpoint WebSocket temps réel SERVEUR (JSON-RPC 2.0).

- `static scope: ControllerScope` — Une instance PAR CONNEXION, par construction — le défaut `singleton` des contrôleurs ne s'applique pas ici.
- `static assertScope(): void` — Refuse qu'une sous-classe se déclare singleton — au démarrage (`Router.setController`), et au constructeur pour qui construit par `new` hors du routeur (harnais de test).
- `constructor(name: string, context: ContextType)`
- `createRealtimeChannel(_channel: string, _publish: RealtimePublish): () => void | null` — Crée le provider d'un canal (listener/ticker → `publish`) et renvoie son `dispose`.
- `protected realtimeActions(): Record<string, RealtimeActionHandler>` — Actions RPC exposées (requête→réponse).
- `protected realtimeChannels(): string[]` — Canaux annoncés au handshake.
- `protected realtimeBroadcastChannels(): string[]` — Préfixes de canaux **broadcast** (cross-process) de cet endpoint.
- `protected realtimeInbound(): RealtimeInboundHandlers<Listen, Emit>` — Canaux FULL-DUPLEX acceptant une entrée client (`method` = nom du canal).
- `protected realtimeApiRequest(): boolean` — Opt-in du **pont API** (une action, deux transports) : `true` → la connexion expose la méthode RPC `api.request {path}` qui re-route le path porté par le message vers l'action controller correspondant …
- `protected handleRealtime(message: string | Uint8Array | null): void` — Point d'entrée à appeler depuis la route WS du contrôleur.
- `protected onRealtimeBinary?(data: Uint8Array): void` — Lit les trames BINAIRES de cette connexion — le point d'extension d'un protocole binaire écrit par l'application, à côté du JSON-RPC ; pendant serveur de `NodefonySocket.onBinary`.
- `protected requestClient<K extends ActionNames<Actions>>(method: K, params?: ActionParams<Actions, K>, timeoutMs?: number): Promise<ActionResult<Actions, K>>` — **L1 — duplex serveur→client.** Émet une REQUÊTE vers le client de CETTE connexion (sur une action qu'il a exposée via `client.register(...)`) et attend sa réponse.
- `protected notifyClient<K extends EventNames<Emit>>(method: K, params?: EventPayload<Emit, K>): void` — Notification CIBLÉE serveur→client (sans réponse) vers CETTE connexion, hors canal pub/sub — pendant *fire-and-forget* de `requestClient`.
- `protected sendBinaryToClient(data: Uint8Array): boolean` — Émet une trame BINAIRE vers CETTE connexion, sans la sérialiser — pendant sortant de `onRealtimeBinary`, et de `NodefonySocket.sendBinary` côté client.

#### `RealtimeHub`

```ts
class RealtimeHub
```

RealtimeHub — broker temps réel **PAR INSTANCE** (1 pod = 1 process = 1 hub local).

- `readonly admissionBudget: AdmissionBudget` — Budget des admissions de l'exemplaire (appels d'`allow` en vol, coupe-circuit, `allowTimedOutTotal`/`allowSaturatedTotal`) — partagé par les files de toutes les connexions.
- `subscribeClient(channel: string, sink: ChannelSink, factory: ChannelFactory, buildFrame?: ChannelFrameBuilder, member?: RealtimeConnection): boolean` — Abonnement demandé par une **connexion cliente** — même chose que `subscribe`, plus le plancher des canaux de plateforme.
- `subscribe(channel: string, sink: ChannelSink, factory: ChannelFactory, buildFrame?: ChannelFrameBuilder): boolean` — Abonne un consommateur qui **répond du canal** : il apporte la `factory`, donc la réponse à « ce canal existe-t-il, et qui le produit ?
- `listen(channel: string, sink: ChannelSink): void` — **Écoute passive** — un service du serveur reçoit ce qui passe sur un canal sans prétendre le produire.
- `isChannelOwned(channel: string): boolean` — Le canal a-t-il un propriétaire (une fabrique a fourni son provider) ?
- `unsubscribe(channel: string, sink: ChannelSink): void` — Désabonne une connexion d'un canal.
- `channelMembers(channel: string): IRealtimeConnection[]` — Les connexions abonnées à un canal par un client — **local à ce pod** : les membres servis par un autre exemplaire n'y figurent pas.
- `subscribeConnection(channel: string, connection: IRealtimeConnection): Promise<boolean>` — Abonne d'office une connexion à un canal — **local à ce pod** : seule une connexion acceptée par ce processus peut l'être.
- `evictConnection(channel: string, connection: IRealtimeConnection): boolean` — Retire une connexion d'un canal — **local à ce pod** ; elle reçoit `realtime:closed { reason: "evicted" }`.
- `closeChannel(channel: string): number` — Termine un canal pour tous ses membres, **sur tous les serveurs** : chacun reçoit `realtime:closed { reason: "ended" }`, et le producteur est libéré.
- `evictUser(channel: string, user: string): number` — Éjecte un compte d'un canal, **sur tous les serveurs** : chacune de ses connexions membres reçoit `realtime:closed { reason: "evicted" }`.
- `publish(channel: string, payload?: object): void` — Publie une charge sur un canal : **fan-out local** **+** propagation conditionnelle au `IBackplane` (autres workers/pods).
- `publishToUser(userId: string, payload?: object): void` — Livre une charge à UNE identité — tous ses onglets, tous les serveurs, et personne d'autre (ADR-0022 §6, D1).
- `broadcastPrefixes(): readonly string[]` — Préfixes déclarés diffusables entre serveurs, dans l'ordre de déclaration — lu par la ligne de démarrage.
- `publishLocal(channel: string, payload: unknown): void` — Fan-out d'une charge aux **seuls abonnés locaux** d'un canal (process courant).
- `markBroadcastChannel(prefix: string): void` — Déclare un **préfixe** de canal **broadcast** : ses publications traversent le `IBackplane` (cross-process).
- `setBackplane(backplane: IBackplane): IBackplane` — Branche le `IBackplane` cross-process (cluster IPC, Redis…) et câble son ingress (`#admitFromBackplane`) : un message reçu d'un autre pair est réinjecté en **fan-out local uniquement** (`publishLocal` …
- `get backplane(): IBackplane | null` — Backplane cross-process branché, ou `null` en mono-process (lecture/tests/sonde).
- `subscriberCount(channel: string): number` — Nombre d'abonnés locaux d'un canal (observabilité / tests).
- `registerConnection(conn: IRealtimeConnProbe): void` — Inscrit une connexion au registre de la sonde (au handshake).
- `unregisterConnection(conn: IRealtimeConnProbe): void` — Retire une connexion du registre de la sonde (au close) et verse ses cumuls à ceux des connexions fermées : les totaux de `probe` restent monotones.
- `registerRevocable(entry: IRevocableConnection): void` — Inscrit une connexion à identité RÉVOCABLE au registre de re-validation (F4, revue 0.6).
- `unregisterRevocable(entry: IRevocableConnection): void` — Retire une connexion du registre de révocation (au close).
- `revalidateRevocable(): Promise<void>` — Re-valide toutes les connexions révocables et ferme (`4001`) celles dont l'identité est morte : session détruite ou passée à un autre compte, jeton expiré ou révoqué.
- `refreshIdentity(identifier: string): number` — Ferme tout de suite les connexions qui ont figé cette identité — ses droits ont changé (`IDENTITY_CHANGED_EVENT`).
- `recordInbound(): void` — Compte une frame entrante full-duplex (canaux gated SIP/bridge).
- `probe(): IRealtimeProbe` — Snapshot d'auto-observabilité de la socket (per-instance).
- `get activeChannels(): string[]` — Canaux actifs (≥ 1 abonné).
- `useAuthenticator(matcher: IRealtimeAuthenticatorMatcher, authenticator: IRealtimeAuthenticator): void` — **Seam #2 (P13 → P6)** — enregistre un authenticator pour les handshakes WS dont l'URL matche `matcher`.
- `resolveAuthenticator(handshake: IRealtimeHandshake): IRealtimeAuthenticator | null` — Résout l'authenticator capturant ce handshake (1ʳᵉ matcher qui matche), ou `null` si aucun (le RealtimeController posera un token anonyme).
- `setOriginGuard(guard: OriginGuard | null): void` — **Seam #4 (P13 → P6)** — pose la politique Origin (RFC 6455 §10.2).
- `checkOrigin(origin: string): boolean` — Vérifie qu'une origin est autorisée (politique CSRF).
- `setMaxChannelsPerConnection(max: number | null): void` — F6a (revue 0.6) — plafond de canaux par connexion (anti-OOM).
- `get maxChannelsPerConnection(): number | null` — Plafond courant de canaux par connexion (`null` = illimité).
- `setSlowConsumerBytes(bytes: number): void` — F9 (revue 0.6) — pose le seuil de comptage des consommateurs lents (`probe()`).
- `get frameCodecs(): IFrameCodecSet` — Les codecs de frame du serveur (ADR-0022 §2) : le texte, et le codec binaire accordé aux clients qui l'offrent — `null` tant que la configuration n'en active aucun.
- `setFrameCodec(codec?: IFrameCodec): void` — Pose le codec binaire du serveur — 1× au boot par `RealtimeService.init()`, depuis la clé `codec` de la configuration.
- `get textFrameCodec(): IFrameCodec` — Le codec des connexions texte — celui qu'emprunte aussi le REST du plan d'administration, pour qu'une valeur lue par `GET` soit celle que la socket livre (#618 D9).
- `setAdmissionLimits(limits: IAdmissionLimits): void` — Pose les bornes des admissions (`authenticateTimeoutMs`, `allowTimeoutMs`, `maxPendingAllowsPerConnection`, `maxPendingAllowsTotal`) — 1× au boot par `RealtimeService.init()`.
- `setTokenForPeer(peer: JsonRpcPeer, token: IRealtimeToken): void` — Associe un token au peer (posé par `RealtimeController.onHandshake()` après succès `authenticator.authenticate()` ou fallback anonyme).
- `getTokenForPeer(peer: JsonRpcPeer): IRealtimeToken` — Renvoie le token associé au peer, ou `ANONYMOUS_REALTIME_TOKEN` si aucun (cas Zero Trust : la lecture ne renvoie JAMAIS `null` — slot #6 audit lookup garanti, voters P6 ne se posent jamais la question …
- `setFrameAuthorizer(authorizer: FrameAuthorizer | null, options?: { readonly silentProbe?: FrameAuthorizer | null; }): void` — **Seam #1 (P13 → P6)** — pose le verrou de frame (cf `FrameAuthorizer`).
- `hasFrameAuthorizer(): boolean` — Un verrou de frame est-il posé ?
- `onPlatformNotice(notify: (message: string, severity: "WARNING" | "INFO") => void): void` — Branche l'alerte du plancher système — tirée **une seule fois**, au premier canal de plateforme refusé faute de module de sécurité.
- `isClosedBySystemFloor(channel: string): boolean` — Ce canal serait-il fermé par le plancher système ?
- `hasUnenforcedChannelPolicies(): boolean` — F1 (revue 0.6) — des politiques de canal sont-elles DÉCLARÉES (`@RealtimeChannel` avec `roles`/`scopes`/`authenticated`) sans `frameAuthorizer` pour les faire respecter ?
- `registerChannelPolicy(name: string, policy: IChannelPolicy, admission?: IChannelAdmission): void` — **Seam #1b** — déclare la politique d'autorisation d'un canal/méthode (`@RealtimeChannel`/`@RealtimeInbound` avec opts).
- `static readonly MAX_PATTERN_WILDCARDS = 3` — Nombre maximum de `*` dans un motif.
- `resolveChannelPolicy(name: string): IChannelPolicy | null` — Politique déclarée pour ce canal/méthode, ou `null` si aucune.
- `resolveChannelAdmission(name: string): IChannelAdmissionRule | null` — Règle d'admission prête à appeler pour ce canal — `null` s'il ne déclare pas `allow`.
- `hasPolicyOwner(owner: object): boolean` — Les politiques de cette classe de contrôleur sont-elles déjà inscrites ?
- `addPolicyOwner(owner: object): void` — Marque les politiques de cette classe comme inscrites — APRÈS l'inscription réussie, jamais avant : une politique refusée doit l'être de nouveau à la poignée de main suivante, pas laisser le canal ouv …
- `hasExactChannelPolicy(name: string): boolean` — Une politique est-elle déclarée sous ce nom EXACT — motifs ignorés ?
- `hasChannelPolicies(): boolean` — Des politiques de canal sont-elles déclarées (au moins une) ?
- `noticeUnguardedDynamicChannel(channel: string): void` — Avertit — **une seule fois** — qu'un canal servi par une fabrique DYNAMIQUE n'est couvert par aucune politique déclarée, alors que d'autres canaux du module en portent une.
- `registerSystemChannel(channel: string, factory: ChannelFactory): void` — Enregistre la **factory d'un canal système** (plateforme) — un module bas niveau (ex.
- `setClientLogsLimits(limits: IClientLogsLimits | null): void` — Ouvre (ou referme) la réception des journaux du navigateur, avec ses bornes.
- `get clientLogsLimits(): IClientLogsLimits | null` — Bornes en vigueur, ou `null` si le canal montant est fermé.
- `runAuthorizer(frame: unknown, peer: JsonRpcPeer): boolean`
- `trackRetainedVerdicts(state: IRealtimeConnectionState): void` — Inscrit une connexion qui vient de retenir son premier « oui » du verrou.
- `untrackRetainedVerdicts(state: IRealtimeConnectionState): void` — Retire une connexion fermée du registre des verdicts retenus.
- `probeChannel(channel: string, peer: JsonRpcPeer): boolean` — Ce peer pourrait-il s'abonner à ce canal ?
- `get registeredAuthenticators(): ReadonlyArray<IRealtimeAuthenticator>` — Authenticators enregistrés (debug / tests).
- `clear(): void` — Dispose tous les providers et vide le hub (arrêt process / reset de test).

#### `ServerRealtimeSocket`

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

**L4 — façade serveur « la socket Nodefony ».** Un handle SERVEUR qui implémente le contrat ISOMORPHE `IRealtimeSocket` au-dessus du `RealtimeHub` : un service back code **comme une page front** (`publish` / `subscribe` / `on` / `channel`) — il tient UN handle, ignore le fan-out et le backplane.

- `constructor(hub?: import("./RealtimeHub").RealtimeHub)`
- `publish<K extends string>(channel: K, payload?: K extends EventNames<Emit> ? EventPayload<Emit, K> : object): void` — Émet sur un canal — fan-out aux abonnés via le hub (+ backplane si broadcast).
- `subscribe(channel: EventNames<Listen> | (string & {})): void` — S'abonne (ref-compté) à un canal pour le RECEVOIR.
- `unsubscribe(channel: EventNames<Listen> | (string & {})): void` — Désabonne (ref-compté) : coupe le sink du hub au DERNIER consommateur.
- `on<K extends string>(channel: K, handler: K extends EventNames<Listen> ? (payload: EventPayload<Listen, K>) => void : RealtimeHandler): () => void` — Branche un handler de réception sur un canal.
- `off<K extends string>(channel: K, handler: K extends EventNames<Listen> ? (payload: EventPayload<Listen, K>) => void : RealtimeHandler): void` — Retire un handler d'un canal — même frontière que `on`.
- `request<K extends string, T = unknown>(_method: K, _params?: ContractParams<Actions, K>, _timeoutMs?: number): Promise<ContractResult<Actions, K, T>>` — **Non supporté** : rejette toujours.
- `channel(name: string): IRealtimeChannel` — Vue par-canal (`IRealtimeChannel`) — fine liaison sur les primitives.
- `getStats(): IChannelStats[]` — Snapshot des compteurs par canal (refs internes — à LIRE).
- `getChannelStats(channel: string): IChannelStats` — Compteurs d'un canal précis ou `undefined`.
- `get subscribedChannels(): string[]` — Canaux actuellement abonnés (≥ 1 consommateur).

### Fonctions (6)

#### `buildOwnHealth`

```ts
function buildOwnHealth(): IRealtimeHealth
```

#### `buildRealtimeHealth`

```ts
function buildRealtimeHealth(): Promise<IRealtimeHealth | IRealtimeClusterHealth>
```

Construit la **santé de la socket** servie par l'endpoint/le canal `nodefony:socket` : la **vue POD agrégée** si la sonde cluster est branchée et a reçu un snapshot du master (Phase 4c, push), sinon la **vue per-instance** (mono-process, sonde désactivée, ou cold start). Lecture pure, jamais throw. Async pour matcher la signature des tickers broker.

#### `createRealtimeAdminApi`

```ts
function createRealtimeAdminApi(): IAdminApi
```

Construit le producteur `IAdminApi` de la socket (namespace `"realtime"`).

#### `createSyslogUplinkHandler`

```ts
function createSyslogUplinkHandler(opts: SyslogUplinkHandlerOptions): RealtimeInboundHandler
```

Fabrique le handler du canal montant des journaux.

#### `getRealtimeHub`

```ts
function getRealtimeHub(): RealtimeHub
function getRealtimeHub<C extends IRealtimeContract>(): IContractRealtimeHub<C>
```

Renvoie le hub realtime du process (singleton lazy) — forme LIBRE : tout nom de canal, toute charge objet. Renvoie le hub realtime du process lu à travers le contrat `C` : la diffusion d'un service, d'un job ou d'une boucle de jeu est vérifiée par le contrat partagé avec le navigateur. Même objet que la forme libre : 0 octet, 0 ns.

#### `serverSocket`

```ts
function serverSocket<Emit extends EventsMap = DefaultEventsMap, Listen extends EventsMap = DefaultEventsMap, Actions extends ActionsMap = DefaultActionsMap>(): ServerRealtimeSocket<Emit, Listen, Actions>
```

Crée un handle serveur (`ServerRealtimeSocket`) sur le hub courant.

### Constantes (7)

#### `ANONYMOUS_REALTIME_TOKEN`

```ts
const ANONYMOUS_REALTIME_TOKEN: IRealtimeToken
```

Token realtime ANONYME — fallback Zero Trust quand aucun matcher `IRealtimeAuthenticatorMatcher` ne capture le handshake.

#### `ANONYMOUS_SUBSCRIBER_IDENTITY`

```ts
const ANONYMOUS_SUBSCRIBER_IDENTITY: ISubscriberIdentity
```

Identité d'admission de l'ANONYME — gelée et partagée par toutes les connexions non authentifiées (0 allocation par connexion).

#### `ContractRealtimeController`

```ts
const ContractRealtimeController: ContractRealtimeControllerConstructor
```

L'instance d'un contrôleur de contrat : forme stricte si `C` déclare des `serverMethods`, socle sinon. Base d'un contrôleur qui IMPLÉMENTE un contrat temps réel — la porte du serveur. Le contrat s'écrit UNE fois, sur `extends` ; la direction du serveur en est dérivée (il émet `serverToClient`, écoute `clientToServer`, appelle `clientMethods`) et il DOIT servir chaque méthode de `serverMethods`.

#### `MAX_CLIENT_SEVERITY`

```ts
const MAX_CLIENT_SEVERITY = 3
```

Sévérité la plus grave qu'un client puisse obtenir (3 = ERROR). Au-dessus vivent CRITIC, ALERT et EMERGENCY — des niveaux d'exploitation qu'un onglet ne décide pas.

#### `RESERVED_SYSTEM_PREFIXES`

```ts
const RESERVED_SYSTEM_PREFIXES: readonly [ "nodefony:" ]
```

**Namespace de canaux RÉSERVÉ À LA PLATEFORME** — un seul préfixe, `nodefony:`.

#### `SLOW_CONSUMER_BYTES`

```ts
const SLOW_CONSUMER_BYTES: number
```

Seuil d'alerte slow-consumer (octets de `bufferedAmount`). Au-delà, la connexion est comptée comme « lente » par la sonde (PAS encore de drop/close — la sonde MESURE avant qu'on optimise : stringify unique → seuil de drop → coalescing). 1 MiB = `websocket.maxPayload` par défaut : une file qui dépasse une frame max pleine est déjà anormale pour des canaux d'ÉTAT (latest-wins).

#### `isReservedSystemChannel`

```ts
const isReservedSystemChannel: typeof isPlatformChannel
```

Le canal appartient-il au namespace réservé à la plateforme ?

### Interfaces (2)

#### `IContractRealtimeHub`

```ts
interface IContractRealtimeHub<C extends IRealtimeContract> extends Omit<RealtimeHub, "publish" | "publishToUser">
```

Le hub lu à travers le contrat `C` : mêmes méthodes que `RealtimeHub`, mais `publish` n'accepte que les canaux de `serverToClient`, chacun avec la charge qu'il déclare. C'est le MÊME objet que le hub libre — une vue de type, sans un octet ni une instruction de plus.

- `publishToUser(userId: string, payload: UserChannelPayload<ContractServerEmit<C>> & object): void` — Livre à UNE identité la charge que le contrat déclare pour le canal personnel (clé gabarit `` [k: `user:${string}`]: … `` de `serverToClient`) — cf `RealtimeHub.publishToUser`.
- `publish<K extends EventNames<ContractServerEmit<C>>>(channel: K, payload: EventPayload<ContractServerEmit<C>, K> & object): void` — Publie sur un canal déclaré par le contrat (fan-out local, puis backplane si le canal est broadcast) — cf `RealtimeHub.publish`.

#### `SyslogUplinkHandlerOptions`

```ts
interface SyslogUplinkHandlerOptions
```

- `syslog: Syslog` — Le journal du pod où réinjecter.
- `maxEntriesPerBatch?: number` — Entrées retenues par lot.
- `maxEntriesPerWindow?: number` — Entrées retenues par fenêtre et par connexion.
- `windowMs?: number` — Durée de la fenêtre de débit, en ms.
- `maxStringLength?: number` — Longueur maximale d'une chaîne acceptée.
- `maxRequestIdLength?: number` — Longueur maximale d'un `requestId` accepté.

### Types (7)

#### `ChannelFactory`

```ts
type ChannelFactory = (channel: string, publish: RealtimePublish) => () => void | null
```

Fabrique le provider PARTAGÉ d'un canal (listener/ticker qui pousse via `publish`). Appelée UNE fois, au 1ᵉʳ abonné. Renvoie son `dispose` (appelé au dernier désabonné) ou `null` si le canal est inconnu. Le provider doit capturer des deps **long-lived** (kernel/syslog/broker, valeurs simples) — JAMAIS la connexion qui a déclenché la création (elle peut fermer alors que le provider partagé survit).

#### `ChannelFrameBuilder`

```ts
type ChannelFrameBuilder = (payload: unknown) => unknown
```

Fabrique la frame protocolaire d'un canal (l'objet, pas ses octets), fournie par l'abonné : le hub ignore tout du protocole. Appelée **au plus une fois par publication**, jamais par abonné ; l'encodage, lui, se fait une fois par codec.

#### `ChannelSink`

```ts
type ChannelSink = (payload: unknown, frame?: ChannelFrame) => void
```

Sink d'un canal : pousse une charge vers UNE connexion abonnée (son `peer.notify`). 1 sink = 1 connexion. Le hub fan-out la charge à tous les sinks d'un canal.

#### `ClientSeverity`

```ts
type ClientSeverity = 3 | 4 | 5 | 6 | 7
```

Les seules sévérités qu'une entrée cliente peut porter, une fois plafonnée.

#### `ContractPolicyNames`

```ts
type ContractPolicyNames<C extends IRealtimeContract> = ContractActionNames<ContractServerMethods<C>> | EventNames<ContractServerEmit<C>> | EventNames<ContractClientEmit<C>>
```

Noms qu'un contrat déclare et qu'une politique peut garder : ses méthodes serveur et les canaux de ses deux directions. Un canal déclaré par gabarit (`user:${string}`) admet aussi son motif (`user:*`). Direction non déclarée : tout nom.

#### `ContractRealtimeMethodHandlers`

```ts
type ContractRealtimeMethodHandlers<C extends IRealtimeContract> = { [K in ContractActionNames<ContractServerMethods<C>>]: TypedRpcActionHandler<ContractServerMethods<C>, K>; }
```

Table COMPLÈTE des méthodes que le serveur doit au contrat : une entrée par nom de `serverMethods`, chacune recevant ses paramètres lus par `Jsonify` et rendant le résultat déclaré. Une méthode oubliée, un nom hors contrat ou une forme fausse ne compilent pas.

#### `RealtimeContractOf`

```ts
type RealtimeContractOf<T> = T extends abstract new (...args: never[]) => { readonly [contractType]?: infer C; } ? unknown extends C ? never : C extends IRealtimeContract ? C : never : never
```

Le contrat qu'une classe de contrôleur implémente, lu sur son étiquette de type ; `never` pour un contrôleur sans contrat.

---

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