{"version":3,"file":"FeatureFlagProvider.mjs","sources":["../../../src/lib/flags/FeatureFlagProvider.tsx"],"sourcesContent":["import React, {\n  useContext,\n  useState,\n  useEffect,\n  useCallback,\n  useMemo,\n  type ReactNode,\n} from 'react';\nimport { FeatureFlagContext } from '../contexts/FeatureFlagContext';\nimport { env } from '../../config/env';\nimport { getDefaultFlags } from '../../config/featureFlagConfig';\nimport type { FlagKey } from './flag-keys';\nimport { _setFlagProviderInitialized, _updateRuntimeFlags, _resetFlagProvider } from './debug-mode';\n\ninterface FeatureFlagContextValue {\n  flags: Record<string, boolean>;\n  isLoading: boolean;\n  isEnabled: (flagKey: FlagKey | string) => boolean;\n  setFlag: (flagKey: string, value: boolean) => void;\n  refreshFlags: () => Promise<void>;\n}\n\ninterface FeatureFlagProviderProps {\n  children: ReactNode;\n  /** Override default flags for testing */\n  initialFlags?: Record<string, boolean>;\n}\n\n/**\n * Loads + exposes feature flag states (local or remote).\n */\nexport function FeatureFlagProvider({\n  children,\n  initialFlags,\n}: FeatureFlagProviderProps): React.JSX.Element {\n  const [flags, setFlags] = useState<Record<string, boolean>>(() => {\n    const initial = {\n      ...getDefaultFlags(),\n      ...initialFlags,\n    };\n    // Initialize runtime flags for non-React usage\n    _setFlagProviderInitialized(initial);\n    return initial;\n  });\n  const [isLoading, setIsLoading] = useState(false);\n\n  // Sync runtime flags when flags state changes\n  useEffect(() => {\n    _updateRuntimeFlags(flags);\n  }, [flags]);\n\n  // Cleanup on unmount\n  useEffect(() => {\n    return () => {\n      _resetFlagProvider();\n    };\n  }, []);\n\n  // Define refreshFlags BEFORE the useEffect that uses it\n  const refreshFlags = useCallback(async () => {\n    if (env.featureFlagsSource !== 'remote') return;\n\n    setIsLoading(true);\n    try {\n      // Fetch from remote feature flag service\n      const response = await fetch(`${env.apiBaseUrl}/feature-flags`);\n      if (response.ok) {\n        const remoteFlags = (await response.json()) as Record<string, boolean>;\n        setFlags((current) => ({\n          ...current,\n          ...remoteFlags,\n        }));\n      }\n    } catch (error) {\n      console.error('Failed to fetch feature flags:', error);\n    } finally {\n      setIsLoading(false);\n    }\n  }, []);\n\n  // Load flags based on configuration\n  useEffect(() => {\n    if (!env.featureFlagsEnabled) return;\n\n    const loadFlags = async (): Promise<void> => {\n      if (env.featureFlagsSource === 'remote') {\n        await refreshFlags();\n      }\n    };\n\n    void loadFlags();\n  }, [refreshFlags]);\n\n  const isEnabled = useCallback(\n    (flagKey: FlagKey | string): boolean => {\n      return flags[flagKey] ?? false;\n    },\n    [flags]\n  );\n\n  const setFlag = useCallback((flagKey: string, value: boolean) => {\n    setFlags((current) => ({\n      ...current,\n      [flagKey]: value,\n    }));\n  }, []);\n\n  // PERFORMANCE: Memoize context value to prevent unnecessary re-renders\n  const value: FeatureFlagContextValue = useMemo(\n    () => ({\n      flags,\n      isLoading,\n      isEnabled,\n      setFlag,\n      refreshFlags,\n    }),\n    [flags, isLoading, isEnabled, setFlag, refreshFlags]\n  );\n\n  return <FeatureFlagContext.Provider value={value}>{children}</FeatureFlagContext.Provider>;\n}\n\n/**\n * Hook to access the feature flag context.\n */\n// eslint-disable-next-line react-refresh/only-export-components\nexport function useFeatureFlagContext(): FeatureFlagContextValue {\n  const context = useContext(FeatureFlagContext);\n  if (!context) {\n    throw new Error('useFeatureFlagContext must be used within a FeatureFlagProvider');\n  }\n  return context;\n}\n"],"names":["FeatureFlagProvider","children","initialFlags","flags","setFlags","useState","initial","getDefaultFlags","_setFlagProviderInitialized","isLoading","setIsLoading","useEffect","_updateRuntimeFlags","_resetFlagProvider","refreshFlags","useCallback","env","response","remoteFlags","current","error","isEnabled","flagKey","setFlag","value","useMemo","jsx","FeatureFlagContext","useFeatureFlagContext","context","useContext"],"mappings":";;;;;;AA+BO,SAASA,EAAoB;AAAA,EAClC,UAAAC;AAAA,EACA,cAAAC;AACF,GAAgD;AAC9C,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAAkC,MAAM;AAChE,UAAMC,IAAU;AAAA,MACd,GAAGC,EAAA;AAAA,MACH,GAAGL;AAAA,IAAA;AAGL,WAAAM,EAA4BF,CAAO,GAC5BA;AAAA,EACT,CAAC,GACK,CAACG,GAAWC,CAAY,IAAIL,EAAS,EAAK;AAGhD,EAAAM,EAAU,MAAM;AACd,IAAAC,EAAoBT,CAAK;AAAA,EAC3B,GAAG,CAACA,CAAK,CAAC,GAGVQ,EAAU,MACD,MAAM;AACX,IAAAE,EAAA;AAAA,EACF,GACC,CAAA,CAAE;AAGL,QAAMC,IAAeC,EAAY,YAAY;AAC3C,QAAIC,EAAI,uBAAuB,UAE/B;AAAA,MAAAN,EAAa,EAAI;AACjB,UAAI;AAEF,cAAMO,IAAW,MAAM,MAAM,GAAGD,EAAI,UAAU,gBAAgB;AAC9D,YAAIC,EAAS,IAAI;AACf,gBAAMC,IAAe,MAAMD,EAAS,KAAA;AACpC,UAAAb,EAAS,CAACe,OAAa;AAAA,YACrB,GAAGA;AAAA,YACH,GAAGD;AAAA,UAAA,EACH;AAAA,QACJ;AAAA,MACF,SAASE,GAAO;AACd,gBAAQ,MAAM,kCAAkCA,CAAK;AAAA,MACvD,UAAA;AACE,QAAAV,EAAa,EAAK;AAAA,MACpB;AAAA;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,EAAAC,EAAU,MAAM;AACd,QAAI,CAACK,EAAI,oBAAqB;AAQ9B,KANkB,YAA2B;AAC3C,MAAIA,EAAI,uBAAuB,YAC7B,MAAMF,EAAA;AAAA,IAEV,GAEK;AAAA,EACP,GAAG,CAACA,CAAY,CAAC;AAEjB,QAAMO,IAAYN;AAAA,IAChB,CAACO,MACQnB,EAAMmB,CAAO,KAAK;AAAA,IAE3B,CAACnB,CAAK;AAAA,EAAA,GAGFoB,IAAUR,EAAY,CAACO,GAAiBE,MAAmB;AAC/D,IAAApB,EAAS,CAACe,OAAa;AAAA,MACrB,GAAGA;AAAA,MACH,CAACG,CAAO,GAAGE;AAAAA,IAAA,EACX;AAAA,EACJ,GAAG,CAAA,CAAE,GAGCA,IAAiCC;AAAA,IACrC,OAAO;AAAA,MACL,OAAAtB;AAAA,MACA,WAAAM;AAAA,MACA,WAAAY;AAAA,MACA,SAAAE;AAAA,MACA,cAAAT;AAAA,IAAA;AAAA,IAEF,CAACX,GAAOM,GAAWY,GAAWE,GAAST,CAAY;AAAA,EAAA;AAGrD,SAAO,gBAAAY,EAACC,EAAmB,UAAnB,EAA4B,OAAAH,GAAe,UAAAvB,EAAA,CAAS;AAC9D;AAMO,SAAS2B,IAAiD;AAC/D,QAAMC,IAAUC,EAAWH,CAAkB;AAC7C,MAAI,CAACE;AACH,UAAM,IAAI,MAAM,iEAAiE;AAEnF,SAAOA;AACT;"}