# `delivery-tracker` _(no submodules)_ ## Purpose `delivery-tracker` is the bounded LRU cache of `SmsDeliveryReport` records that `SmsService` consults for delivery status. Receipts may arrive via webhook ingest (`tracker.ingest(report)`) or be lazily fetched from the configured provider via `tracker.lookupOrFetch(messageId, provider)`. The cache is bounded so a long-running service does not retain every receipt indefinitely. When no provider is supplied and the cache misses, `lookupOrFetch` throws `SmsReceiptNotFoundError` (code `SMS.RECEIPT_NOT_FOUND`) so callers can distinguish a miss from a remote provider error. ## Features - LRU cache keyed by `messageId`, bounded by `maxEntries` (default 1024). - `ingest(report)` — record / refresh a receipt; oldest entry evicts on overflow. - `getStatus(messageId)` — synchronous cache read; refreshes LRU order on hit. - `lookupOrFetch(messageId, provider?)` — cache-first, falls back to `provider.getStatus`; result is cached on success. - `size()` and `clear()` for observation / reset. ## Usage: Basic ```ts import { DeliveryTracker } from "@suaveplan/sms/delivery-tracker"; const tracker = new DeliveryTracker(); tracker.ingest({ messageId: "m1", to: "+15551234567", status: "delivered", timestamp: new Date(), }); console.log(tracker.getStatus("m1")); ``` ## Usage: Advanced ```ts import { DeliveryTracker } from "@suaveplan/sms/delivery-tracker"; import { InMemorySmsProvider } from "@suaveplan/sms/in-memory-provider"; const tracker = new DeliveryTracker({ maxEntries: 4 }); const provider = new InMemorySmsProvider(); // Lazy fetch — first call hits the provider, second hits cache. const fromProvider = await tracker.lookupOrFetch("m1", provider); const fromCache = await tracker.lookupOrFetch("m1", provider); ``` ## API Reference - `class DeliveryTracker` - `constructor(options?: DeliveryTrackerOptions)` - `ingest(report: SmsDeliveryReport): void` - `getStatus(messageId: string): SmsDeliveryReport | undefined` - `lookupOrFetch(messageId: string, provider?: SmsProvider): Promise` - `size(): number` - `clear(): void` - `interface DeliveryTrackerOptions` - `maxEntries?: number` (default 1024, must be ≥ 1) ## Implementation Notes The implementation uses a plain `Map` and exploits JavaScript's insertion-ordered iteration to maintain LRU order: on each hit we `delete` then `set` the entry, pushing it to the back. On `ingest`, an existing entry is deleted before re-insertion to keep order canonical. Eviction reads the first key in the iterator (the oldest entry) and deletes it. `lookupOrFetch` catches no provider errors — they propagate to the caller so a network failure on receipt fetch isn't silently swallowed.