{"version":3,"sources":["../src/store/userStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { createJSONStorage, persist } from 'zustand/middleware';\nimport type { MyDataResponse } from '../types/user';\nimport { useAuthStore } from './authStore';\n\n/**\n * API client interface for user store\n */\nexport interface UserStoreApiClient {\n  get: <T>(url: string) => Promise<{ data: T }>;\n}\n\n/**\n * Configuration for creating a user store\n */\nexport interface CreateUserStoreConfig {\n  apiClient: UserStoreApiClient;\n  storageKey?: string;\n  cacheTTL?: number;\n}\n\n/**\n * Cache state for user data\n */\ninterface UserDataCache {\n  data: MyDataResponse | null;\n  cachedUserId: string | null;\n  lastFetched: number | null;\n  isLoading: boolean;\n  error: string | null;\n}\n\n/**\n * User store state interface\n */\nexport interface UserStoreState extends UserDataCache {\n  fetchUserData: (force?: boolean) => Promise<void>;\n  clearUserData: () => void;\n  setLoading: (loading: boolean) => void;\n  setError: (error: string | null) => void;\n}\n\n/**\n * Default cache TTL in milliseconds (5 minutes)\n */\nconst DEFAULT_CACHE_TTL = 5 * 60 * 1000;\n\n/**\n * Check if cache is still valid\n */\nconst isCacheValid = (\n  lastFetched: number | null,\n  cacheTTL: number\n): boolean => {\n  if (!lastFetched) return false;\n  return Date.now() - lastFetched < cacheTTL;\n};\n\n/**\n * Factory function to create a user store with dependency injection\n */\nexport function createUserStore(config: CreateUserStoreConfig) {\n  const {\n    apiClient,\n    storageKey = 'user-data-storage',\n    cacheTTL = DEFAULT_CACHE_TTL,\n  } = config;\n\n  /**\n   * Get current user data from the backend\n   */\n  const getMyData = async (): Promise<MyDataResponse> => {\n    const response = await apiClient.get<MyDataResponse>('/auth/me');\n    return response.data;\n  };\n\n  /**\n   * Get current user ID from auth store\n   */\n  const getCurrentUserId = (): string | null => {\n    return useAuthStore.getState().user?.id ?? null;\n  };\n\n  /**\n   * Check if cached data belongs to current user\n   */\n  const isCacheForCurrentUser = (cachedUserId: string | null): boolean => {\n    const currentUserId = getCurrentUserId();\n\n    if (!currentUserId) {\n      // No current user, cache is invalid\n      return false;\n    }\n\n    if (!cachedUserId) {\n      // No cached user ID, cache is invalid\n      return false;\n    }\n\n    return cachedUserId === currentUserId;\n  };\n\n  return create<UserStoreState>()(\n    persist(\n      (set, get) => ({\n        // Initial state\n        data: null,\n        cachedUserId: null,\n        lastFetched: null,\n        isLoading: false,\n        error: null,\n\n        /**\n         * Fetch user data from API with caching\n         */\n        fetchUserData: async (force = false): Promise<void> => {\n          const { data, cachedUserId, lastFetched, isLoading } = get();\n\n          // Avoid multiple simultaneous requests\n          if (isLoading) return;\n\n          // Validate cache belongs to current user\n          const cacheValidForUser = isCacheForCurrentUser(cachedUserId);\n\n          // Use cache if valid, belongs to current user, and not forcing refresh\n          if (\n            !force &&\n            data &&\n            cacheValidForUser &&\n            isCacheValid(lastFetched, cacheTTL)\n          ) {\n            return;\n          }\n\n          // If cache doesn't belong to current user, clear it\n          if (!cacheValidForUser && data) {\n            set({ data: null, cachedUserId: null, lastFetched: null });\n          }\n\n          try {\n            set({ isLoading: true, error: null });\n\n            const userData = await getMyData();\n\n            set({\n              data: userData,\n              cachedUserId: userData.user?.id ?? null,\n              lastFetched: Date.now(),\n              isLoading: false,\n              error: null,\n            });\n          } catch (error) {\n            const errorMessage =\n              error instanceof Error\n                ? error.message\n                : 'Failed to fetch user data';\n\n            set({\n              isLoading: false,\n              error: errorMessage,\n            });\n\n            throw error;\n          }\n        },\n\n        /**\n         * Clear all user data from store\n         */\n        clearUserData: (): void => {\n          set({\n            data: null,\n            cachedUserId: null,\n            lastFetched: null,\n            isLoading: false,\n            error: null,\n          });\n        },\n\n        /**\n         * Set loading state\n         */\n        setLoading: (loading: boolean): void => {\n          set({ isLoading: loading });\n        },\n\n        /**\n         * Set error state\n         */\n        setError: (error: string | null): void => {\n          set({ error });\n        },\n      }),\n      {\n        name: storageKey,\n        storage: createJSONStorage(() => localStorage),\n        // Persist data, cachedUserId and lastFetched (not loading/error states)\n        partialize: (state) => ({\n          data: state.data,\n          cachedUserId: state.cachedUserId,\n          lastFetched: state.lastFetched,\n        }),\n      }\n    )\n  );\n}\n"],"mappings":";;;;;AAAA,SAAS,cAAc;AACvB,SAAS,mBAAmB,eAAe;AA4C3C,IAAM,oBAAoB,IAAI,KAAK;AAKnC,IAAM,eAAe,CACnB,aACA,aACY;AACZ,MAAI,CAAC,YAAa,QAAO;AACzB,SAAO,KAAK,IAAI,IAAI,cAAc;AACpC;AAKO,SAAS,gBAAgB,QAA+B;AAC7D,QAAM;AAAA,IACJ;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,EACb,IAAI;AAKJ,QAAM,YAAY,YAAqC;AACrD,UAAM,WAAW,MAAM,UAAU,IAAoB,UAAU;AAC/D,WAAO,SAAS;AAAA,EAClB;AAKA,QAAM,mBAAmB,MAAqB;AAC5C,WAAO,aAAa,SAAS,EAAE,MAAM,MAAM;AAAA,EAC7C;AAKA,QAAM,wBAAwB,CAAC,iBAAyC;AACtE,UAAM,gBAAgB,iBAAiB;AAEvC,QAAI,CAAC,eAAe;AAElB,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,cAAc;AAEjB,aAAO;AAAA,IACT;AAEA,WAAO,iBAAiB;AAAA,EAC1B;AAEA,SAAO,OAAuB;AAAA,IAC5B;AAAA,MACE,CAAC,KAAK,SAAS;AAAA;AAAA,QAEb,MAAM;AAAA,QACN,cAAc;AAAA,QACd,aAAa;AAAA,QACb,WAAW;AAAA,QACX,OAAO;AAAA;AAAA;AAAA;AAAA,QAKP,eAAe,OAAO,QAAQ,UAAyB;AACrD,gBAAM,EAAE,MAAM,cAAc,aAAa,UAAU,IAAI,IAAI;AAG3D,cAAI,UAAW;AAGf,gBAAM,oBAAoB,sBAAsB,YAAY;AAG5D,cACE,CAAC,SACD,QACA,qBACA,aAAa,aAAa,QAAQ,GAClC;AACA;AAAA,UACF;AAGA,cAAI,CAAC,qBAAqB,MAAM;AAC9B,gBAAI,EAAE,MAAM,MAAM,cAAc,MAAM,aAAa,KAAK,CAAC;AAAA,UAC3D;AAEA,cAAI;AACF,gBAAI,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAEpC,kBAAM,WAAW,MAAM,UAAU;AAEjC,gBAAI;AAAA,cACF,MAAM;AAAA,cACN,cAAc,SAAS,MAAM,MAAM;AAAA,cACnC,aAAa,KAAK,IAAI;AAAA,cACtB,WAAW;AAAA,cACX,OAAO;AAAA,YACT,CAAC;AAAA,UACH,SAAS,OAAO;AACd,kBAAM,eACJ,iBAAiB,QACb,MAAM,UACN;AAEN,gBAAI;AAAA,cACF,WAAW;AAAA,cACX,OAAO;AAAA,YACT,CAAC;AAED,kBAAM;AAAA,UACR;AAAA,QACF;AAAA;AAAA;AAAA;AAAA,QAKA,eAAe,MAAY;AACzB,cAAI;AAAA,YACF,MAAM;AAAA,YACN,cAAc;AAAA,YACd,aAAa;AAAA,YACb,WAAW;AAAA,YACX,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA;AAAA;AAAA;AAAA,QAKA,YAAY,CAAC,YAA2B;AACtC,cAAI,EAAE,WAAW,QAAQ,CAAC;AAAA,QAC5B;AAAA;AAAA;AAAA;AAAA,QAKA,UAAU,CAAC,UAA+B;AACxC,cAAI,EAAE,MAAM,CAAC;AAAA,QACf;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS,kBAAkB,MAAM,YAAY;AAAA;AAAA,QAE7C,YAAY,CAAC,WAAW;AAAA,UACtB,MAAM,MAAM;AAAA,UACZ,cAAc,MAAM;AAAA,UACpB,aAAa,MAAM;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}