2.8 KiB
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 bymaxEntries(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 toprovider.getStatus; result is cached on success.size()andclear()for observation / reset.
Usage: Basic
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
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 DeliveryTrackerconstructor(options?: DeliveryTrackerOptions)ingest(report: SmsDeliveryReport): voidgetStatus(messageId: string): SmsDeliveryReport | undefinedlookupOrFetch(messageId: string, provider?: SmsProvider): Promise<SmsDeliveryReport>size(): numberclear(): void
interface DeliveryTrackerOptionsmaxEntries?: 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.