UNPKG

@launchdarkly/react-native-client-sdk

Version:
177 lines 8.85 kB
import { BasicLogger, createDefaultSourceFactoryProvider, createFDv2DataManagerBase, internal, LDClientImpl, MOBILE_DATA_SYSTEM_DEFAULTS, MOBILE_TRANSITION_TABLE, mobileFdv1Endpoints, MODE_TABLE, resolveForegroundMode, safeRegisterDebugOverridePlugins, } from '@launchdarkly/js-client-sdk-common'; import MobileDataManager from './MobileDataManager'; import validateOptions, { filterToBaseOptions } from './options'; import createPlatform from './platform'; import { ApplicationState, ConnectionManager, NetworkState, } from './platform/ConnectionManager'; import RNStateDetector from './RNStateDetector'; /** * The React Native LaunchDarkly client. Instantiate this class to create an * instance of the ReactNativeLDClient and pass it to the {@link LDProvider}. * * @example * ```tsx * const featureClient = new ReactNativeLDClient(MOBILE_KEY, AutoEnvAttributes.Enabled); * * <LDProvider client={featureClient}> * <Welcome /> * </LDProvider> * ``` */ function shouldAutoSwitchLifecycle(config) { var _a; if (config === true) { return true; } if (typeof config === 'object' && config.type === 'automatic') { return (_a = config.lifecycle) !== null && _a !== void 0 ? _a : true; } return false; } function shouldAutoSwitchNetwork(config) { var _a; if (config === true) { return true; } if (typeof config === 'object' && config.type === 'automatic') { return (_a = config.network) !== null && _a !== void 0 ? _a : true; } return false; } export default class ReactNativeLDClient extends LDClientImpl { /** * Creates an instance of the LaunchDarkly client. * * @param sdkKey The LaunchDarkly mobile key. * @param autoEnvAttributes Enable / disable Auto environment attributes. When enabled, the SDK will automatically * provide data about the mobile environment where the application is running. To learn more, * read [Automatic environment attributes](https://docs.launchdarkly.com/sdk/features/environment-attributes). * for more documentation. * @param options {@link LDOptions} to initialize the client with. */ constructor(sdkKey, autoEnvAttributes, options = {}) { var _a, _b; const { logger: customLogger, debug } = options; const logger = customLogger !== null && customLogger !== void 0 ? customLogger : new BasicLogger({ level: debug ? 'debug' : 'info', // eslint-disable-next-line no-console destination: console.log, }); const validatedRnOptions = validateOptions(options, logger); const internalOptions = { analyticsEventPath: `/mobile`, diagnosticEventPath: `/mobile/events/diagnostic`, highTimeoutThreshold: 15, getImplementationHooks: (_environmentMetadata) => internal.safeGetHooks(logger, _environmentMetadata, validatedRnOptions.plugins), registerDebugOverrides: (debugOverride) => safeRegisterDebugOverridePlugins(logger, debugOverride, validatedRnOptions.plugins), credentialType: 'mobileKey', dataSystemDefaults: MOBILE_DATA_SYSTEM_DEFAULTS, }; const platform = createPlatform(logger, options, validatedRnOptions.storage); const endpoints = mobileFdv1Endpoints(); const dataManagerFactory = (flagManager, configuration, baseHeaders, emitter, diagnosticsManager) => { var _a; if (configuration.dataSystem) { return createFDv2DataManagerBase({ platform, flagManager, credential: sdkKey, config: configuration, baseHeaders, emitter, transitionTable: MOBILE_TRANSITION_TABLE, foregroundMode: resolveForegroundMode(configuration.dataSystem, MOBILE_DATA_SYSTEM_DEFAULTS), backgroundMode: (_a = configuration.dataSystem.backgroundConnectionMode) !== null && _a !== void 0 ? _a : 'background', modeTable: MODE_TABLE, sourceFactoryProvider: createDefaultSourceFactoryProvider(), fdv1Endpoints: mobileFdv1Endpoints(), buildQueryParams: () => [], // Mobile uses Authorization header, not query params }); } return new MobileDataManager(platform, flagManager, sdkKey, configuration, validatedRnOptions, endpoints.polling, endpoints.streaming, baseHeaders, emitter, diagnosticsManager); }; super(sdkKey, autoEnvAttributes, platform, Object.assign(Object.assign({}, filterToBaseOptions(options)), { logger }), dataManagerFactory, internalOptions); if (this.isFDv2) { const fdv2DataManager = this.dataManager; this.setEventSendingEnabled(true, false); fdv2DataManager.setFlushCallback(() => this.flush()); // Wire state detection directly to FDv2 data manager using the // validated automaticModeSwitching config from the data system. const { automaticModeSwitching } = (_a = this.dataSystemConfig) !== null && _a !== void 0 ? _a : {}; const stateDetector = new RNStateDetector(); this._stateDetector = stateDetector; if (shouldAutoSwitchLifecycle(automaticModeSwitching)) { stateDetector.setApplicationStateListener((state) => { fdv2DataManager.setLifecycleState(state === ApplicationState.Foreground ? 'foreground' : 'background'); }); } if (shouldAutoSwitchNetwork(automaticModeSwitching)) { stateDetector.setNetworkStateListener((state) => { fdv2DataManager.setNetworkState(state === NetworkState.Available ? 'available' : 'unavailable'); }); } } else { const initialConnectionMode = (_b = options.initialConnectionMode) !== null && _b !== void 0 ? _b : 'streaming'; this.setEventSendingEnabled(initialConnectionMode !== 'offline', false); const dataManager = this.dataManager; const destination = { setNetworkAvailability: (available) => { dataManager.setNetworkAvailability(available); }, setEventSendingEnabled: (enabled, flush) => { this.setEventSendingEnabled(enabled, flush); }, setConnectionMode: async (mode) => { dataManager.setConnectionMode(mode); }, }; this._connectionManager = new ConnectionManager(logger, { initialConnectionMode, automaticNetworkHandling: validatedRnOptions.automaticNetworkHandling, automaticBackgroundHandling: validatedRnOptions.automaticBackgroundHandling, runInBackground: validatedRnOptions.runInBackground, }, destination, new RNStateDetector()); } internal.safeRegisterPlugins(logger, this.environmentMetadata, this, validatedRnOptions.plugins); } async close() { var _a, _b; (_a = this._stateDetector) === null || _a === void 0 ? void 0 : _a.stopListening(); (_b = this._connectionManager) === null || _b === void 0 ? void 0 : _b.close(); return super.close(); } async setConnectionMode(mode) { var _a, _b; if (this.isFDv2) { // FDv2 path if (mode !== undefined && !(mode in MODE_TABLE)) { this.logger.warn(`setConnectionMode called with invalid mode '${mode}'. ` + `Valid modes: ${Object.keys(MODE_TABLE).join(', ')}.`); return; } this.dataManager.setConnectionMode(mode); } else { // FDv1 path if (mode === undefined || mode === 'one-shot' || mode === 'background') { this.logger.warn(`setConnectionMode('${mode}') is only supported with the FDv2 data system (dataSystem option).`); return; } (_a = this._connectionManager) === null || _a === void 0 ? void 0 : _a.setConnectionMode(mode); (_b = this._connectionManager) === null || _b === void 0 ? void 0 : _b.setOffline(mode === 'offline'); } } getConnectionMode() { if (this.isFDv2) { return this.dataManager.getCurrentMode(); } return this.dataManager.getConnectionMode(); } isOffline() { if (this.isFDv2) { return this.dataManager.getCurrentMode() === 'offline'; } return this.dataManager.getConnectionMode() === 'offline'; } } //# sourceMappingURL=ReactNativeLDClient.js.map