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,52 @@
# `memory.ts` — default in-memory `DeadLetterSink`
## Purpose
Provides the default `DeadLetterSink` implementation shipped with the plugin: an unbounded `Array<DeadLetterEntry>` backed sink suitable for tests and development environments. The list is most-recent-first via `unshift`, so a caller invoking `list({ limit: 10 })` always sees the ten most-recent exhausted deliveries. Production deployments typically configure a sibling sink (S3, Postgres, Mailpit) so dead letters survive process restart; this implementation exists so the plugin can boot with zero configuration and so tests can assert exhaustion behavior without standing up storage.
## Features
- `record` is a single `unshift` — O(1) on every write.
- `list` walks the array applying the optional `endpointId` filter and `limit` cap; returns a frozen-by-array slice.
- No bounded capacity — operators relying on the in-memory sink in long-running services should rotate the plugin or wire a durable sibling.
## Usage: Basic
```ts
import { MemoryDeadLetterSink } from "@suaveplan/api-plugin-webhook/dead-letter/memory";
const sink = new MemoryDeadLetterSink();
const failed = await sink.list();
```
## Usage: Advanced
```ts
import { MemoryDeadLetterSink } from "@suaveplan/api-plugin-webhook/dead-letter/memory";
const sink = new MemoryDeadLetterSink();
await sink.record({
id: "dl-1",
endpointId: "ep-1",
tenantId: null,
event: "order.created",
payload: { id: "w-1", event: "order.created", data: {}, timestamp: "..." },
attempts: [],
firstAttemptAt: "2026-05-18T00:00:00.000Z",
finalAttemptAt: "2026-05-18T00:00:00.000Z",
reason: "5x HTTP 500",
});
const onlyForEp1 = await sink.list({ endpointId: "ep-1", limit: 5 });
console.log(onlyForEp1.length); // 1
```
## API Reference
- `new MemoryDeadLetterSink()` — no constructor arguments.
- `record(entry)` — pushes the entry to the front of the internal array.
- `list(filter?)` — applies the optional `endpointId` and `limit` filter and returns a snapshot. Most-recent first.
## Implementation Notes
Because the sink is an unbounded array in process memory, it must NOT be used as the durable record in production systems. The plugin docs flag this — operators wire a durable sibling sink or a composite sink that records to both memory (for fast inspection) and durable storage. The implementation chose `unshift` over `push` so consumers do not need to compute `reverse()` for the "most-recent first" view that operators want; the small cost (O(n) per insert) is acceptable for the in-memory implementation's intended use case.