# @nwire/dead-letter

> Dead-letter sink contract — destination for messages whose handler exhausted retries.

## What it does

Defines `DeadLetterSink` (one method: `record(entry)`) and ships an in-memory default. The runtime calls `sink.record(entry)` once per failed dispatch after `max + 1` attempts have all thrown. Production wires plug in a persistent adapter (BullMQ's failed-jobs board, a Mongo collection, an SNS topic); the contract is identical.

## Install

```bash
pnpm add @nwire/dead-letter
```

## Quick start

```ts
import { InMemoryDeadLetterSink } from "@nwire/dead-letter";
import { createApp } from "@nwire/forge";

const dlq = new InMemoryDeadLetterSink();
const app = createApp("learnflow", { modules, deadLetter: dlq });

// In tests:
const entries = await dlq.list();
expect(entries.map((e) => e.actionName)).toContain("flakyAction");
```

## API surface

- `DeadLetterSink` — interface adapters implement.
- `InMemoryDeadLetterSink` — process-local default; useful in tests.
- `DeadLetterEntry` — record shape (actionName, input, envelope, attempts, lastError, enteredAt).
- `buildDeadLetterEntry(...)` — helper for adapters constructing entries.

## When to use

Any production deployment — silently dropping retries-exhausted jobs is a production bug.

## Within nwire-app

For developers using this package as part of the Nwire stack — register it via `app.use(...)` or it auto-wires when you compose `createApp({ modules })`.

```ts
import { createApp } from "@nwire/forge";

const app = createApp({
  /* ...config... */
});
// Adapter/plugin wiring happens here when applicable.
```
