options.fireExperimentExposure
is false.\n * @param experimentName\n */\n static manuallyLogExperimentExposure(experimentName) {\n statsig_js_lite_1.default.manuallyLogExperimentExposure(experimentName);\n }\n static shutdownStatsig() {\n statsig_js_lite_1.default.shutdown();\n }\n /**\n * Adds a new override for the given gate.\n *\n * This method is additive, meaning you can call it multiple times with different gate names to build\n * your full set of overrides.\n *\n * Overrides are persisted to the `STATSIG_JS_LITE_LOCAL_OVERRIDES` key in localStorage, so they will\n * continue to affect every client that is initialized on the same domain after this method is called.\n * If you are using this API for testing purposes, you should call ${@link clearGateOverride} after\n * your tests are completed to remove this localStorage entry.\n *\n * @param {string} gateName\n * @param {boolean} value\n */\n static overrideGate(gateName, value) {\n statsig_js_lite_1.default.overrideGate(gateName, value);\n }\n /**\n * Removes any overrides that have been set for the given gate.\n * @param {string} gateName\n */\n static clearGateOverride(gateName) {\n statsig_js_lite_1.default.overrideGate(gateName, null);\n }\n /**\n * Adds a new override for the given config (or experiment).\n *\n * This method is additive, meaning you can call it multiple times with different experiment names to build\n * your full set of overrides.\n *\n * Overrides are persisted to the `STATSIG_JS_LITE_LOCAL_OVERRIDES` key in localStorage, so they will\n * continue to affect every client that is initialized on the same domain after this method is called.\n * If you are using this API for testing purposes, you should call ${@link clearConfigOverride} after\n * your tests are completed to remove this localStorage entry.\n *\n * @param {string} experimentName\n * @param {object} values\n */\n static overrideConfig(experimentName, values) {\n statsig_js_lite_1.default.overrideConfig(experimentName, values);\n }\n /**\n * Removes any overrides that have been set for the given experiment.\n * @param {string} experimentName\n */\n static clearConfigOverride(experimentName) {\n statsig_js_lite_1.default.overrideConfig(experimentName, null);\n }\n /**\n * Set overrides for gates, experiments and layers in batch.\n *\n * Note that these overrides are **not** additive and will completely replace any that have been added\n * via prior calls to {@link overrideConfig} or {@link overrideGate}.\n *\n * Overrides are persisted to the `STATSIG_JS_LITE_LOCAL_OVERRIDES` key in localStorage, so they will\n * continue to affect every client that is initialized on the same domain after this method is called.\n * If you are using this API for testing purposes, you should call ${@link clearAllOverrides} after\n * your tests are completed to remove this localStorage entry.\n *\n * @param {object} overrides\n */\n static setOverrides(overrides) {\n statsig_js_lite_1.default.setOverrides(Object.assign({ gates: {}, configs: {}, layers: {} }, overrides));\n }\n /**\n * Clears overrides for all gates, configs (including experiments) and layers.\n */\n static clearAllOverrides() {\n statsig_js_lite_1.default.setOverrides(null);\n }\n /**\n * Returns whether the given identifiers and customAttributes align with the current\n * set that is being used by the client.\n *\n * If this method returns false, then the {@link updateUser} or {@link updateUserWithValues}\n * methods can be used to re-align these values.\n *\n * @param identifiers\n * @param customAttributes\n * @returns a flag indicating whether the clients current configuration aligns with the given values\n */\n static isCurrentUser(identifiers, customAttributes) {\n return (FeatureGates.shallowEquals(FeatureGates.currentIdentifiers, identifiers) &&\n FeatureGates.shallowEquals(FeatureGates.currentAttributes, customAttributes));\n }\n /**\n * This method initializes the client using a network call to fetch the bootstrap values for the given user.\n *\n * @param clientOptions\n * @param identifiers\n * @param customAttributes\n * @private\n */\n static async init(clientOptions, identifiers, customAttributes) {\n const fromValuesClientOptions = Object.assign(Object.assign({}, clientOptions), { disableCurrentPageLogging: true });\n let experimentValues;\n let customAttributesFromResult;\n try {\n // If client sdk key fetch fails, an error would be thrown and handled instead of waiting for the experiment\n // values request to be settled, and it will fall back to use default values.\n const clientSdkKeyPromise = fetcher_1.default.fetchClientSdk(clientOptions).then((value) => (fromValuesClientOptions.sdkKey = value.clientSdkKey));\n const experimentValuesPromise = fetcher_1.default.fetchExperimentValues(clientOptions, identifiers, customAttributes);\n // Only wait for the experiment values request to finish and try to initialise the client with experiment\n // values if both requests are successful. Else an error would be thrown and handled by the catch\n const [, experimentValuesResult] = await Promise.all([\n clientSdkKeyPromise,\n experimentValuesPromise\n ]);\n experimentValues = experimentValuesResult.experimentValues;\n customAttributesFromResult =\n experimentValuesResult.customAttributes;\n }\n catch (error) {\n if (error instanceof Error) {\n console.error(`Error occurred when trying to fetch the Feature Gates client values, error: ${error === null || error === void 0 ? void 0 : error.message}`);\n }\n console.warn(`Initialising Statsig client without values`);\n await FeatureGates.initFromValues(fromValuesClientOptions, identifiers, customAttributes);\n throw error;\n }\n await this.initFromValues(fromValuesClientOptions, identifiers, customAttributesFromResult, experimentValues);\n }\n /**\n * This method initializes the client using a set of boostrap values obtained from one of the server-side SDKs.\n *\n * @param clientOptions\n * @param identifiers\n * @param customAttributes\n * @param initializeValues\n * @private\n */\n static async initFromValues(clientOptions, identifiers, customAttributes, initializeValues = {}) {\n const user = this.toStatsigUser(identifiers, customAttributes);\n FeatureGates.currentIdentifiers = identifiers;\n FeatureGates.currentAttributes = customAttributes;\n if (!clientOptions.sdkKey) {\n clientOptions.sdkKey = DEFAULT_CLIENT_KEY;\n }\n if (!clientOptions.eventLoggingApi) {\n clientOptions.eventLoggingApi = DEFAULT_EVENT_LOGGING_API;\n }\n const { sdkKey } = clientOptions;\n const statsigOptions = this.toStatsigOptions(clientOptions, initializeValues);\n try {\n await statsig_js_lite_1.default.initialize(sdkKey, user, statsigOptions);\n }\n catch (error) {\n if (error instanceof Error) {\n console.error(`Error occurred when trying to initialise the Statsig client, error: ${error === null || error === void 0 ? void 0 : error.message}`);\n }\n console.warn(`Initialising Statsig client with default sdk key and without values`);\n await statsig_js_lite_1.default.initialize(DEFAULT_CLIENT_KEY, user, Object.assign(Object.assign({}, statsigOptions), { initializeValues: {} }));\n throw error;\n }\n }\n /**\n * This method creates an instance of StatsigUser from the given set of identifiers and attributes.\n *\n * @param identifiers\n * @param customAttributes\n * @private\n */\n static toStatsigUser(identifiers, customAttributes) {\n const user = {\n customIDs: identifiers,\n custom: customAttributes\n };\n if (identifiers.atlassianAccountId) {\n user.userID = identifiers.atlassianAccountId;\n }\n return user;\n }\n /**\n * This method updates the user for this client with the bootstrap values returned from a given Promise.\n * It uses the customAttributes from fetching experiment values to update the Statsig user but\n * uses the customAttributes from given input to check if the user has changed.\n *\n * @param identifiers\n * @param customAttributes\n * @param initializeValuesPromise\n * @private\n */\n static async updateUserUsingInitializeValuesProducer(getInitializeValues, identifiers, customAttributes) {\n if (!FeatureGates.initPromise) {\n throw new Error('The FeatureGates client must be initialized before you can update the user.');\n }\n // If the user isn't changing at all, then exit immediately\n if (FeatureGates.isCurrentUser(identifiers, customAttributes)) {\n return FeatureGates.initPromise;\n }\n // Wait for the current initialize/update to finish\n const originalInitPromise = FeatureGates.initPromise;\n try {\n await FeatureGates.initPromise;\n }\n catch (err) {\n // Proceed with the user update even if the init failed, since this update\n // may put the client back into a valid state.\n }\n const initializeValuesPromise = getInitializeValues();\n const updateUserPromise = FeatureGates.updateStatsigClientUser(initializeValuesPromise, identifiers, customAttributes);\n // We replace the init promise here since we are essentially re-initializing the client at this point.\n // Any subsequent calls to await FeatureGates.initialize() or FeatureGates.updateUser() will now also await this user update.\n FeatureGates.initPromise = updateUserPromise.catch(() => {\n // If the update failed then it changed nothing, so revert back to the original promise.\n FeatureGates.initPromise = originalInitPromise;\n });\n return updateUserPromise;\n }\n /**\n * This method updates the user on the nested Statsig client\n *\n * @param identifiers\n * @param customAttributes\n * @param initializeValuesPromise\n * @private\n */\n static async updateStatsigClientUser(initializeValuesPromise, identifiers, customAttributes) {\n var _a, _b;\n let initializeValues, user;\n try {\n initializeValues = await initializeValuesPromise;\n user = FeatureGates.toStatsigUser(identifiers, initializeValues.customAttributesFromFetch);\n }\n catch (err) {\n // Make sure the updateUserCompletionCallback is called for any errors in our custom code.\n // This is not necessary for the updateUserWithValues call, because the Statsig client will already invoke the callback itself.\n const errMsg = err instanceof Error ? err.message : JSON.stringify(err);\n (_b = (_a = FeatureGates.initOptions).updateUserCompletionCallback) === null || _b === void 0 ? void 0 : _b.call(_a, false, errMsg);\n throw err;\n }\n const success = statsig_js_lite_1.default.updateUserWithValues(user, initializeValues.experimentValues);\n if (success) {\n FeatureGates.currentIdentifiers = identifiers;\n FeatureGates.currentAttributes = customAttributes;\n }\n else {\n throw new Error('Failed to update user. An unexpected error occured.');\n }\n }\n /**\n * This method transforms the options given by the user into the format accepted by the Statsig client.\n *\n * @param options\n * @private\n */\n static toStatsigOptions(options, initializeValues) {\n const { \n // De-structured to remove from restClientOptions\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n sdkKey, \n // De-structured to remove from restClientOptions\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n updateUserCompletionCallback } = options, restClientOptions = __rest(options, [\"sdkKey\", \"updateUserCompletionCallback\"]);\n return Object.assign(Object.assign(Object.assign({}, restClientOptions), { initializeValues, environment: {\n tier: options.environment\n }, disableCurrentPageLogging: true }), (options.updateUserCompletionCallback && {\n updateUserCompletionCallback: FeatureGates.toStatsigUpdateUserCompletionCallback(options.updateUserCompletionCallback)\n }));\n }\n /**\n * This method transforms an UpdateUserCompletionCallback in our own format into the format accepted by the Statsig client.\n *\n * @param callback\n * @private\n */\n static toStatsigUpdateUserCompletionCallback(callback) {\n /**\n * The duration passed to the callback indicates how long the update took, but it is deceptive since it only times the\n * Statsig code and doesn't account for all of the extra custom work we do to obtain the bootstrap values.\n * As a result, we just suppress this parameter in our own callback rather than trying to keep it accurate.\n */\n return (_duration, success, message) => {\n callback(success, message);\n };\n }\n static shallowEquals(objectA, objectB) {\n if (!objectA && !objectB) {\n return true;\n }\n if (!objectA || !objectB) {\n return false;\n }\n const aEntries = Object.entries(objectA);\n const bEntries = Object.entries(objectB);\n if (aEntries.length !== bEntries.length) {\n return false;\n }\n const ascendingKeyOrder = ([key1], [key2]) => key1.localeCompare(key2);\n aEntries.sort(ascendingKeyOrder);\n bEntries.sort(ascendingKeyOrder);\n for (let i = 0; i < aEntries.length; i++) {\n const [, aValue] = aEntries[i];\n const [, bValue] = bEntries[i];\n if (aValue !== bValue) {\n return false;\n }\n }\n return true;\n }\n}\nFeatureGates.initPromise = null;\nFeatureGates.initCompleted = false;\nFeatureGates.hasGetExperimentErrorOccurred = false;\nFeatureGates.hasGetExperimentValueErrorOccurred = false;\nFeatureGates.hasCheckGateErrorOccurred = false;\nexports.default = FeatureGates;\n// This makes it possible to get a reference to the FeatureGates client at runtime.\n// This is important for overriding values in Cyprus tests, as there needs to be a\n// way to get the exact instance for a window in order to mock some of its methods.\nif (typeof window !== 'undefined') {\n window.__FEATUREGATES_JS__ = FeatureGates;\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FeatureGateEnvironment = void 0;\nvar FeatureGateEnvironment;\n(function (FeatureGateEnvironment) {\n FeatureGateEnvironment[\"Development\"] = \"development\";\n FeatureGateEnvironment[\"Staging\"] = \"staging\";\n FeatureGateEnvironment[\"Production\"] = \"production\";\n})(FeatureGateEnvironment || (exports.FeatureGateEnvironment = FeatureGateEnvironment = {}));\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CLIENT_VERSION = void 0;\nexports.CLIENT_VERSION = \"4.7.1\";\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FeatureGatesInitialization = void 0;\nconst react_1 = require(\"react\");\nconst feature_gate_js_client_1 = __importDefault(require(\"@atlassian/feature-gate-js-client\"));\nconst utils_1 = require(\"./utils\");\n/**\n * This component initializes the @atlassian/feature-flag-js-client by fetching the gate and experiment\n * evaluations for the given user, and blocks rendering of the children until the rendering is complete.\n */\nconst FeatureGatesInitialization = ({ children, enabled = true, identifiers, customAttributes, options, initializingComponent, overrides, onReady }) => {\n // Rather than checking the state of all overrides, we can just assume that if overrides are provided\n // then some sort of update will need to be performed, and hold off rendering until the useEffect is run.\n const [isInitialized, setInitialized] = (0, react_1.useState)(!overrides &&\n (0, utils_1.isClientAlreadyInCorrectState)(identifiers, customAttributes));\n // Use a ref for the options, so that we can use them within the following useEffect\n // without adding options as a dependency.\n // This avoids the user updating every time an option is changed.\n const optionsRef = (0, react_1.useRef)(options);\n (0, react_1.useEffect)(() => {\n optionsRef.current = options;\n }, [options]);\n (0, react_1.useEffect)(() => {\n if (enabled) {\n if ((0, utils_1.isClientAlreadyInCorrectState)(identifiers, customAttributes)) {\n (0, utils_1.applyOverrides)(overrides);\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady();\n }\n else {\n const initPromise = feature_gate_js_client_1.default.initializeCalled()\n ? feature_gate_js_client_1.default.updateUser(optionsRef.current, identifiers, customAttributes)\n : feature_gate_js_client_1.default.initialize(optionsRef.current, identifiers, customAttributes);\n void initPromise\n .then(() => (0, utils_1.applyOverrides)(overrides))\n .catch((err) => (0, utils_1.toError)(err))\n .then((err) => {\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady(err || undefined);\n });\n }\n }\n else {\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady();\n }\n return () => (0, utils_1.clearOverrides)(overrides);\n }, [enabled, identifiers, customAttributes, overrides]);\n return (0, utils_1.pickChildToRender)(enabled, isInitialized, children, initializingComponent);\n};\nexports.FeatureGatesInitialization = FeatureGatesInitialization;\nexports.default = exports.FeatureGatesInitialization;\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FeatureGatesInitializationWithDefaults = void 0;\nconst react_1 = require(\"react\");\nconst feature_gate_js_client_1 = __importDefault(require(\"@atlassian/feature-gate-js-client\"));\nconst utils_1 = require(\"./utils\");\n/**\n * This component initializes the @atlassian/feature-flag-js-client by fetching the gate and experiment\n * evaluations for the given user, and blocks rendering of the children until the rendering is complete.\n */\nconst FeatureGatesInitializationWithDefaults = ({ children, enabled = true, identifiers, customAttributes, options, overrides, onReady }) => {\n // Rather than checking the state of all overrides, we can just assume that if overrides are provided\n // then some sort of update will need to be performed, and hold off rendering until the useEffect is run.\n const [isInitialized, setInitialized] = (0, react_1.useState)(!overrides &&\n (0, utils_1.isClientAlreadyInCorrectState)(identifiers, customAttributes));\n // Use a ref for the options, so that we can use them within the following useEffect\n // without adding options as a dependency.\n // This avoids the user updating every time an option is changed.\n const optionsRef = (0, react_1.useRef)(options);\n (0, react_1.useEffect)(() => {\n optionsRef.current = options;\n }, [options]);\n (0, react_1.useEffect)(() => {\n if (enabled) {\n if ((0, utils_1.isClientAlreadyInCorrectState)(identifiers, customAttributes)) {\n (0, utils_1.applyOverrides)(overrides);\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady();\n }\n else {\n setInitialized(false);\n const initPromise = feature_gate_js_client_1.default.initializeCalled()\n ? feature_gate_js_client_1.default.updateUserWithValues(identifiers, customAttributes)\n : feature_gate_js_client_1.default.initializeFromValues(Object.assign({ sdkKey: 'client-default-key' }, (optionsRef.current || {})), identifiers, customAttributes);\n void initPromise\n .then(() => (0, utils_1.applyOverrides)(overrides))\n .catch((err) => (0, utils_1.toError)(err))\n .then((err) => {\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady(err || undefined);\n });\n }\n }\n else {\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady();\n }\n return () => (0, utils_1.clearOverrides)(overrides);\n }, [enabled, identifiers, customAttributes, overrides]);\n return (0, utils_1.pickChildToRender)(enabled, isInitialized, children);\n};\nexports.FeatureGatesInitializationWithDefaults = FeatureGatesInitializationWithDefaults;\nexports.default = exports.FeatureGatesInitializationWithDefaults;\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.FeatureGatesInitializationWithValues = void 0;\nconst react_1 = require(\"react\");\nconst feature_gate_js_client_1 = __importDefault(require(\"@atlassian/feature-gate-js-client\"));\nconst utils_1 = require(\"./utils\");\n/**\n * This component initializes the @atlassian/feature-flag-js-client by fetching the gate and experiment\n * evaluations for the given user, and blocks rendering of the children until the rendering is complete.\n */\nconst FeatureGatesInitializationWithValues = ({ children, enabled = true, identifiers, customAttributes, options, initializeValues, overrides, onReady }) => {\n // Rather than checking the state of all overrides, we can just assume that if overrides are provided\n // then some sort of update will need to be performed, and hold off rendering until the useEffect is run.\n const [isInitialized, setInitialized] = (0, react_1.useState)(!overrides &&\n (0, utils_1.isClientAlreadyInCorrectState)(identifiers, customAttributes));\n // Use a ref for the options, so that we can use them within the following useEffect\n // without adding options as a dependency.\n // This avoids the user updating every time an option is changed.\n const optionsRef = (0, react_1.useRef)(options);\n (0, react_1.useEffect)(() => {\n optionsRef.current = options;\n }, [options]);\n (0, react_1.useEffect)(() => {\n if (enabled) {\n if ((0, utils_1.isClientAlreadyInCorrectState)(identifiers, customAttributes)) {\n (0, utils_1.applyOverrides)(overrides);\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady();\n }\n else {\n setInitialized(false);\n const initPromise = feature_gate_js_client_1.default.initializeCalled()\n ? feature_gate_js_client_1.default.updateUserWithValues(identifiers, customAttributes, initializeValues)\n : feature_gate_js_client_1.default.initializeFromValues(optionsRef.current, identifiers, customAttributes, initializeValues);\n void initPromise\n .then(() => (0, utils_1.applyOverrides)(overrides))\n .catch((err) => (0, utils_1.toError)(err))\n .then((err) => {\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady(err || undefined);\n });\n }\n }\n else {\n setInitialized(true);\n onReady === null || onReady === void 0 ? void 0 : onReady();\n }\n return () => (0, utils_1.clearOverrides)(overrides);\n }, [enabled, identifiers, customAttributes, initializeValues, overrides]);\n return (0, utils_1.pickChildToRender)(enabled, isInitialized, children);\n};\nexports.FeatureGatesInitializationWithValues = FeatureGatesInitializationWithValues;\nexports.default = exports.FeatureGatesInitializationWithValues;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./FeatureGatesInitialization\"), exports);\n__exportStar(require(\"./FeatureGatesInitializationWithDefaults\"), exports);\n__exportStar(require(\"./FeatureGatesInitializationWithValues\"), exports);\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.clearOverrides = exports.applyOverrides = exports.toError = exports.pickChildToRender = exports.isClientAlreadyInCorrectState = void 0;\nconst react_1 = __importDefault(require(\"react\"));\nconst feature_gate_js_client_1 = __importDefault(require(\"@atlassian/feature-gate-js-client\"));\nlet hasWarnedAboutMissingOverrideSupport = false;\nfunction isClientAlreadyInCorrectState(identifiers, customAttributes) {\n var _a, _b;\n // If either of these methods don't exist (ie. if the product is using