fix: address PR review — bugs, dead code, error handling
Critical fixes:
- Smart Home: invalidate entity state query after toggle mutation
- Beszel live mode: use 5s refetchInterval instead of global 30s
- Fix unit test assertions for 5-arg setQueryCacheAsync signature
- Fix serialize/deserialize mismatch: JSON.parse on read (matches persister's JSON.stringify)
- Remove render-time setActiveQueryCacheBoardId race (keep only useEffect)
Error handling:
- Log persistence errors instead of swallowing with catch(() => {})
- Log QueryCacheHydration failures with ErrorWithMetadata
- Beszel: log partial failures (system details, container stats)
Dead code removal:
- Remove dead queryKey from all 39 request handlers + lib files
- Delete unused Redis APIs: createCacheChannel, createChannelWithLatestAndEvents,
createChannelEventHistory, history-channel.ts
- Remove stale createCacheChannel mock from docker test
Cleanup:
- Seed system-resources chart from initial query data (no empty start)
- Remove redundant refetchOnWindowFocus/refetchOnReconnect from BoardProvider
This commit is contained in:
50 files changed
+31
-254
No files matched your search
@@ -3,17 +3,22 @@ import { createAsyncStoragePersister } from "@tanstack/query-async-storage-persi
|
||||
import { fetchApi } from "@homarr/api/client";
|
||||
import { getActiveQueryCacheBoardId, queryCacheStoragePrefix } from "@homarr/api/query-cache";
|
||||
|
||||
// ponytail: write-only persister — restore is SSR-only via QueryCacheHydration
|
||||
const queryCacheStorage = {
|
||||
getItem: (_key: string) => null as string | null,
|
||||
async setItem(_key: string, value: string) {
|
||||
const boardId = getActiveQueryCacheBoardId();
|
||||
if (!boardId) return;
|
||||
await fetchApi.queryCache.setItem.mutate({ boardId, value }).catch(() => {});
|
||||
await fetchApi.queryCache.setItem.mutate({ boardId, value }).catch((error) => {
|
||||
console.warn("[query-cache] persist failed", error);
|
||||
});
|
||||
},
|
||||
async removeItem(_key: string) {
|
||||
const boardId = getActiveQueryCacheBoardId();
|
||||
if (!boardId) return;
|
||||
await fetchApi.queryCache.removeItem.mutate({ boardId }).catch(() => {});
|
||||
await fetchApi.queryCache.removeItem.mutate({ boardId }).catch((error) => {
|
||||
console.warn("[query-cache] remove failed", error);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ import "~/styles/gridstack.scss";
|
||||
|
||||
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
|
||||
import type { PersistedClient } from "@tanstack/react-query-persist-client";
|
||||
import { parse } from "superjson";
|
||||
|
||||
import { getQueryClient } from "@homarr/api/server";
|
||||
import { IntegrationProvider } from "@homarr/auth/client";
|
||||
import { auth } from "@homarr/auth/next";
|
||||
@@ -123,11 +121,14 @@ async function QueryCacheHydration({ userId, boardId }: { userId: string; boardI
|
||||
const serialized = await getQueryCacheAsync(userId, boardId);
|
||||
if (!serialized) return null;
|
||||
|
||||
const persisted = parse<PersistedClient>(serialized);
|
||||
const persisted = JSON.parse(serialized) as PersistedClient;
|
||||
if (!persisted?.clientState?.queries?.length) return null;
|
||||
|
||||
return <HydrationBoundary state={persisted.clientState} />;
|
||||
} catch {
|
||||
} catch (error) {
|
||||
logger.warn(
|
||||
new ErrorWithMetadata("Failed to hydrate query cache", { userId, boardId }, { cause: error }),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user