react-native
Version:
A framework for building native apps using React
85 lines (71 loc) • 2.25 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import type {
ReactNativeFeatureFlagsJsOnly,
ReactNativeFeatureFlagsJsOnlyOverrides,
} from './ReactNativeFeatureFlags';
import NativeReactNativeFeatureFlags from './NativeReactNativeFeatureFlags';
const accessedFeatureFlags: Set<string> = new Set();
let overrides: ?ReactNativeFeatureFlagsJsOnlyOverrides;
export type Getter<T> = () => T;
function createGetter<T: boolean | number | string>(
configName: string,
customValueGetter: Getter<?T>,
defaultValue: T,
): Getter<T> {
let cachedValue: ?T;
return () => {
if (cachedValue == null) {
accessedFeatureFlags.add(configName);
cachedValue = customValueGetter() ?? defaultValue;
}
return cachedValue;
};
}
export function createJavaScriptFlagGetter<
K: $Keys<ReactNativeFeatureFlagsJsOnly>,
>(
configName: K,
defaultValue: ReturnType<ReactNativeFeatureFlagsJsOnly[K]>,
): Getter<ReturnType<ReactNativeFeatureFlagsJsOnly[K]>> {
return createGetter(
configName,
() => overrides?.[configName]?.(),
defaultValue,
);
}
type NativeFeatureFlags = $NonMaybeType<typeof NativeReactNativeFeatureFlags>;
export function createNativeFlagGetter<K: $Keys<NativeFeatureFlags>>(
configName: K,
defaultValue: ReturnType<$NonMaybeType<NativeFeatureFlags[K]>>,
): Getter<ReturnType<$NonMaybeType<NativeFeatureFlags[K]>>> {
return createGetter(
configName,
() => NativeReactNativeFeatureFlags?.[configName]?.(),
defaultValue,
);
}
export function getOverrides(): ?ReactNativeFeatureFlagsJsOnlyOverrides {
return overrides;
}
export function setOverrides(
newOverrides: ReactNativeFeatureFlagsJsOnlyOverrides,
): void {
if (overrides != null) {
throw new Error('Feature flags cannot be overridden more than once');
}
if (accessedFeatureFlags.size > 0) {
const accessedFeatureFlagsStr = Array.from(accessedFeatureFlags).join(', ');
throw new Error(
`Feature flags were accessed before being overridden: ${accessedFeatureFlagsStr}`,
);
}
overrides = newOverrides;
}