Sets up global cache and uses it to fetch sessions
This commit is contained in:
74
src/context/cache/CacheContext.tsx
vendored
Normal file
74
src/context/cache/CacheContext.tsx
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import { createContext, use, useContext, useMemo, useRef } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import { RecordCache } from "@/lib/recordCache";
|
||||
import { pb } from "@/lib/pocketbase";
|
||||
import { type DocumentId, type AnyDocument, CollectionIds } from "@/lib/types";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
/**
|
||||
* Context value for the record cache singleton.
|
||||
*/
|
||||
export type CacheContextValue = RecordCache;
|
||||
|
||||
const CacheContext = createContext<CacheContextValue | undefined>(undefined);
|
||||
|
||||
/**
|
||||
* Provider for the record cache context. Provides a singleton RecordCache instance to children.
|
||||
*/
|
||||
export function CacheProvider({ children }: { children: ReactNode }) {
|
||||
const cacheRef = useRef<RecordCache | undefined>(undefined);
|
||||
if (!cacheRef.current) {
|
||||
cacheRef.current = new RecordCache();
|
||||
}
|
||||
return (
|
||||
<CacheContext.Provider value={cacheRef.current}>
|
||||
{children}
|
||||
</CacheContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to access the record cache context. Throws if used outside of CacheProvider.
|
||||
*/
|
||||
export function useCache(): CacheContextValue {
|
||||
const ctx = useContext(CacheContext);
|
||||
if (!ctx) throw new Error("useCache must be used within a CacheProvider");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
export function useDocument(documentId: DocumentId): AnyDocument {
|
||||
const cache = useCache();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
async function fetchItems() {
|
||||
const cacheValue = cache.getDocument(documentId);
|
||||
|
||||
if (cacheValue) {
|
||||
console.info(`Serving ${documentId} from cache.`);
|
||||
return cacheValue;
|
||||
}
|
||||
|
||||
const { doc } = await queryClient.fetchQuery({
|
||||
queryKey: [CollectionIds.Documents, documentId],
|
||||
queryFn: async () => {
|
||||
const doc: AnyDocument = await pb
|
||||
.collection("documents")
|
||||
.getOne(documentId, {
|
||||
expand:
|
||||
"relationships_via_primary,relationships_via_primary.secondary",
|
||||
});
|
||||
|
||||
console.info(`Saving ${documentId} to cache.`);
|
||||
cache.set(doc);
|
||||
|
||||
return { doc };
|
||||
},
|
||||
});
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
const items = useMemo(fetchItems, [documentId, cache, queryClient]);
|
||||
|
||||
return use(items);
|
||||
}
|
||||
Reference in New Issue
Block a user