refactor(domain): split Icon/WebSub/Counters out of FeedRepository

FeedRepository no longer owns favicons, WebSub subscriber lists or the
monitoring counters singleton. Each concern gets its own repository
(IconRepository, WebSubSubscriptionRepository, CountersRepository),
sharing the key schema via feed-keys. KV key strings are unchanged;
counters increment policy stays in utils/stats.ts.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
Julien HerrandClaude Opus 4.7 committed 2026-05-24 00:27:33 +02:00
1 parent b347f2f625
commit a31ff42f59
13 files changed
+204 -119

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
import { Env } from "../types";
import { feedKeys } from "./feed-keys";
/**
* KV access for cached per-domain favicons (`icon:<domain>`). Entries may be
* positive (base64 bytes) or negative (a sentinel marking a failed fetch), and
* always carry a TTL — the cache's sole expiry mechanism.
*/
export class IconRepository {
constructor(private readonly kv: KVNamespace) {}
static from(env: Env): IconRepository {
return new IconRepository(env.EMAIL_STORAGE);
}
getText(domain: string): Promise<string | null> {
return this.kv.get(feedKeys.icon(domain), "text");
}
async getJson<T>(domain: string): Promise<T | null> {
return (await this.kv.get(feedKeys.icon(domain), {
type: "json",
})) as T | null;
}
async put(domain: string, value: string, ttlSeconds: number): Promise<void> {
await this.kv.put(feedKeys.icon(domain), value, {
expirationTtl: ttlSeconds,
});
}
}