flipflag-sdk 1.1.21 → 1.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"react-native.mjs","sources":["../src/core/FlipFlagSDK.ts","../src/react-native/FeatureFlagProvider.tsx","../src/react-native/useFeatureFlag.ts","../src/react-native/useFeatureFlags.ts","../src/react-native/useABTest.ts","../src/react-native/identifyUser.ts","../src/react-native/offlineStorage.ts"],"sourcesContent":["import {\n FlipFlagConfig,\n FeatureFlagResponse,\n FeatureFlagsResponse,\n ABTestResponse,\n ABTestEventResponse,\n ABTestsResponse,\n FlipFlagError,\n CacheEntry,\n RetryOptions,\n SDKState,\n IdentifyUserOptions,\n} from \"../types\";\n\nexport class FlipFlagSDK {\n private config: FlipFlagConfig;\n private cache = new Map<string, CacheEntry<any>>();\n private defaultBaseUrl = \"https://app.flipflag.ru\";\n private pullIntervalId?: NodeJS.Timeout;\n private state: SDKState;\n private stateListeners: Set<(state: SDKState) => void> = new Set();\n\n constructor(config: FlipFlagConfig) {\n this.config = {\n baseUrl: this.defaultBaseUrl,\n cacheTimeout: 30000, // 30 seconds\n retryAttempts: 3,\n retryDelay: 1000, // 1 second\n pullInterval: 60000, // 1 minute\n ...config,\n };\n\n this.state = {\n flags: {},\n abTests: {},\n lastFetch: null,\n isLoading: false,\n error: null,\n };\n\n // Start automatic pulling if pullInterval is set\n if (this.config.pullInterval && this.config.pullInterval > 0) {\n this.startPulling();\n }\n }\n\n /**\n * Identify user for A/B testing and user-specific flags\n */\n identifyUser(options: IdentifyUserOptions): void {\n this.config.userId = options.userId;\n\n // Clear A/B test cache since user changed\n this.clearABTestCache();\n\n // If we have a user, we might want to refresh immediately\n if (this.config.pullInterval && this.config.pullInterval > 0) {\n this.pullData();\n }\n }\n\n /**\n * Get current SDK state\n */\n getState(): SDKState {\n return { ...this.state };\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(callback: (state: SDKState) => void): () => void {\n this.stateListeners.add(callback);\n\n // Return unsubscribe function\n return () => {\n this.stateListeners.delete(callback);\n };\n }\n\n /**\n * Get a feature flag value from current state\n */\n getFlagValue(flagName: string): boolean {\n return this.state.flags[flagName] ?? false;\n }\n\n /**\n * Get A/B test variant from current state\n */\n getABTestVariant(testName: string): ABTestResponse | null {\n return this.state.abTests[testName] || null;\n }\n\n /**\n * Start automatic data pulling\n */\n private startPulling(): void {\n if (this.pullIntervalId) {\n clearInterval(this.pullIntervalId);\n }\n\n this.pullIntervalId = setInterval(() => {\n this.pullData();\n }, this.config.pullInterval!);\n\n // Initial pull\n this.pullData();\n }\n\n /**\n * Stop automatic data pulling\n */\n stopPulling(): void {\n if (this.pullIntervalId) {\n clearInterval(this.pullIntervalId);\n this.pullIntervalId = undefined;\n }\n }\n\n /**\n * Pull fresh data from API\n */\n private async pullData(): Promise<void> {\n try {\n this.updateState({ isLoading: true, error: null });\n\n // Pull flags\n const flagsResponse = await this.fetchAllFlags();\n\n // Pull A/B tests if user is identified\n let abTestsResponse: ABTestsResponse | null = null;\n if (this.config.userId) {\n try {\n abTestsResponse = await this.fetchAllABTests();\n } catch (error) {\n console.warn(\"Failed to fetch A/B tests:\", error);\n }\n }\n\n const newState: Partial<SDKState> = {\n flags: flagsResponse?.flags || {},\n lastFetch: new Date(),\n isLoading: false,\n error: null,\n };\n\n if (abTestsResponse) {\n const abTestsMap: Record<string, ABTestResponse> = {};\n abTestsResponse.abTests.forEach((test) => {\n // For each test, get the variant for current user\n if (this.config.userId) {\n // This would normally fetch the variant, but for demo we'll simulate\n abTestsMap[test.name] = {\n testName: test.name,\n testId: test.id,\n variantId: \"variant_a\", // Default variant\n variant: test.variants[0] || {\n id: \"default\",\n name: \"Default\",\n value: null,\n weight: 100,\n },\n timestamp: new Date().toISOString(),\n };\n }\n });\n newState.abTests = abTestsMap;\n }\n\n this.updateState(newState);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n this.updateState({\n isLoading: false,\n error: errorMessage,\n });\n console.error(\"Failed to pull data:\", error);\n }\n }\n\n /**\n * Update state and notify listeners\n */\n private updateState(newState: Partial<SDKState>): void {\n this.state = { ...this.state, ...newState };\n\n // Notify all listeners\n this.stateListeners.forEach((callback) => {\n try {\n callback(this.state);\n } catch (error) {\n console.error(\"State listener error:\", error);\n }\n });\n }\n\n /**\n * Fetch all flags from API\n */\n private async fetchAllFlags(): Promise<FeatureFlagsResponse | null> {\n try {\n const url = new URL(\n `/api/sdk/flags/${this.config.projectId}`,\n this.config.baseUrl\n );\n if (this.config.environment) {\n url.searchParams.set(\"environment\", this.config.environment);\n }\n\n return await this.makeRequest<FeatureFlagsResponse>(url.toString());\n } catch (error) {\n console.error(\"Failed to fetch flags:\", error);\n return null;\n }\n }\n\n /**\n * Fetch all A/B tests from API\n */\n private async fetchAllABTests(): Promise<ABTestsResponse | null> {\n try {\n const url = new URL(\n `/api/sdk/ab-tests/${this.config.projectId}`,\n this.config.baseUrl\n );\n if (this.config.environment) {\n url.searchParams.set(\"environment\", this.config.environment);\n }\n\n return await this.makeRequest<ABTestsResponse>(url.toString());\n } catch (error) {\n console.error(\"Failed to fetch A/B tests:\", error);\n return null;\n }\n }\n\n /**\n * Clear A/B test cache\n */\n private clearABTestCache(): void {\n const abTestKeys = Array.from(this.cache.keys()).filter((key) =>\n key.startsWith(\"abtest:\")\n );\n abTestKeys.forEach((key) => this.cache.delete(key));\n }\n\n /**\n * Get all feature flags for a project\n */\n async getFlags(\n projectId: string = this.config.projectId,\n environment?: string\n ): Promise<FeatureFlagsResponse> {\n const cacheKey = `flags:${projectId}:${environment || \"all\"}`;\n const cached = this.getFromCache<FeatureFlagsResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(`/api/sdk/flags/${projectId}`, this.config.baseUrl);\n if (environment || this.config.environment) {\n url.searchParams.set(\n \"environment\",\n environment || this.config.environment!\n );\n }\n\n const response = await this.makeRequest<FeatureFlagsResponse>(\n url.toString()\n );\n this.setCache(cacheKey, response, this.config.cacheTimeout!);\n\n return response;\n }\n\n /**\n * Get a specific feature flag value\n */\n async getFlag(\n flagName: string,\n projectId: string = this.config.projectId,\n environment?: string\n ): Promise<FeatureFlagResponse> {\n // If we have the flag in state, return it immediately\n if (this.state.flags[flagName] !== undefined) {\n return {\n projectId: this.config.projectId,\n flagName,\n environment: this.config.environment || \"all\",\n value: this.state.flags[flagName],\n timestamp:\n this.state.lastFetch?.toISOString() || new Date().toISOString(),\n };\n }\n\n // Check if we're currently loading data (pullData in progress)\n // In this case, wait a bit and check state again\n if (this.state.isLoading) {\n // Wait up to 5 seconds for loading to complete\n for (let i = 0; i < 50; i++) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n if (!this.state.isLoading && this.state.flags[flagName] !== undefined) {\n return {\n projectId: this.config.projectId,\n flagName,\n environment: this.config.environment || \"all\",\n value: this.state.flags[flagName],\n timestamp:\n this.state.lastFetch?.toISOString() || new Date().toISOString(),\n };\n }\n }\n }\n\n const cacheKey = `flag:${projectId}:${flagName}:${environment || \"all\"}`;\n const cached = this.getFromCache<FeatureFlagResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(\n `/api/sdk/flags/${projectId}/${flagName}`,\n this.config.baseUrl\n );\n if (environment || this.config.environment) {\n url.searchParams.set(\n \"environment\",\n environment || this.config.environment!\n );\n }\n\n const response = await this.makeRequest<FeatureFlagResponse>(\n url.toString()\n );\n this.setCache(cacheKey, response, this.config.cacheTimeout!);\n\n return response;\n }\n\n /**\n * Get A/B test variant for a user\n */\n async getAbTestVariant(\n testName: string,\n userId: string,\n projectId: string = this.config.projectId\n ): Promise<ABTestResponse> {\n // If we have the A/B test in state, return it immediately\n const stateVariant = this.state.abTests[testName];\n if (stateVariant && stateVariant.testName === testName) {\n return stateVariant;\n }\n\n const cacheKey = `abtest:${projectId}:${testName}:${userId}`;\n const cached = this.getFromCache<ABTestResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(\n `/api/sdk/ab-test/${projectId}/${testName}`,\n this.config.baseUrl\n );\n\n const response = await this.makeRequest<ABTestResponse>(url, {\n headers: {\n \"X-User-ID\": userId,\n },\n });\n\n // Cache A/B test variants for longer since they shouldn't change frequently for a user\n this.setCache(cacheKey, response, this.config.cacheTimeout! * 10);\n\n return response;\n }\n\n /**\n * Record an A/B test event\n */\n async recordAbTestEvent(\n testName: string,\n userId: string,\n event: string,\n variantId: string,\n eventData?: Record<string, any>,\n projectId: string = this.config.projectId\n ): Promise<ABTestEventResponse> {\n const url = new URL(\n `/api/sdk/ab-test/${projectId}/${testName}/event`,\n this.config.baseUrl\n );\n\n return this.makeRequest<ABTestEventResponse>(url, {\n method: \"POST\",\n headers: {\n \"X-User-ID\": userId,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n event,\n variantId,\n eventData,\n }),\n });\n }\n\n /**\n * Get all A/B tests for a project\n */\n async getAbTests(\n projectId: string = this.config.projectId\n ): Promise<ABTestsResponse> {\n const cacheKey = `abtests:${projectId}`;\n const cached = this.getFromCache<ABTestsResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(`/api/sdk/ab-tests/${projectId}`, this.config.baseUrl);\n\n const response = await this.makeRequest<ABTestsResponse>(url);\n this.setCache(cacheKey, response, this.config.cacheTimeout!);\n\n return response;\n }\n\n /**\n * Clear cache for specific key or all cache\n */\n clearCache(key?: string): void {\n if (key) {\n this.cache.delete(key);\n } else {\n this.cache.clear();\n }\n }\n\n /**\n * Update configuration\n */\n updateConfig(newConfig: Partial<FlipFlagConfig>): void {\n this.config = { ...this.config, ...newConfig };\n }\n\n private async makeRequest<T>(\n url: string | URL,\n options: RequestInit = {}\n ): Promise<T> {\n // Convert URL object to string if needed\n const urlString = url instanceof URL ? url.toString() : url;\n\n // If URL starts with '/', prepend baseUrl and handle trailing slashes\n const fullUrl = urlString.startsWith(\"/\")\n ? `${this.config.baseUrl?.replace(/\\/$/, \"\") || this.defaultBaseUrl}${urlString}`\n : urlString;\n\n const headers = {\n \"X-API-Key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n };\n\n const requestOptions: RequestInit = {\n ...options,\n headers,\n };\n\n return this.makeRequestWithRetry<T>(fullUrl, requestOptions);\n }\n\n private async makeRequestWithRetry<T>(\n url: string,\n options: RequestInit,\n retryOptions: RetryOptions = {\n attempts: this.config.retryAttempts!,\n delay: this.config.retryDelay!,\n backoff: 2,\n }\n ): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= retryOptions.attempts; attempt++) {\n try {\n const response = await fetch(url, options);\n if (!response.ok) {\n console.log(\"retry sdk\");\n const errorData = await response.json().catch(() => ({}));\n throw new Error(\n `HTTP ${response.status}: ${errorData.error || response.statusText}`\n );\n }\n\n return await response.json();\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on client errors (4xx) except 429 (rate limit)\n if (error instanceof Error && error.message.includes(\"HTTP 4\")) {\n if (!error.message.includes(\"HTTP 429\")) {\n throw error;\n }\n }\n\n if (attempt < retryOptions.attempts) {\n const delay =\n retryOptions.delay * Math.pow(retryOptions.backoff, attempt - 1);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError!;\n }\n\n private getFromCache<T>(key: string): T | null {\n const entry = this.cache.get(key);\n\n if (!entry) {\n return null;\n }\n\n if (Date.now() - entry.timestamp > entry.ttl) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.data;\n }\n\n private setCache<T>(key: string, data: T, ttl: number): void {\n this.cache.set(key, {\n data,\n timestamp: Date.now(),\n ttl,\n });\n }\n\n /**\n * Cleanup method - should be called when SDK is no longer needed\n */\n public destroy(): void {\n this.stopPulling();\n this.stateListeners.clear();\n this.cache.clear();\n }\n}\n","import React, { createContext, useContext, ReactNode } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { FlipFlagConfig } from \"../types\";\n\ninterface FeatureFlagContextValue {\n sdk: FlipFlagSDK;\n config: FlipFlagConfig;\n}\n\nconst FeatureFlagContext = createContext<FeatureFlagContextValue | null>(null);\n\ninterface FeatureFlagProviderProps {\n children: ReactNode;\n config: FlipFlagConfig;\n}\n\nexport function FeatureFlagProvider({\n children,\n config,\n}: FeatureFlagProviderProps) {\n const sdk = new FlipFlagSDK(config);\n\n const contextValue: FeatureFlagContextValue = {\n sdk,\n config,\n };\n\n return (\n <FeatureFlagContext.Provider value={contextValue}>\n {children}\n </FeatureFlagContext.Provider>\n );\n}\n\nexport function useFeatureFlagContext(): FeatureFlagContextValue {\n const context = useContext(FeatureFlagContext);\n\n if (!context) {\n throw new Error(\n \"useFeatureFlagContext must be used within a FeatureFlagProvider\"\n );\n }\n\n return context;\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { FeatureFlagValue, FlipFlagConfig } from \"../types\";\nimport { FeatureFlagHookResult } from \"./types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\ninterface UseFeatureFlagOptions {\n fallbackValue?: FeatureFlagValue;\n enabled?: boolean;\n}\n\nexport function useFeatureFlag(\n flagName: string,\n options: UseFeatureFlagOptions & { config?: FlipFlagConfig } = {}\n): FeatureFlagHookResult {\n const [value, setValue] = useState<FeatureFlagValue>(\n options.fallbackValue ?? false\n );\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Try to get SDK from context, otherwise create new instance\n let sdk: FlipFlagSDK;\n try {\n const context = useFeatureFlagContext();\n sdk = context.sdk;\n } catch {\n if (!options.config) {\n throw new Error(\n \"useFeatureFlag must be used within FeatureFlagProvider or config must be provided\"\n );\n }\n sdk = new FlipFlagSDK(options.config);\n }\n\n const updateFromState = useCallback(() => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n try {\n const flagValue = sdk.getFlagValue(flagName);\n setValue(flagValue);\n setLoading(false);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n if (options.fallbackValue !== undefined) {\n setValue(options.fallbackValue);\n }\n setLoading(false);\n }\n }, [sdk, flagName, options.fallbackValue, options.enabled]);\n\n const refetch = useCallback(async () => {\n sdk.clearCache(\n `flag:${sdk[\"config\"].projectId}:${flagName}:${sdk[\"config\"].environment || \"all\"}`\n );\n setLoading(true);\n\n try {\n const response = await sdk.getFlag(flagName);\n setValue(response.value);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n if (options.fallbackValue !== undefined) {\n setValue(options.fallbackValue);\n }\n } finally {\n setLoading(false);\n }\n }, [sdk, flagName, options.fallbackValue]);\n\n useEffect(() => {\n // Subscribe to state changes\n const unsubscribe = sdk.subscribe((state) => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n const flagValue = state.flags[flagName];\n if (flagValue !== undefined) {\n setValue(flagValue);\n setLoading(false);\n setError(state.error);\n }\n });\n\n // Initial update from current state\n updateFromState();\n\n return unsubscribe;\n }, [updateFromState, options.enabled]);\n\n return {\n value,\n loading,\n error,\n refetch,\n };\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { FeatureFlagValue, FlipFlagConfig } from \"../types\";\nimport { FeatureFlagsHookResult } from \"./types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\ninterface UseFeatureFlagsOptions {\n fallbackValues?: Record<string, FeatureFlagValue>;\n enabled?: boolean;\n}\n\nexport function useFeatureFlags(\n flagNames: string[],\n options: UseFeatureFlagsOptions & { config?: FlipFlagConfig } = {}\n): FeatureFlagsHookResult {\n const [flags, setFlags] = useState<Record<string, FeatureFlagValue>>(() => {\n // Initialize with fallback values\n const initialFlags: Record<string, FeatureFlagValue> = {};\n flagNames.forEach((flagName) => {\n initialFlags[flagName] = options.fallbackValues?.[flagName] ?? false;\n });\n return initialFlags;\n });\n\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Try to get SDK from context, otherwise create new instance\n let sdk: FlipFlagSDK;\n try {\n const context = useFeatureFlagContext();\n sdk = context.sdk;\n } catch {\n if (!options.config) {\n throw new Error(\n \"useFeatureFlags must be used within FeatureFlagProvider or config must be provided\"\n );\n }\n sdk = new FlipFlagSDK(options.config);\n }\n\n const updateFromState = useCallback(() => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n try {\n const newFlags: Record<string, FeatureFlagValue> = { ...flags };\n let hasChanges = false;\n\n flagNames.forEach((flagName) => {\n const flagValue = sdk.getFlagValue(flagName);\n if (newFlags[flagName] !== flagValue) {\n newFlags[flagName] = flagValue;\n hasChanges = true;\n }\n });\n\n if (hasChanges) {\n setFlags(newFlags);\n }\n\n setLoading(false);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n // Use fallback values\n const fallbackFlags: Record<string, FeatureFlagValue> = {};\n flagNames.forEach((flagName) => {\n fallbackFlags[flagName] = options.fallbackValues?.[flagName] ?? false;\n });\n setFlags(fallbackFlags);\n setLoading(false);\n }\n }, [sdk, flagNames, options.fallbackValues, options.enabled, flags]);\n\n const refetch = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n // Force refresh by triggering pull\n await Promise.all(\n flagNames.map((flagName) =>\n sdk.getFlag(flagName).catch(() => {\n // Ignore individual flag errors, will use state values\n })\n )\n );\n\n updateFromState();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n // Use fallback values\n const fallbackFlags: Record<string, FeatureFlagValue> = {};\n flagNames.forEach((flagName) => {\n fallbackFlags[flagName] = options.fallbackValues?.[flagName] ?? false;\n });\n setFlags(fallbackFlags);\n setLoading(false);\n }\n }, [sdk, flagNames, options.fallbackValues, updateFromState]);\n\n useEffect(() => {\n // Subscribe to state changes\n const unsubscribe = sdk.subscribe((state) => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n const newFlags: Record<string, FeatureFlagValue> = { ...flags };\n let hasChanges = false;\n\n flagNames.forEach((flagName) => {\n const flagValue = state.flags[flagName];\n if (flagValue !== undefined && newFlags[flagName] !== flagValue) {\n newFlags[flagName] = flagValue;\n hasChanges = true;\n }\n });\n\n if (hasChanges) {\n setFlags(newFlags);\n }\n\n setLoading(false);\n setError(state.error);\n });\n\n // Initial update from current state\n updateFromState();\n\n return unsubscribe;\n }, [updateFromState, options.enabled]);\n\n return {\n flags,\n loading,\n error,\n refetch,\n };\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { ABTestValue, FlipFlagConfig } from \"../types\";\nimport { ABTestHookResult } from \"./types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\ninterface UseABTestOptions {\n userId: string;\n enabled?: boolean;\n}\n\nexport function useABTest(\n testName: string,\n options: UseABTestOptions & { config?: FlipFlagConfig }\n): ABTestHookResult {\n const [variant, setVariant] = useState<ABTestValue | null>(null);\n const [variantId, setVariantId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Try to get SDK from context, otherwise create new instance\n let sdk: FlipFlagSDK;\n try {\n const context = useFeatureFlagContext();\n sdk = context.sdk;\n } catch {\n if (!options.config) {\n throw new Error(\n \"useABTest must be used within FeatureFlagProvider or config must be provided\"\n );\n }\n sdk = new FlipFlagSDK(options.config);\n }\n\n const updateFromState = useCallback(() => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n try {\n const abTestVariant = sdk.getABTestVariant(testName);\n if (abTestVariant) {\n setVariant(abTestVariant.variant.value);\n setVariantId(abTestVariant.variantId);\n } else {\n setVariant(null);\n setVariantId(null);\n }\n\n setLoading(false);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n setVariant(null);\n setVariantId(null);\n setLoading(false);\n }\n }, [sdk, testName, options.enabled]);\n\n const recordEvent = useCallback(\n async (event: string, eventData?: Record<string, any>) => {\n if (!variantId) {\n console.warn(\"Cannot record event: no variant assigned yet\");\n return;\n }\n\n try {\n await sdk.recordAbTestEvent(\n testName,\n options.userId,\n event,\n variantId,\n eventData\n );\n } catch (err) {\n console.error(\"Failed to record A/B test event:\", err);\n }\n },\n [sdk, testName, options.userId, variantId]\n );\n\n useEffect(() => {\n // Subscribe to state changes\n const unsubscribe = sdk.subscribe((state) => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n const abTestVariant = state.abTests[testName];\n if (abTestVariant) {\n setVariant(abTestVariant.variant.value);\n setVariantId(abTestVariant.variantId);\n } else {\n setVariant(null);\n setVariantId(null);\n }\n\n setLoading(false);\n setError(state.error);\n });\n\n // Initial update from current state\n updateFromState();\n\n return unsubscribe;\n }, [updateFromState, options.enabled]);\n\n return {\n variant,\n variantId,\n loading,\n error,\n recordEvent,\n };\n}\n","import { IdentifyUserOptions } from \"../types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\n/**\n * Identify user for A/B testing and user-specific flags\n * Must be called within FeatureFlagProvider\n */\nexport function identifyUser(options: IdentifyUserOptions): void {\n const context = useFeatureFlagContext();\n context.sdk.identifyUser(options);\n}\n","import AsyncStorage from \"@react-native-async-storage/async-storage\";\nimport { OfflineStorage } from \"./types\";\n\n/**\n * Create offline storage using AsyncStorage\n */\nexport function createOfflineStorage(): OfflineStorage {\n return {\n async getItem(key: string): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(key);\n } catch (error) {\n console.error(\"AsyncStorage getItem error:\", error);\n return null;\n }\n },\n\n async setItem(key: string, value: string): Promise<void> {\n try {\n await AsyncStorage.setItem(key, value);\n } catch (error) {\n console.error(\"AsyncStorage setItem error:\", error);\n }\n },\n\n async removeItem(key: string): Promise<void> {\n try {\n await AsyncStorage.removeItem(key);\n } catch (error) {\n console.error(\"AsyncStorage removeItem error:\", error);\n }\n },\n };\n}\n\n/**\n * Create offline storage with custom storage implementation\n */\nexport function createCustomOfflineStorage(\n storage: OfflineStorage\n): OfflineStorage {\n return storage;\n}\n"],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"react-native.mjs","sources":["../src/core/FlipFlagSDK.ts","../src/react-native/FeatureFlagProvider.tsx","../src/react-native/useFeatureFlag.ts","../src/react-native/useFeatureFlags.ts","../src/react-native/useABTest.ts","../src/react-native/identifyUser.ts","../src/react-native/offlineStorage.ts"],"sourcesContent":["import {\n FlipFlagConfig,\n FeatureFlagResponse,\n FeatureFlagsResponse,\n ABTestResponse,\n ABTestEventResponse,\n ABTestsResponse,\n FlipFlagError,\n CacheEntry,\n RetryOptions,\n SDKState,\n IdentifyUserOptions,\n} from \"../types\";\n\nexport class FlipFlagSDK {\n private config: FlipFlagConfig;\n private cache = new Map<string, CacheEntry<any>>();\n private defaultBaseUrl = \"https://app.flipflag.ru\";\n private pullIntervalId?: NodeJS.Timeout;\n private state: SDKState;\n private stateListeners: Set<(state: SDKState) => void> = new Set();\n private maxListeners = 100; // Maximum number of listeners to prevent memory leaks\n\n constructor(config: FlipFlagConfig) {\n // Validate required configuration\n this.validateConfig(config);\n\n this.config = {\n baseUrl: this.defaultBaseUrl,\n cacheTimeout: 30000, // 30 seconds\n retryAttempts: 3,\n retryDelay: 1000, // 1 second\n pullInterval: 60000, // 1 minute\n ...config,\n };\n\n this.state = {\n flags: {},\n abTests: {},\n lastFetch: null,\n isLoading: false,\n error: null,\n };\n\n // Start automatic pulling if pullInterval is set\n if (this.config.pullInterval && this.config.pullInterval > 0) {\n this.startPulling();\n }\n }\n\n /**\n * Identify user for A/B testing and user-specific flags\n */\n identifyUser(options: IdentifyUserOptions): void {\n if (!options || typeof options !== \"object\") {\n throw new Error(\"options must be an object\");\n }\n\n if (!options.userId || typeof options.userId !== \"string\") {\n throw new Error(\"userId is required and must be a string\");\n }\n\n if (options.userProperties && typeof options.userProperties !== \"object\") {\n throw new Error(\"userProperties must be an object\");\n }\n\n this.config.userId = options.userId;\n\n // Clear A/B test cache since user changed\n this.clearABTestCache();\n\n // If we have a user, we might want to refresh immediately\n if (this.config.pullInterval && this.config.pullInterval > 0) {\n this.pullData();\n }\n }\n\n /**\n * Get current SDK state\n */\n getState(): SDKState {\n return { ...this.state };\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(callback: (state: SDKState) => void): () => void {\n if (this.stateListeners.size >= this.maxListeners) {\n console.warn(\n `Maximum number of listeners (${this.maxListeners}) reached. This may cause memory leaks.`\n );\n }\n\n this.stateListeners.add(callback);\n\n // Return unsubscribe function\n return () => {\n this.stateListeners.delete(callback);\n };\n }\n\n /**\n * Get a feature flag value from current state\n */\n getFlagValue(flagName: string): boolean {\n return this.state.flags[flagName] ?? false;\n }\n\n /**\n * Get A/B test variant from current state\n */\n getABTestVariant(testName: string): ABTestResponse | null {\n return this.state.abTests[testName] || null;\n }\n\n /**\n * Start automatic data pulling\n */\n private startPulling(): void {\n if (this.pullIntervalId) {\n clearInterval(this.pullIntervalId);\n }\n\n this.pullIntervalId = setInterval(() => {\n this.pullData();\n }, this.config.pullInterval!);\n\n // Initial pull\n this.pullData();\n }\n\n /**\n * Stop automatic data pulling\n */\n stopPulling(): void {\n if (this.pullIntervalId) {\n clearInterval(this.pullIntervalId);\n this.pullIntervalId = undefined;\n }\n }\n\n /**\n * Pull fresh data from API\n */\n private async pullData(): Promise<void> {\n try {\n this.updateState({ isLoading: true, error: null });\n\n // Pull flags\n const flagsResponse = await this.fetchAllFlags();\n\n // Pull A/B tests if user is identified\n let abTestsResponse: ABTestsResponse | null = null;\n if (this.config.userId) {\n try {\n abTestsResponse = await this.fetchAllABTests();\n } catch (error) {\n console.warn(\"Failed to fetch A/B tests:\", error);\n }\n }\n\n const newState: Partial<SDKState> = {\n flags: flagsResponse?.flags || {},\n lastFetch: new Date(),\n isLoading: false,\n error: null,\n };\n\n if (abTestsResponse) {\n const abTestsMap: Record<string, ABTestResponse> = {};\n abTestsResponse.abTests.forEach((test) => {\n // For each test, get the variant for current user\n if (this.config.userId) {\n // This would normally fetch the variant, but for demo we'll simulate\n abTestsMap[test.name] = {\n testName: test.name,\n testId: test.id,\n variantId: \"variant_a\", // Default variant\n variant: test.variants[0] || {\n id: \"default\",\n name: \"Default\",\n value: null,\n weight: 100,\n },\n timestamp: new Date().toISOString(),\n };\n }\n });\n newState.abTests = abTestsMap;\n }\n\n this.updateState(newState);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n this.updateState({\n isLoading: false,\n error: errorMessage,\n });\n console.error(\"Failed to pull data:\", error);\n }\n }\n\n /**\n * Update state and notify listeners\n */\n private updateState(newState: Partial<SDKState>): void {\n this.state = { ...this.state, ...newState };\n\n // Notify all listeners\n this.stateListeners.forEach((callback) => {\n try {\n callback(this.state);\n } catch (error) {\n console.error(\"State listener error:\", error);\n // Remove faulty listener to prevent repeated errors\n this.stateListeners.delete(callback);\n }\n });\n }\n\n /**\n * Fetch all flags from API\n */\n private async fetchAllFlags(): Promise<FeatureFlagsResponse | null> {\n try {\n const url = new URL(\n `/api/sdk/flags/${this.config.projectId}`,\n this.config.baseUrl\n );\n if (this.config.environment) {\n url.searchParams.set(\"environment\", this.config.environment);\n }\n\n return await this.makeRequest<FeatureFlagsResponse>(url.toString());\n } catch (error) {\n console.error(\"Failed to fetch flags:\", error);\n return null;\n }\n }\n\n /**\n * Fetch all A/B tests from API\n */\n private async fetchAllABTests(): Promise<ABTestsResponse | null> {\n try {\n const url = new URL(\n `/api/sdk/ab-tests/${this.config.projectId}`,\n this.config.baseUrl\n );\n if (this.config.environment) {\n url.searchParams.set(\"environment\", this.config.environment);\n }\n\n return await this.makeRequest<ABTestsResponse>(url.toString());\n } catch (error) {\n console.error(\"Failed to fetch A/B tests:\", error);\n return null;\n }\n }\n\n /**\n * Clear A/B test cache\n */\n private clearABTestCache(): void {\n const abTestKeys = Array.from(this.cache.keys()).filter((key) =>\n key.startsWith(\"abtest:\")\n );\n abTestKeys.forEach((key) => this.cache.delete(key));\n }\n\n /**\n * Get all feature flags for a project\n */\n async getFlags(\n projectId: string = this.config.projectId,\n environment?: string\n ): Promise<FeatureFlagsResponse> {\n const cacheKey = `flags:${projectId}:${environment || \"all\"}`;\n const cached = this.getFromCache<FeatureFlagsResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(`/api/sdk/flags/${projectId}`, this.config.baseUrl);\n if (environment || this.config.environment) {\n url.searchParams.set(\n \"environment\",\n environment || this.config.environment!\n );\n }\n\n const response = await this.makeRequest<FeatureFlagsResponse>(\n url.toString()\n );\n this.setCache(cacheKey, response, this.config.cacheTimeout!);\n\n return response;\n }\n\n /**\n * Get a specific feature flag value\n */\n async getFlag(\n flagName: string,\n projectId: string = this.config.projectId,\n environment?: string\n ): Promise<FeatureFlagResponse> {\n if (!flagName || typeof flagName !== \"string\") {\n throw new Error(\"flagName is required and must be a string\");\n }\n\n if (!projectId || typeof projectId !== \"string\") {\n throw new Error(\"projectId must be a string\");\n }\n\n if (environment && typeof environment !== \"string\") {\n throw new Error(\"environment must be a string\");\n }\n // If we have the flag in state, return it immediately\n if (this.state.flags[flagName] !== undefined) {\n return {\n projectId: this.config.projectId,\n flagName,\n environment: this.config.environment || \"all\",\n value: this.state.flags[flagName],\n timestamp:\n this.state.lastFetch?.toISOString() || new Date().toISOString(),\n };\n }\n\n // Check if we're currently loading data (pullData in progress)\n // In this case, wait for loading to complete using Promise\n if (this.state.isLoading) {\n await this.waitForLoadingComplete();\n // After waiting, check state again\n if (this.state.flags[flagName] !== undefined) {\n return {\n projectId: this.config.projectId,\n flagName,\n environment: this.config.environment || \"all\",\n value: this.state.flags[flagName],\n timestamp:\n this.state.lastFetch?.toISOString() || new Date().toISOString(),\n };\n }\n }\n\n const cacheKey = `flag:${projectId}:${flagName}:${environment || \"all\"}`;\n const cached = this.getFromCache<FeatureFlagResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(\n `/api/sdk/flags/${projectId}/${flagName}`,\n this.config.baseUrl\n );\n if (environment || this.config.environment) {\n url.searchParams.set(\n \"environment\",\n environment || this.config.environment!\n );\n }\n\n const response = await this.makeRequest<FeatureFlagResponse>(\n url.toString()\n );\n this.setCache(cacheKey, response, this.config.cacheTimeout!);\n\n return response;\n }\n\n /**\n * Validate configuration\n */\n private validateConfig(config: FlipFlagConfig): void {\n if (!config.apiKey || typeof config.apiKey !== \"string\") {\n throw new Error(\"apiKey is required and must be a string\");\n }\n\n if (!config.projectId || typeof config.projectId !== \"string\") {\n throw new Error(\"projectId is required and must be a string\");\n }\n\n if (config.baseUrl && typeof config.baseUrl !== \"string\") {\n throw new Error(\"baseUrl must be a string\");\n }\n\n if (config.environment && typeof config.environment !== \"string\") {\n throw new Error(\"environment must be a string\");\n }\n\n if (config.userId && typeof config.userId !== \"string\") {\n throw new Error(\"userId must be a string\");\n }\n\n if (\n config.cacheTimeout &&\n (typeof config.cacheTimeout !== \"number\" || config.cacheTimeout < 0)\n ) {\n throw new Error(\"cacheTimeout must be a non-negative number\");\n }\n\n if (\n config.retryAttempts &&\n (typeof config.retryAttempts !== \"number\" || config.retryAttempts < 0)\n ) {\n throw new Error(\"retryAttempts must be a non-negative number\");\n }\n\n if (\n config.retryDelay &&\n (typeof config.retryDelay !== \"number\" || config.retryDelay < 0)\n ) {\n throw new Error(\"retryDelay must be a non-negative number\");\n }\n\n if (\n config.pullInterval &&\n (typeof config.pullInterval !== \"number\" || config.pullInterval < 0)\n ) {\n throw new Error(\"pullInterval must be a non-negative number\");\n }\n }\n\n /**\n * Wait for loading to complete with timeout\n */\n private async waitForLoadingComplete(timeout: number = 5000): Promise<void> {\n const startTime = Date.now();\n\n return new Promise((resolve, reject) => {\n const checkLoading = () => {\n if (!this.state.isLoading) {\n resolve();\n return;\n }\n\n if (Date.now() - startTime > timeout) {\n reject(new Error(\"Timeout waiting for SDK loading to complete\"));\n return;\n }\n\n // Check again after a short delay\n setTimeout(checkLoading, 50);\n };\n\n checkLoading();\n });\n }\n\n /**\n * Get A/B test variant for a user\n */\n async getAbTestVariant(\n testName: string,\n userId: string,\n projectId: string = this.config.projectId\n ): Promise<ABTestResponse> {\n if (!testName || typeof testName !== \"string\") {\n throw new Error(\"testName is required and must be a string\");\n }\n\n if (!userId || typeof userId !== \"string\") {\n throw new Error(\"userId is required and must be a string\");\n }\n\n if (!projectId || typeof projectId !== \"string\") {\n throw new Error(\"projectId must be a string\");\n }\n // If we have the A/B test in state, return it immediately\n const stateVariant = this.state.abTests[testName];\n if (stateVariant && stateVariant.testName === testName) {\n return stateVariant;\n }\n\n const cacheKey = `abtest:${projectId}:${testName}:${userId}`;\n const cached = this.getFromCache<ABTestResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(\n `/api/sdk/ab-test/${projectId}/${testName}`,\n this.config.baseUrl\n );\n\n const response = await this.makeRequest<ABTestResponse>(url, {\n headers: {\n \"X-User-ID\": userId,\n },\n });\n\n // Cache A/B test variants for longer since they shouldn't change frequently for a user\n this.setCache(cacheKey, response, this.config.cacheTimeout! * 10);\n\n return response;\n }\n\n /**\n * Record an A/B test event\n */\n async recordAbTestEvent(\n testName: string,\n userId: string,\n event: string,\n variantId: string,\n eventData?: Record<string, any>,\n projectId: string = this.config.projectId\n ): Promise<ABTestEventResponse> {\n const url = new URL(\n `/api/sdk/ab-test/${projectId}/${testName}/event`,\n this.config.baseUrl\n );\n\n return this.makeRequest<ABTestEventResponse>(url, {\n method: \"POST\",\n headers: {\n \"X-User-ID\": userId,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n event,\n variantId,\n eventData,\n }),\n });\n }\n\n /**\n * Get all A/B tests for a project\n */\n async getAbTests(\n projectId: string = this.config.projectId\n ): Promise<ABTestsResponse> {\n const cacheKey = `abtests:${projectId}`;\n const cached = this.getFromCache<ABTestsResponse>(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const url = new URL(`/api/sdk/ab-tests/${projectId}`, this.config.baseUrl);\n\n const response = await this.makeRequest<ABTestsResponse>(url);\n this.setCache(cacheKey, response, this.config.cacheTimeout!);\n\n return response;\n }\n\n /**\n * Clear cache for specific key or all cache\n */\n clearCache(key?: string): void {\n if (key) {\n this.cache.delete(key);\n } else {\n this.cache.clear();\n }\n }\n\n /**\n * Clear cache for specific flag\n */\n clearFlagCache(flagName: string, environment?: string): void {\n const cacheKey = `flag:${this.config.projectId}:${flagName}:${environment || \"all\"}`;\n this.cache.delete(cacheKey);\n }\n\n /**\n * Clear cache for all flags\n */\n clearFlagsCache(environment?: string): void {\n const cacheKey = `flags:${this.config.projectId}:${environment || \"all\"}`;\n this.cache.delete(cacheKey);\n }\n\n /**\n * Clear cache for A/B test variant\n */\n clearABTestCache(testName?: string, userId?: string): void {\n if (testName && userId) {\n const cacheKey = `abtest:${this.config.projectId}:${testName}:${userId}`;\n this.cache.delete(cacheKey);\n } else {\n // Clear all A/B test cache\n const abTestKeys = Array.from(this.cache.keys()).filter((key) =>\n key.startsWith(\"abtest:\")\n );\n abTestKeys.forEach((key) => this.cache.delete(key));\n }\n }\n\n /**\n * Update configuration\n */\n updateConfig(newConfig: Partial<FlipFlagConfig>): void {\n this.config = { ...this.config, ...newConfig };\n }\n\n private async makeRequest<T>(\n url: string | URL,\n options: RequestInit = {}\n ): Promise<T> {\n // Convert URL object to string if needed\n const urlString = url instanceof URL ? url.toString() : url;\n\n // If URL starts with '/', prepend baseUrl and handle trailing slashes\n const fullUrl = urlString.startsWith(\"/\")\n ? `${this.config.baseUrl?.replace(/\\/$/, \"\") || this.defaultBaseUrl}${urlString}`\n : urlString;\n\n const headers = {\n \"X-API-Key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n };\n\n const requestOptions: RequestInit = {\n ...options,\n headers,\n };\n\n return this.makeRequestWithRetry<T>(fullUrl, requestOptions);\n }\n\n private async makeRequestWithRetry<T>(\n url: string,\n options: RequestInit,\n retryOptions: RetryOptions = {\n attempts: this.config.retryAttempts!,\n delay: this.config.retryDelay!,\n backoff: 2,\n }\n ): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= retryOptions.attempts; attempt++) {\n try {\n const response = await fetch(url, options);\n if (!response.ok) {\n console.log(\"retry sdk\");\n const errorData = await response.json().catch(() => ({}));\n throw new Error(\n `HTTP ${response.status}: ${errorData.error || response.statusText}`\n );\n }\n\n return await response.json();\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on client errors (4xx) except 429 (rate limit)\n if (error instanceof Error && error.message.includes(\"HTTP 4\")) {\n if (!error.message.includes(\"HTTP 429\")) {\n throw error;\n }\n }\n\n if (attempt < retryOptions.attempts) {\n const delay =\n retryOptions.delay * Math.pow(retryOptions.backoff, attempt - 1);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError!;\n }\n\n private getFromCache<T>(key: string): T | null {\n const entry = this.cache.get(key);\n\n if (!entry) {\n return null;\n }\n\n if (Date.now() - entry.timestamp > entry.ttl) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.data;\n }\n\n private setCache<T>(key: string, data: T, ttl: number): void {\n this.cache.set(key, {\n data,\n timestamp: Date.now(),\n ttl,\n });\n }\n\n /**\n * Cleanup method - should be called when SDK is no longer needed\n */\n public destroy(): void {\n this.stopPulling();\n this.stateListeners.clear();\n this.cache.clear();\n }\n}\n","import React, { createContext, useContext, ReactNode } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { FlipFlagConfig } from \"../types\";\n\ninterface FeatureFlagContextValue {\n sdk: FlipFlagSDK;\n config: FlipFlagConfig;\n}\n\nconst FeatureFlagContext = createContext<FeatureFlagContextValue | null>(null);\n\ninterface FeatureFlagProviderProps {\n children: ReactNode;\n config: FlipFlagConfig;\n}\n\nexport function FeatureFlagProvider({\n children,\n config,\n}: FeatureFlagProviderProps) {\n const sdk = new FlipFlagSDK(config);\n\n const contextValue: FeatureFlagContextValue = {\n sdk,\n config,\n };\n\n return (\n <FeatureFlagContext.Provider value={contextValue}>\n {children}\n </FeatureFlagContext.Provider>\n );\n}\n\nexport function useFeatureFlagContext(): FeatureFlagContextValue {\n const context = useContext(FeatureFlagContext);\n\n if (!context) {\n throw new Error(\n \"useFeatureFlagContext must be used within a FeatureFlagProvider\"\n );\n }\n\n return context;\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { FeatureFlagValue, FlipFlagConfig } from \"../types\";\nimport { FeatureFlagHookResult } from \"./types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\ninterface UseFeatureFlagOptions {\n fallbackValue?: FeatureFlagValue;\n enabled?: boolean;\n}\n\nexport function useFeatureFlag(\n flagName: string,\n options: UseFeatureFlagOptions & { config?: FlipFlagConfig } = {}\n): FeatureFlagHookResult {\n const [value, setValue] = useState<FeatureFlagValue>(\n options.fallbackValue ?? false\n );\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Try to get SDK from context, otherwise create new instance\n let sdk: FlipFlagSDK;\n try {\n const context = useFeatureFlagContext();\n sdk = context.sdk;\n } catch {\n if (!options.config) {\n throw new Error(\n \"useFeatureFlag must be used within FeatureFlagProvider or config must be provided\"\n );\n }\n sdk = new FlipFlagSDK(options.config);\n }\n\n const updateFromState = useCallback(() => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n try {\n const flagValue = sdk.getFlagValue(flagName);\n setValue(flagValue);\n setLoading(false);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n if (options.fallbackValue !== undefined) {\n setValue(options.fallbackValue);\n }\n setLoading(false);\n }\n }, [sdk, flagName, options.fallbackValue, options.enabled]);\n\n const refetch = useCallback(async () => {\n sdk.clearCache(\n `flag:${sdk[\"config\"].projectId}:${flagName}:${sdk[\"config\"].environment || \"all\"}`\n );\n setLoading(true);\n\n try {\n const response = await sdk.getFlag(flagName);\n setValue(response.value);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n if (options.fallbackValue !== undefined) {\n setValue(options.fallbackValue);\n }\n } finally {\n setLoading(false);\n }\n }, [sdk, flagName, options.fallbackValue]);\n\n useEffect(() => {\n // Subscribe to state changes\n const unsubscribe = sdk.subscribe((state) => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n const flagValue = state.flags[flagName];\n if (flagValue !== undefined) {\n setValue(flagValue);\n setLoading(false);\n setError(state.error);\n }\n });\n\n // Initial update from current state\n updateFromState();\n\n return unsubscribe;\n }, [updateFromState, options.enabled]);\n\n return {\n value,\n loading,\n error,\n refetch,\n };\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { FeatureFlagValue, FlipFlagConfig } from \"../types\";\nimport { FeatureFlagsHookResult } from \"./types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\ninterface UseFeatureFlagsOptions {\n fallbackValues?: Record<string, FeatureFlagValue>;\n enabled?: boolean;\n}\n\nexport function useFeatureFlags(\n flagNames: string[],\n options: UseFeatureFlagsOptions & { config?: FlipFlagConfig } = {}\n): FeatureFlagsHookResult {\n const [flags, setFlags] = useState<Record<string, FeatureFlagValue>>(() => {\n // Initialize with fallback values\n const initialFlags: Record<string, FeatureFlagValue> = {};\n flagNames.forEach((flagName) => {\n initialFlags[flagName] = options.fallbackValues?.[flagName] ?? false;\n });\n return initialFlags;\n });\n\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Try to get SDK from context, otherwise create new instance\n let sdk: FlipFlagSDK;\n try {\n const context = useFeatureFlagContext();\n sdk = context.sdk;\n } catch {\n if (!options.config) {\n throw new Error(\n \"useFeatureFlags must be used within FeatureFlagProvider or config must be provided\"\n );\n }\n sdk = new FlipFlagSDK(options.config);\n }\n\n const updateFromState = useCallback(() => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n try {\n const newFlags: Record<string, FeatureFlagValue> = { ...flags };\n let hasChanges = false;\n\n flagNames.forEach((flagName) => {\n const flagValue = sdk.getFlagValue(flagName);\n if (newFlags[flagName] !== flagValue) {\n newFlags[flagName] = flagValue;\n hasChanges = true;\n }\n });\n\n if (hasChanges) {\n setFlags(newFlags);\n }\n\n setLoading(false);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n // Use fallback values\n const fallbackFlags: Record<string, FeatureFlagValue> = {};\n flagNames.forEach((flagName) => {\n fallbackFlags[flagName] = options.fallbackValues?.[flagName] ?? false;\n });\n setFlags(fallbackFlags);\n setLoading(false);\n }\n }, [sdk, flagNames, options.fallbackValues, options.enabled, flags]);\n\n const refetch = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n // Force refresh by triggering pull\n await Promise.all(\n flagNames.map((flagName) =>\n sdk.getFlag(flagName).catch(() => {\n // Ignore individual flag errors, will use state values\n })\n )\n );\n\n updateFromState();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n\n // Use fallback values\n const fallbackFlags: Record<string, FeatureFlagValue> = {};\n flagNames.forEach((flagName) => {\n fallbackFlags[flagName] = options.fallbackValues?.[flagName] ?? false;\n });\n setFlags(fallbackFlags);\n setLoading(false);\n }\n }, [sdk, flagNames, options.fallbackValues, updateFromState]);\n\n useEffect(() => {\n // Subscribe to state changes\n const unsubscribe = sdk.subscribe((state) => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n const newFlags: Record<string, FeatureFlagValue> = { ...flags };\n let hasChanges = false;\n\n flagNames.forEach((flagName) => {\n const flagValue = state.flags[flagName];\n if (flagValue !== undefined && newFlags[flagName] !== flagValue) {\n newFlags[flagName] = flagValue;\n hasChanges = true;\n }\n });\n\n if (hasChanges) {\n setFlags(newFlags);\n }\n\n setLoading(false);\n setError(state.error);\n });\n\n // Initial update from current state\n updateFromState();\n\n return unsubscribe;\n }, [updateFromState, options.enabled]);\n\n return {\n flags,\n loading,\n error,\n refetch,\n };\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { FlipFlagSDK } from \"../core/FlipFlagSDK\";\nimport { ABTestValue, FlipFlagConfig } from \"../types\";\nimport { ABTestHookResult } from \"./types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\ninterface UseABTestOptions {\n userId: string;\n enabled?: boolean;\n}\n\nexport function useABTest(\n testName: string,\n options: UseABTestOptions & { config?: FlipFlagConfig }\n): ABTestHookResult {\n const [variant, setVariant] = useState<ABTestValue | null>(null);\n const [variantId, setVariantId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Try to get SDK from context, otherwise create new instance\n let sdk: FlipFlagSDK;\n try {\n const context = useFeatureFlagContext();\n sdk = context.sdk;\n } catch {\n if (!options.config) {\n throw new Error(\n \"useABTest must be used within FeatureFlagProvider or config must be provided\"\n );\n }\n sdk = new FlipFlagSDK(options.config);\n }\n\n const updateFromState = useCallback(() => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n try {\n const abTestVariant = sdk.getABTestVariant(testName);\n if (abTestVariant) {\n setVariant(abTestVariant.variant.value);\n setVariantId(abTestVariant.variantId);\n } else {\n setVariant(null);\n setVariantId(null);\n }\n\n setLoading(false);\n setError(null);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Unknown error\";\n setError(errorMessage);\n setVariant(null);\n setVariantId(null);\n setLoading(false);\n }\n }, [sdk, testName, options.enabled]);\n\n const recordEvent = useCallback(\n async (event: string, eventData?: Record<string, any>) => {\n if (!variantId) {\n console.warn(\"Cannot record event: no variant assigned yet\");\n return;\n }\n\n try {\n await sdk.recordAbTestEvent(\n testName,\n options.userId,\n event,\n variantId,\n eventData\n );\n } catch (err) {\n console.error(\"Failed to record A/B test event:\", err);\n }\n },\n [sdk, testName, options.userId, variantId]\n );\n\n useEffect(() => {\n // Subscribe to state changes\n const unsubscribe = sdk.subscribe((state) => {\n if (!options.enabled && options.enabled !== undefined) {\n return;\n }\n\n const abTestVariant = state.abTests[testName];\n if (abTestVariant) {\n setVariant(abTestVariant.variant.value);\n setVariantId(abTestVariant.variantId);\n } else {\n setVariant(null);\n setVariantId(null);\n }\n\n setLoading(false);\n setError(state.error);\n });\n\n // Initial update from current state\n updateFromState();\n\n return unsubscribe;\n }, [updateFromState, options.enabled]);\n\n return {\n variant,\n variantId,\n loading,\n error,\n recordEvent,\n };\n}\n","import { IdentifyUserOptions } from \"../types\";\nimport { useFeatureFlagContext } from \"./FeatureFlagProvider\";\n\n/**\n * Identify user for A/B testing and user-specific flags\n * Must be called within FeatureFlagProvider\n */\nexport function identifyUser(options: IdentifyUserOptions): void {\n const context = useFeatureFlagContext();\n context.sdk.identifyUser(options);\n}\n","import AsyncStorage from \"@react-native-async-storage/async-storage\";\nimport { OfflineStorage } from \"./types\";\n\n/**\n * Create offline storage using AsyncStorage\n */\nexport function createOfflineStorage(): OfflineStorage {\n return {\n async getItem(key: string): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(key);\n } catch (error) {\n console.error(\"AsyncStorage getItem error:\", error);\n return null;\n }\n },\n\n async setItem(key: string, value: string): Promise<void> {\n try {\n await AsyncStorage.setItem(key, value);\n } catch (error) {\n console.error(\"AsyncStorage setItem error:\", error);\n }\n },\n\n async removeItem(key: string): Promise<void> {\n try {\n await AsyncStorage.removeItem(key);\n } catch (error) {\n console.error(\"AsyncStorage removeItem error:\", error);\n }\n },\n };\n}\n\n/**\n * Create offline storage with custom storage implementation\n */\nexport function createCustomOfflineStorage(\n storage: OfflineStorage\n): OfflineStorage {\n return storage;\n}\n"],"names":["_jsx"],"mappings":"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"}
package/dist/react.js CHANGED
@@ -8,6 +8,9 @@ class FlipFlagSDK {
8
8
  this.cache = new Map();
9
9
  this.defaultBaseUrl = "https://app.flipflag.ru";
10
10
  this.stateListeners = new Set();
11
+ this.maxListeners = 100; // Maximum number of listeners to prevent memory leaks
12
+ // Validate required configuration
13
+ this.validateConfig(config);
11
14
  this.config = {
12
15
  baseUrl: this.defaultBaseUrl,
13
16
  cacheTimeout: 30000, // 30 seconds
@@ -32,6 +35,15 @@ class FlipFlagSDK {
32
35
  * Identify user for A/B testing and user-specific flags
33
36
  */
34
37
  identifyUser(options) {
38
+ if (!options || typeof options !== "object") {
39
+ throw new Error("options must be an object");
40
+ }
41
+ if (!options.userId || typeof options.userId !== "string") {
42
+ throw new Error("userId is required and must be a string");
43
+ }
44
+ if (options.userProperties && typeof options.userProperties !== "object") {
45
+ throw new Error("userProperties must be an object");
46
+ }
35
47
  this.config.userId = options.userId;
36
48
  // Clear A/B test cache since user changed
37
49
  this.clearABTestCache();
@@ -50,6 +62,9 @@ class FlipFlagSDK {
50
62
  * Subscribe to state changes
51
63
  */
52
64
  subscribe(callback) {
65
+ if (this.stateListeners.size >= this.maxListeners) {
66
+ console.warn(`Maximum number of listeners (${this.maxListeners}) reached. This may cause memory leaks.`);
67
+ }
53
68
  this.stateListeners.add(callback);
54
69
  // Return unsubscribe function
55
70
  return () => {
@@ -160,6 +175,8 @@ class FlipFlagSDK {
160
175
  }
161
176
  catch (error) {
162
177
  console.error("State listener error:", error);
178
+ // Remove faulty listener to prevent repeated errors
179
+ this.stateListeners.delete(callback);
163
180
  }
164
181
  });
165
182
  }
@@ -224,6 +241,15 @@ class FlipFlagSDK {
224
241
  */
225
242
  async getFlag(flagName, projectId = this.config.projectId, environment) {
226
243
  var _a, _b;
244
+ if (!flagName || typeof flagName !== "string") {
245
+ throw new Error("flagName is required and must be a string");
246
+ }
247
+ if (!projectId || typeof projectId !== "string") {
248
+ throw new Error("projectId must be a string");
249
+ }
250
+ if (environment && typeof environment !== "string") {
251
+ throw new Error("environment must be a string");
252
+ }
227
253
  // If we have the flag in state, return it immediately
228
254
  if (this.state.flags[flagName] !== undefined) {
229
255
  return {
@@ -235,20 +261,18 @@ class FlipFlagSDK {
235
261
  };
236
262
  }
237
263
  // Check if we're currently loading data (pullData in progress)
238
- // In this case, wait a bit and check state again
264
+ // In this case, wait for loading to complete using Promise
239
265
  if (this.state.isLoading) {
240
- // Wait up to 5 seconds for loading to complete
241
- for (let i = 0; i < 50; i++) {
242
- await new Promise((resolve) => setTimeout(resolve, 100));
243
- if (!this.state.isLoading && this.state.flags[flagName] !== undefined) {
244
- return {
245
- projectId: this.config.projectId,
246
- flagName,
247
- environment: this.config.environment || "all",
248
- value: this.state.flags[flagName],
249
- timestamp: ((_b = this.state.lastFetch) === null || _b === void 0 ? void 0 : _b.toISOString()) || new Date().toISOString(),
250
- };
251
- }
266
+ await this.waitForLoadingComplete();
267
+ // After waiting, check state again
268
+ if (this.state.flags[flagName] !== undefined) {
269
+ return {
270
+ projectId: this.config.projectId,
271
+ flagName,
272
+ environment: this.config.environment || "all",
273
+ value: this.state.flags[flagName],
274
+ timestamp: ((_b = this.state.lastFetch) === null || _b === void 0 ? void 0 : _b.toISOString()) || new Date().toISOString(),
275
+ };
252
276
  }
253
277
  }
254
278
  const cacheKey = `flag:${projectId}:${flagName}:${environment || "all"}`;
@@ -264,10 +288,76 @@ class FlipFlagSDK {
264
288
  this.setCache(cacheKey, response, this.config.cacheTimeout);
265
289
  return response;
266
290
  }
291
+ /**
292
+ * Validate configuration
293
+ */
294
+ validateConfig(config) {
295
+ if (!config.apiKey || typeof config.apiKey !== "string") {
296
+ throw new Error("apiKey is required and must be a string");
297
+ }
298
+ if (!config.projectId || typeof config.projectId !== "string") {
299
+ throw new Error("projectId is required and must be a string");
300
+ }
301
+ if (config.baseUrl && typeof config.baseUrl !== "string") {
302
+ throw new Error("baseUrl must be a string");
303
+ }
304
+ if (config.environment && typeof config.environment !== "string") {
305
+ throw new Error("environment must be a string");
306
+ }
307
+ if (config.userId && typeof config.userId !== "string") {
308
+ throw new Error("userId must be a string");
309
+ }
310
+ if (config.cacheTimeout &&
311
+ (typeof config.cacheTimeout !== "number" || config.cacheTimeout < 0)) {
312
+ throw new Error("cacheTimeout must be a non-negative number");
313
+ }
314
+ if (config.retryAttempts &&
315
+ (typeof config.retryAttempts !== "number" || config.retryAttempts < 0)) {
316
+ throw new Error("retryAttempts must be a non-negative number");
317
+ }
318
+ if (config.retryDelay &&
319
+ (typeof config.retryDelay !== "number" || config.retryDelay < 0)) {
320
+ throw new Error("retryDelay must be a non-negative number");
321
+ }
322
+ if (config.pullInterval &&
323
+ (typeof config.pullInterval !== "number" || config.pullInterval < 0)) {
324
+ throw new Error("pullInterval must be a non-negative number");
325
+ }
326
+ }
327
+ /**
328
+ * Wait for loading to complete with timeout
329
+ */
330
+ async waitForLoadingComplete(timeout = 5000) {
331
+ const startTime = Date.now();
332
+ return new Promise((resolve, reject) => {
333
+ const checkLoading = () => {
334
+ if (!this.state.isLoading) {
335
+ resolve();
336
+ return;
337
+ }
338
+ if (Date.now() - startTime > timeout) {
339
+ reject(new Error("Timeout waiting for SDK loading to complete"));
340
+ return;
341
+ }
342
+ // Check again after a short delay
343
+ setTimeout(checkLoading, 50);
344
+ };
345
+ checkLoading();
346
+ });
347
+ }
267
348
  /**
268
349
  * Get A/B test variant for a user
269
350
  */
270
351
  async getAbTestVariant(testName, userId, projectId = this.config.projectId) {
352
+ if (!testName || typeof testName !== "string") {
353
+ throw new Error("testName is required and must be a string");
354
+ }
355
+ if (!userId || typeof userId !== "string") {
356
+ throw new Error("userId is required and must be a string");
357
+ }
358
+ if (!projectId || typeof projectId !== "string") {
359
+ throw new Error("projectId must be a string");
360
+ }
271
361
  // If we have the A/B test in state, return it immediately
272
362
  const stateVariant = this.state.abTests[testName];
273
363
  if (stateVariant && stateVariant.testName === testName) {
@@ -331,6 +421,34 @@ class FlipFlagSDK {
331
421
  this.cache.clear();
332
422
  }
333
423
  }
424
+ /**
425
+ * Clear cache for specific flag
426
+ */
427
+ clearFlagCache(flagName, environment) {
428
+ const cacheKey = `flag:${this.config.projectId}:${flagName}:${environment || "all"}`;
429
+ this.cache.delete(cacheKey);
430
+ }
431
+ /**
432
+ * Clear cache for all flags
433
+ */
434
+ clearFlagsCache(environment) {
435
+ const cacheKey = `flags:${this.config.projectId}:${environment || "all"}`;
436
+ this.cache.delete(cacheKey);
437
+ }
438
+ /**
439
+ * Clear cache for A/B test variant
440
+ */
441
+ clearABTestCache(testName, userId) {
442
+ if (testName && userId) {
443
+ const cacheKey = `abtest:${this.config.projectId}:${testName}:${userId}`;
444
+ this.cache.delete(cacheKey);
445
+ }
446
+ else {
447
+ // Clear all A/B test cache
448
+ const abTestKeys = Array.from(this.cache.keys()).filter((key) => key.startsWith("abtest:"));
449
+ abTestKeys.forEach((key) => this.cache.delete(key));
450
+ }
451
+ }
334
452
  /**
335
453
  * Update configuration
336
454
  */
@@ -439,17 +557,18 @@ function useFeatureFlag(flagName, options = {}) {
439
557
  const [loading, setLoading] = react.useState(true);
440
558
  const [error, setError] = react.useState(null);
441
559
  // Try to get SDK from context, otherwise create new instance
442
- let sdk;
443
- try {
444
- const context = useFeatureFlagContext();
445
- sdk = context.sdk;
446
- }
447
- catch (_b) {
448
- if (!options.config) {
449
- throw new Error("useFeatureFlag must be used within FeatureFlagProvider or config must be provided");
560
+ const sdk = react.useMemo(() => {
561
+ try {
562
+ const context = useFeatureFlagContext();
563
+ return context.sdk;
450
564
  }
451
- sdk = new FlipFlagSDK(options.config);
452
- }
565
+ catch (_a) {
566
+ if (!options.config) {
567
+ throw new Error("useFeatureFlag must be used within FeatureFlagProvider or config must be provided");
568
+ }
569
+ return new FlipFlagSDK(options.config);
570
+ }
571
+ }, [options.config]);
453
572
  const updateFromState = react.useCallback(() => {
454
573
  if (!options.enabled && options.enabled !== undefined) {
455
574
  return;
@@ -526,6 +645,27 @@ function useFeatureFlag(flagName, options = {}) {
526
645
  };
527
646
  }
528
647
 
648
+ /**
649
+ * Wait for SDK loading to complete with timeout
650
+ */
651
+ function waitForSDKLoading(sdk, timeout = 5000) {
652
+ const startTime = Date.now();
653
+ return new Promise((resolve, reject) => {
654
+ const checkLoading = () => {
655
+ if (!sdk.getState().isLoading) {
656
+ resolve();
657
+ return;
658
+ }
659
+ if (Date.now() - startTime > timeout) {
660
+ reject(new Error("Timeout waiting for SDK loading to complete"));
661
+ return;
662
+ }
663
+ // Check again after a short delay
664
+ setTimeout(checkLoading, 50);
665
+ };
666
+ checkLoading();
667
+ });
668
+ }
529
669
  function useFeatureFlags(flagNames, options = {}) {
530
670
  const [flags, setFlags] = react.useState(() => {
531
671
  // Initialize with fallback values
@@ -540,17 +680,18 @@ function useFeatureFlags(flagNames, options = {}) {
540
680
  const [error, setError] = react.useState(null);
541
681
  const [isInitialized, setIsInitialized] = react.useState(false);
542
682
  // Try to get SDK from context, otherwise create new instance
543
- let sdk;
544
- try {
545
- const context = useFeatureFlagContext();
546
- sdk = context.sdk;
547
- }
548
- catch (_a) {
549
- if (!options.config) {
550
- throw new Error("useFeatureFlags must be used within FeatureFlagProvider or config must be provided");
683
+ const sdk = react.useMemo(() => {
684
+ try {
685
+ const context = useFeatureFlagContext();
686
+ return context.sdk;
551
687
  }
552
- sdk = new FlipFlagSDK(options.config);
553
- }
688
+ catch (_a) {
689
+ if (!options.config) {
690
+ throw new Error("useFeatureFlags must be used within FeatureFlagProvider or config must be provided");
691
+ }
692
+ return new FlipFlagSDK(options.config);
693
+ }
694
+ }, [options.config]);
554
695
  const fetchFlags = react.useCallback(async () => {
555
696
  if (!options.enabled && options.enabled !== undefined) {
556
697
  return;
@@ -582,30 +723,29 @@ function useFeatureFlags(flagNames, options = {}) {
582
723
  }
583
724
  // If SDK is currently loading, wait for it to complete
584
725
  if (sdk.getState().isLoading) {
585
- // Wait up to 5 seconds for loading to complete
586
- for (let i = 0; i < 50; i++) {
587
- await new Promise((resolve) => setTimeout(resolve, 100));
588
- const currentState = sdk.getState();
589
- if (!currentState.isLoading) {
590
- // Check again if we now have all flags
591
- const updatedStateFlags = {};
592
- let updatedHasAllFlags = true;
593
- flagNames.forEach((flagName) => {
594
- const stateValue = sdk.getFlagValue(flagName);
595
- if (stateValue !== undefined) {
596
- updatedStateFlags[flagName] = stateValue;
597
- }
598
- else {
599
- updatedHasAllFlags = false;
600
- }
601
- });
602
- if (updatedHasAllFlags) {
603
- setFlags(updatedStateFlags);
604
- setLoading(false);
605
- return;
726
+ try {
727
+ await waitForSDKLoading(sdk);
728
+ // Check again if we now have all flags
729
+ const updatedStateFlags = {};
730
+ let updatedHasAllFlags = true;
731
+ flagNames.forEach((flagName) => {
732
+ const stateValue = sdk.getFlagValue(flagName);
733
+ if (stateValue !== undefined) {
734
+ updatedStateFlags[flagName] = stateValue;
606
735
  }
736
+ else {
737
+ updatedHasAllFlags = false;
738
+ }
739
+ });
740
+ if (updatedHasAllFlags) {
741
+ setFlags(updatedStateFlags);
742
+ setLoading(false);
743
+ return;
607
744
  }
608
745
  }
746
+ catch (error) {
747
+ console.warn("Timeout waiting for SDK loading, proceeding with API call");
748
+ }
609
749
  }
610
750
  // If we still don't have all flags, make HTTP request
611
751
  const response = await sdk.getFlags();
@@ -648,7 +788,7 @@ function useFeatureFlags(flagNames, options = {}) {
648
788
  }, [sdk, fetchFlags]);
649
789
  react.useEffect(() => {
650
790
  fetchFlags();
651
- }, []); // Remove fetchFlags dependency to prevent infinite loop
791
+ }, [fetchFlags]); // Include fetchFlags dependency
652
792
  // Subscribe to state changes for automatic updates
653
793
  react.useEffect(() => {
654
794
  const unsubscribe = sdk.subscribe((state) => {
@@ -689,17 +829,18 @@ function useABTest(testName, options) {
689
829
  const [loading, setLoading] = react.useState(true);
690
830
  const [error, setError] = react.useState(null);
691
831
  // Try to get SDK from context, otherwise create new instance
692
- let sdk;
693
- try {
694
- const context = useFeatureFlagContext();
695
- sdk = context.sdk;
696
- }
697
- catch (_a) {
698
- if (!options.config) {
699
- throw new Error("useABTest must be used within FeatureFlagProvider or config must be provided");
832
+ const sdk = react.useMemo(() => {
833
+ try {
834
+ const context = useFeatureFlagContext();
835
+ return context.sdk;
700
836
  }
701
- sdk = new FlipFlagSDK(options.config);
702
- }
837
+ catch (_a) {
838
+ if (!options.config) {
839
+ throw new Error("useABTest must be used within FeatureFlagProvider or config must be provided");
840
+ }
841
+ return new FlipFlagSDK(options.config);
842
+ }
843
+ }, [options.config]);
703
844
  const fetchVariant = react.useCallback(async () => {
704
845
  if (!options.enabled && options.enabled !== undefined) {
705
846
  return;