{"version":3,"file":"unleash-react.umd.cjs","names":[],"sources":["../src/FlagContext.ts","../src/FlagProvider.tsx","../src/useFlagContext.ts","../src/useUnleashClientSubscription.ts","../src/useFlag.ts","../src/variantsAreEqual.ts","../src/useFlags.ts","../src/useFlagsStatus.ts","../src/useVariant.ts","../src/useUnleashContext.ts","../src/useUnleashClient.ts","../src/index.ts"],"sourcesContent":["import React from 'react';\nimport type { UnleashClient } from 'unleash-proxy-client';\n\nexport interface IFlagContextValue\n  extends Pick<\n    UnleashClient,\n    'on' | 'off' | 'updateContext' | 'isEnabled' | 'getVariant'\n  > {\n  client: UnleashClient;\n  flagsReady: boolean;\n  setFlagsReady: React.Dispatch<\n    React.SetStateAction<IFlagContextValue['flagsReady']>\n  >;\n  flagsError: any;\n  setFlagsError: React.Dispatch<\n    React.SetStateAction<IFlagContextValue['flagsError']>\n  >;\n}\n\nconst FlagContext = React.createContext<IFlagContextValue | null>(null);\n\nexport default FlagContext;\n","/** @format */\n\nimport React, { type FC, type PropsWithChildren, useEffect, useMemo, useState } from 'react';\nimport { type IConfig, IMutableContext, UnleashClient } from 'unleash-proxy-client';\nimport FlagContext, { type IFlagContextValue } from './FlagContext';\n\nexport interface IFlagProvider {\n  config?: IConfig;\n  unleashClient?: UnleashClient;\n  startClient?: boolean;\n  stopClient?: boolean;\n  startTransition?: (fn: () => void) => void;\n}\n\nconst offlineConfig: IConfig = {\n  bootstrap: [],\n  disableRefresh: true,\n  disableMetrics: true,\n  url: 'http://localhost',\n  appName: 'offline',\n  clientKey: 'not-used',\n};\n\n// save startTransition as var to avoid webpack analysis (https://github.com/webpack/webpack/issues/14814)\nconst _startTransition = 'startTransition';\n// fallback for React <18 which doesn't support startTransition\n// Fallback for React <18 and exclude startTransition if in React Native\nconst defaultStartTransition = React[_startTransition] || (fn => fn());\n\nconst FlagProvider: FC<PropsWithChildren<IFlagProvider>> = ({\n  config: customConfig,\n  children,\n  unleashClient,\n  startClient = true,\n  stopClient = true,\n  startTransition = defaultStartTransition\n}) => {\n  const config = customConfig || offlineConfig;\n  const client = React.useRef<UnleashClient>(\n    unleashClient || new UnleashClient(config)\n  );\n  const [flagsReady, setFlagsReady] = React.useState(\n    Boolean(\n      unleashClient\n        ? (customConfig?.bootstrap && customConfig?.bootstrapOverride !== false) || unleashClient.isReady?.()\n        : config.bootstrap && config.bootstrapOverride !== false\n    )\n  );\n  const [flagsError, setFlagsError] = useState(client.current.getError?.() || null);\n\n  useEffect(() => {\n    if (!config && !unleashClient) {\n      console.error(\n        `You must provide either a config or an unleash client to the flag provider.\n        If you are initializing the client in useEffect, you can avoid this warning\n        by checking if the client exists before rendering.`\n      );\n    }\n\n    const errorCallback = (e: any) => {\n      startTransition(() => {\n        setFlagsError((currentError: any) => currentError || e);\n      });\n    };\n\n    const clearErrorCallback = (e: any) => {\n      startTransition(() => {\n        setFlagsError(null);\n      });\n    }\n\n    let timeout: ReturnType<typeof setTimeout> | null = null;\n    const readyCallback = () => {\n      // wait for flags to resolve after useFlag gets the same event\n      timeout = setTimeout(() => {\n        startTransition(() => {\n          setFlagsReady(true);\n        });\n      }, 0);\n    };\n\n    client.current.on('ready', readyCallback);\n    client.current.on('error', errorCallback);\n    client.current.on('recovered', clearErrorCallback);\n\n    if (startClient) {\n      // defensively stop the client first\n      client.current.stop();\n      // start the client\n      client.current.start();\n    }\n\n    // stop unleash client on unmount\n    return function cleanup() {\n      if (client.current) {\n        client.current.off('error', errorCallback);\n        client.current.off('ready', readyCallback);\n        client.current.off('recovered', clearErrorCallback);\n        if (stopClient) {\n          client.current.stop();\n        }\n      }\n      if (timeout) {\n        clearTimeout(timeout);\n      }\n    };\n  }, []);\n\n  const context = useMemo<IFlagContextValue>(\n    () => ({\n      on: (...args) => client.current.on(...args),\n      off: (...args) => client.current.off(...args),\n      isEnabled: (...args) => client.current.isEnabled(...args),\n      updateContext: async (...args) =>\n        await client.current.updateContext(...args),\n      getVariant: (...args) => client.current.getVariant(...args),\n      client: client.current,\n      flagsReady,\n      flagsError,\n      setFlagsReady,\n      setFlagsError,\n    }),\n    [flagsReady, flagsError]\n  );\n\n  return (\n    <FlagContext.Provider value={context}>{children}</FlagContext.Provider>\n  );\n};\n\nexport default FlagProvider;\n","import { useContext } from \"react\";\nimport FlagContext, { type IFlagContextValue } from \"./FlagContext\";\nimport type { UnleashClient } from \"unleash-proxy-client\";\n\nconst methods = {\n\ton: (event: string, callback: Function, ctx?: any): UnleashClient => {\n\t\tconsole.error(\"on() must be used within a FlagProvider\");\n\t\treturn mockUnleashClient;\n\t},\n\toff: (event: string, callback?: Function): UnleashClient => {\n\t\tconsole.error(\"off() must be used within a FlagProvider\");\n\t\treturn mockUnleashClient;\n\t},\n\tupdateContext: async () => {\n\t\tconsole.error(\"updateContext() must be used within a FlagProvider\");\n\t\treturn undefined;\n\t},\n\tisEnabled: () => {\n\t\tconsole.error(\"isEnabled() must be used within a FlagProvider\");\n\t\treturn false;\n\t},\n\tgetVariant: () => {\n\t\tconsole.error(\"getVariant() must be used within a FlagProvider\");\n\t\treturn { name: \"disabled\", enabled: false };\n\t}\n};\n\nconst mockUnleashClient = {\n\t...methods,\n\ttoggles: [],\n\timpressionDataAll: {},\n\tcontext: {},\n\tstorage: {},\n\tstart: () => {},\n\tstop: () => {},\n\tisReady: () => false,\n\tgetError: () => null,\n\tgetAllToggles: () => []\n} as unknown as UnleashClient;\n\nconst defaultContextValue: IFlagContextValue = {\n\t...methods,\n\tclient: mockUnleashClient,\n\tflagsReady: false,\n\tsetFlagsReady: () => {\n\t\tconsole.error(\"setFlagsReady() must be used within a FlagProvider\");\n\t},\n\tflagsError: null,\n\tsetFlagsError: () => {\n\t\tconsole.error(\"setFlagsError() must be used within a FlagProvider\");\n\t}\n};\n\nexport function useFlagContext() {\n\tconst context = useContext(FlagContext);\n\tif (!context) {\n\t\tconsole.error(\"useFlagContext() must be used within a FlagProvider\");\n\t\treturn defaultContextValue;\n\t}\n\treturn context;\n}\n","import { useCallback } from 'react';\nimport type { UnleashClient } from 'unleash-proxy-client';\n\nconst useUnleashClientSubscription = (client?: UnleashClient) =>\n  useCallback(\n    (onStoreChange: () => void) => {\n      if (!client) return () => {};\n\n      client.on('update', onStoreChange);\n      client.on('ready', onStoreChange);\n\n      return () => {\n        client.off('update', onStoreChange);\n        client.off('ready', onStoreChange);\n      };\n    },\n    [client]\n  );\n\nexport default useUnleashClientSubscription;\n","import { useSyncExternalStore } from 'use-sync-external-store/shim';\nimport { useFlagContext } from './useFlagContext';\nimport useUnleashClientSubscription from './useUnleashClientSubscription';\n\nconst useFlag = (featureName: string): boolean => {\n  const { isEnabled, client } = useFlagContext();\n\n  const subscribeToUnleashClient = useUnleashClientSubscription(client);\n\n  const getFlagSnapshot = () => isEnabled(featureName);\n\n  return useSyncExternalStore(\n    subscribeToUnleashClient,\n    getFlagSnapshot,\n    getFlagSnapshot\n  );\n};\n\nexport default useFlag;\n","import type { IVariant } from 'unleash-proxy-client';\n\nconst variantsAreEqual = (\n  first?: IVariant,\n  second?: IVariant\n): boolean =>\n  first?.name === second?.name &&\n  first?.enabled === second?.enabled &&\n  first?.feature_enabled === second?.feature_enabled &&\n  first?.payload?.type === second?.payload?.type &&\n  first?.payload?.value === second?.payload?.value;\n\nexport default variantsAreEqual;\n","import { useCallback } from 'react';\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';\nimport type { IToggle } from 'unleash-proxy-client';\nimport { useFlagContext } from './useFlagContext';\nimport useUnleashClientSubscription from './useUnleashClientSubscription';\nimport variantsAreEqual from './variantsAreEqual';\n\nconst togglesAreEqual = (a: IToggle[], b: IToggle[]): boolean =>\n  a.length === b.length &&\n  a.every((toggle, index) => {\n    const other = b[index];\n    return (\n      Boolean(other) &&\n      toggle.name === other.name &&\n      toggle.enabled === other.enabled &&\n      variantsAreEqual(toggle.variant, other.variant)\n    );\n  });\n\nconst selectToggles = (toggles: IToggle[]) => toggles;\n\nconst useFlags = (): IToggle[] => {\n  const { client } = useFlagContext();\n\n  const subscribeToUnleashClient = useUnleashClientSubscription(client);\n\n  const getTogglesSnapshot = useCallback(\n    () => client?.getAllToggles() ?? [],\n    [client]\n  );\n\n  return useSyncExternalStoreWithSelector(\n    subscribeToUnleashClient,\n    getTogglesSnapshot,\n    getTogglesSnapshot,\n    selectToggles,\n    togglesAreEqual\n  );\n};\n\nexport default useFlags;\n","/** @format */\nimport { useFlagContext } from './useFlagContext';\n\nconst useFlagsStatus = () => {\n  const { flagsReady, flagsError } = useFlagContext();\n\n  return { flagsReady, flagsError };\n};\n\nexport default useFlagsStatus;\n","import { useCallback } from 'react';\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';\nimport { IVariant } from 'unleash-proxy-client';\nimport { useFlagContext } from './useFlagContext';\nimport useUnleashClientSubscription from './useUnleashClientSubscription';\nimport variantsAreEqual from './variantsAreEqual';\n\nconst selectVariant = (variant: IVariant) => variant;\n\nconst useVariant = (featureName: string): Partial<IVariant> => {\n  const { getVariant, client } = useFlagContext();\n\n  const subscribeToUnleashClient = useUnleashClientSubscription(client);\n\n  const getVariantSnapshot = useCallback(\n    () => getVariant(featureName),\n    [getVariant, featureName]\n  );\n\n  const variant = useSyncExternalStoreWithSelector(\n    subscribeToUnleashClient,\n    getVariantSnapshot,\n    getVariantSnapshot,\n    selectVariant,\n    variantsAreEqual\n  );\n\n  return variant || {};\n};\n\nexport default useVariant;\n","import { useFlagContext } from './useFlagContext';\n\nconst useUnleashContext = () => {\n  const { updateContext } = useFlagContext();\n\n  return updateContext;\n};\n\nexport default useUnleashContext;\n","import { useFlagContext } from './useFlagContext';\n\nconst useUnleashClient = () => {\n  const { client } = useFlagContext();\n  return client;\n};\n\nexport default useUnleashClient;\n","/** @format */\n\nexport type {\n  IConfig,\n  IContext,\n  IMutableContext,\n  IVariant,\n  IToggle,\n} from 'unleash-proxy-client';\nexport {\n  UnleashClient,\n  type IStorageProvider,\n  LocalStorageProvider,\n  InMemoryStorageProvider,\n} from 'unleash-proxy-client';\n\nimport FlagContext from './FlagContext';\nimport FlagProvider from './FlagProvider';\nimport useFlag from './useFlag';\nimport useFlags from './useFlags';\nimport useFlagsStatus from './useFlagsStatus';\nimport useVariant from './useVariant';\nimport useUnleashContext from './useUnleashContext';\nimport useUnleashClient from './useUnleashClient';\n\nimport { IFlagProvider } from './FlagProvider';\n\nexport {\n  FlagContext,\n  FlagProvider,\n  useFlag,\n  useFlags,\n  useFlagsStatus,\n  useVariant,\n  useUnleashContext,\n  useUnleashClient,\n};\n\nexport type { IFlagProvider };\n\nexport default FlagProvider;\n"],"mappings":"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"}