fix: address CodeRabbit review — stream tee, cache guard, base64, layout fallback

- BoardLayoutFallback: use HomarrLogoWithTitle (no board context required)
- integration-data-cache: guard cache.set with placeholder identity to
  prevent stale write-back after invalidation + test
- next-cache-handler: memoize the promise (not resolved handler) to
  prevent concurrent Redis connections
- redis-handler: tee ReadableStream before consuming in set(), hand fresh
  branch to each get() caller
- redis-handler: base64-encode body instead of number[] (3-4x smaller)
This commit is contained in:
Thomas Camlong committed 2026-08-07 22:09:11 +02:00
1 parent 00855d4825
commit 4270f2f2f1
5 files changed
+58 -25

No files matched your search

@@ -83,6 +83,27 @@ describe("getCachedIntegrationData", () => {
expect(fetcher).toHaveBeenCalledTimes(1);
});
test("invalidation during pending fetch prevents stale write-back", async () => {
let resolveOuter!: (v: { value: string }) => void;
const fetcher = vi.fn(
() =>
new Promise<{ value: string }>((resolve) => {
resolveOuter = resolve;
}),
);
const p1 = getCachedIntegrationData("integration-a", "widget:race", fetcher);
invalidateIntegrationDataCache("integration-a");
resolveOuter({ value: "stale" });
await p1;
const freshFetcher = vi.fn(async () => ({ value: "fresh" }));
const result = await getCachedIntegrationData("integration-a", "widget:race", freshFetcher);
expect(result).toEqual({ value: "fresh" });
expect(freshFetcher).toHaveBeenCalledTimes(1);
});
test("invalidates all cache entries for an integration", async () => {
const fetcherOne = vi.fn(async () => ({ value: "one" }));
const fetcherTwo = vi.fn(async () => ({ value: "two" }));
+4 -2
View File
@@ -56,8 +56,10 @@ export const getCachedIntegrationData = async <T>(
const pending = fetcher()
.then((data) => {
cache.set(key, { data, timestamp: Date.now() });
evictOldestEntry();
if (cache.get(key) === placeholder) {
cache.set(key, { data, timestamp: Date.now() });
evictOldestEntry();
}
return data;
})
.catch((error) => {