Revert "fix: harden automatic mobile boards"

This reverts commit d0b9348b86.
This commit is contained in:
ajnart committed 2026-07-29 20:06:32 +02:00
1 parent 92a2be2b65
commit dba9a250ff
37 files changed
+137 -637

No files matched your search

@@ -4,17 +4,6 @@ import { describe, expect, test, vi } from "vitest";
import { createRequestHandler } from "./request-handler";
const createDeferred = <T>() => {
let resolve!: (value: T) => void;
let reject!: (reason: unknown) => void;
const promise = new Promise<T>((resolvePromise, rejectPromise) => {
resolve = resolvePromise;
reject = rejectPromise;
});
return { promise, reject, resolve };
};
describe("createRequestHandler", () => {
test("keeps the standard result contract free of cache provenance", async () => {
const requestHandler = createRequestHandler({
@@ -58,47 +47,4 @@ describe("createRequestHandler", () => {
"offline",
);
});
test("does not let a pre-invalidation request overwrite a newer cached result", async () => {
const first = createDeferred<string>();
const second = createDeferred<string>();
const requestAsync = vi.fn().mockReturnValueOnce(first.promise).mockReturnValueOnce(second.promise);
const requestHandler = createRequestHandler({ requestAsync });
const handler = requestHandler.handler({ integrationId: "first" });
const oldRequest = handler.getDataWithProvenanceAsync();
requestHandler.invalidateCache();
const newRequest = handler.getDataWithProvenanceAsync();
second.resolve("new");
await expect(newRequest).resolves.toMatchObject({ data: "new" });
first.resolve("old");
await expect(oldRequest).resolves.toMatchObject({ data: "old" });
await expect(handler.getDataWithProvenanceAsync()).resolves.toMatchObject({ data: "new" });
expect(requestAsync).toHaveBeenCalledTimes(2);
});
test("does not let a pre-invalidation request clear a newer inflight request", async () => {
const first = createDeferred<string>();
const second = createDeferred<string>();
const requestAsync = vi.fn().mockReturnValueOnce(first.promise).mockReturnValueOnce(second.promise);
const requestHandler = createRequestHandler({ requestAsync });
const handler = requestHandler.handler({ integrationId: "first" });
const oldRequest = handler.getDataWithProvenanceAsync();
requestHandler.invalidateCache();
const newRequest = handler.getDataWithProvenanceAsync();
first.resolve("old");
await expect(oldRequest).resolves.toMatchObject({ data: "old" });
const sharedNewRequest = handler.getDataWithProvenanceAsync();
expect(requestAsync).toHaveBeenCalledTimes(2);
second.resolve("new");
await expect(Promise.all([newRequest, sharedNewRequest])).resolves.toEqual([
expect.objectContaining({ data: "new" }),
expect.objectContaining({ data: "new" }),
]);
});
});
@@ -22,11 +22,9 @@ export const createRequestHandler = <TData, TInput extends Record<string, unknow
) => {
const cache = new Map<string, CacheEntry<TData>>();
const inflight = new Map<string, Promise<RequestResult<TData>>>();
let cacheGeneration = 0;
return {
invalidateCache: () => {
cacheGeneration += 1;
cache.clear();
inflight.clear();
},
@@ -43,29 +41,21 @@ export const createRequestHandler = <TData, TInput extends Record<string, unknow
const existing = inflight.get(key);
if (existing) return existing;
const requestGeneration = cacheGeneration;
let promise: Promise<RequestResult<TData>>;
const isCurrentRequest = () => requestGeneration === cacheGeneration && inflight.get(key) === promise;
promise = options
const promise = options
.requestAsync(input)
.then((data) => {
const entry: CacheEntry<TData> = { data, timestamp: new Date(), expiresAt: Date.now() + ttl };
if (isCurrentRequest()) {
if (cache.size >= MAX_CACHE_SIZE) evictExpired(cache);
if (cache.size >= MAX_CACHE_SIZE) {
const oldest = cache.keys().next().value;
if (oldest) cache.delete(oldest);
}
cache.set(key, entry);
inflight.delete(key);
if (cache.size >= MAX_CACHE_SIZE) evictExpired(cache);
if (cache.size >= MAX_CACHE_SIZE) {
const oldest = cache.keys().next().value;
if (oldest) cache.delete(oldest);
}
const entry: CacheEntry<TData> = { data, timestamp: new Date(), expiresAt: Date.now() + ttl };
cache.set(key, entry);
inflight.delete(key);
return { data: entry.data, timestamp: entry.timestamp, isStale: false };
})
.catch((err) => {
if (isCurrentRequest()) inflight.delete(key);
inflight.delete(key);
if (options.fallbackToStaleOnError && cached) {
return { data: cached.data, timestamp: cached.timestamp, isStale: true };
}