Advertisement
Guest User

Untitled

a guest
Jul 28th, 2023
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. type Fetcher<T> = () => Promise<T>;
  2.  
  3. type QueryResult<T> = { data: T };
  4.  
  5. interface Query<T> {
  6.   data: T;
  7.   new (key: string, fun: Fetcher<T>): Query<T>;
  8.   invalidate(): void;
  9.   fetch(): Promise<void>;
  10. }
  11.  
  12. interface QueryClient<T> {
  13.   new (cache: QueryCache): QueryClient<T>;
  14.   fetch(key: string, fun: Fetcher<T>): Promise<QueryResult<T>>;
  15.   invalidateQuery(key: string): void;
  16.   createResult(query: Query<T>): QueryResult<T>;
  17. }
  18.  
  19. interface QueryCache {
  20.   set(key: string, value: any): void;
  21.   createQuery(key: string, fun: Fetcher<any>): Query<any>;
  22.   findQuery(key: string): Query<any> | null;
  23. }
  24.  
  25. type ZalupaData = { data: number };
  26.  
  27. class Api {
  28.   async fetchZalupa(id: number): Promise<ZalupaData> {
  29.     await new Promise((resolve) => setTimeout(resolve, 1000));
  30.     return { data: 10 };
  31.   }
  32. }
  33.  
  34. class Zalupa {
  35.   data: ZalupaData | null = null;
  36.  
  37.   constructor(
  38.     private api: Api,
  39.     private client: QueryClient<ZalupaData | null>
  40.   ) {}
  41.  
  42.   async fetchZalupa(id: number) {
  43.     let result;
  44.     try {
  45.       const response = await this.api.fetchZalupa(id);
  46.       result = response;
  47.     } catch (e) {
  48.       console.log(e);
  49.     }
  50.     return result || null;
  51.   }
  52.  
  53.   async getZalupa(id: number) {
  54.     const fun = () => this.api.fetchZalupa(id);
  55.     const { data } = await this.client.fetch(this.getKey(id), fun);
  56.     if (data) {
  57.       this.setData(data);
  58.     }
  59.   }
  60.  
  61.   invalidate(id: number) {
  62.     this.client.invalidateQuery(this.getKey(id));
  63.   }
  64.  
  65.   private getKey(id: number) {
  66.     return `zalupa-${id}`;
  67.   }
  68.  
  69.   private setData(data: ZalupaData) {
  70.     this.data = data;
  71.   }
  72. }
  73.  
  74. function useZalupa() {
  75.   const cache = useMemo(() => new QueryCache(), []);
  76.   const client = useMemo(() => new QueryClient(cache), []);
  77.   const api = useMemo(() => new Api(), []);
  78.   return useMemo(() => new Zalupa(client, api), [client]);
  79. }
  80.  
  81. function Component({ id }: { id: number }) {
  82.   const zalupa = useZalupa();
  83.  
  84.   useOnEvent("EVENT", ({ id }) => {
  85.     zalupa.invalidateQuery(id);
  86.     zalupa.getZalupa(id);
  87.   });
  88.  
  89.   useEffect(() => {
  90.     zalupa.getZalupa(id);
  91.   }, [id]);
  92.  
  93.   return <>{zalupa.data}</>;
  94. }
  95.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement