first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
# `deliverPresenceWebhook`
## Purpose
Best-effort, signed delivery of a single presence event to a configured webhook receiver. The gateway calls this function on every presence transition (`join` / `leave` / `update`) when a `presenceWebhook` is configured on the daemon. Retry, exponential backoff, and circuit-breaking are owned by `@suaveplan/webhook-client.deliver`, which internally threads `@suaveplan/retry` — the gateway never has to reinvent that policy.
## Features
- Per-event opt-in filter: `config.events` constrains which kinds fan out. Default (`undefined`) fans out every kind.
- HMAC-SHA-256 signed payloads when `config.secret` is set, matching the proposal's "signed delivery payload" requirement.
- Errors are swallowed and routed to an optional `onError(err)` hook so presence — which is inherently lossy — never crashes the daemon.
- Deterministic delivery id: `presence-<clientId>-<at>` makes the receiver's idempotency story easy.
## Usage: Basic Example
```ts
import { deliverPresenceWebhook } from "@suaveplan/websocket-gateway";
await deliverPresenceWebhook(
{ url: "https://example.com/webhooks/presence", secret: "shared-secret" },
{ kind: "presence:join", clientId: "alice", roomId: "ops", status: "online", at: Date.now() }
);
```
## Usage: Advanced Example
```ts
import { deliverPresenceWebhook } from "@suaveplan/websocket-gateway";
import { logger } from "@suaveplan/logger";
await deliverPresenceWebhook(
{
url: "https://hooks.example.com/presence",
secret: process.env.PRESENCE_HMAC,
events: ["presence:join", "presence:leave"], // skip 'update' chatter
},
{
kind: "presence:update",
clientId: "alice",
roomId: undefined,
status: "away",
at: Date.now(),
},
(err) => logger.warn("presence webhook delivery failed", { err })
);
```
## API Reference
- `deliverPresenceWebhook(config, event, onError?): Promise<void>`
- `PresenceWebhookEvent` — `{ kind, clientId, roomId, status, at }` value object.
## Implementation Notes
The function never throws — `webhook-client.deliver` already classifies retryable vs terminal status codes and consumes the retry budget internally. Surfacing failures upstream would force the gateway to invent a recovery policy, but presence is best-effort by design (receivers reconcile via the next heartbeat / connection event). Delivery is signed with the same algorithm `webhook-client` defaults to (`sha256`); future stronger algorithms (e.g. ed25519) become a `config.algorithm` switch the moment `webhook-client` exposes one.