launchdarkly-react-client-sdk
Version:
LaunchDarkly SDK for React
367 lines (353 loc) • 16.1 kB
TypeScript
import * as launchdarkly_js_client_sdk from 'launchdarkly-js-client-sdk';
import { LDFlagSet, LDClient, LDContext, LDOptions } from 'launchdarkly-js-client-sdk';
export * from 'launchdarkly-js-client-sdk';
import * as React from 'react';
import React__default, { Component, PropsWithChildren, ReactNode } from 'react';
/**
* Controls the props the wrapped component receives from the `LDConsumer` HOC.
*/
interface ConsumerOptions {
/**
* If true then the wrapped component only receives the `ldClient` instance
* and nothing else.
*/
clientOnly: boolean;
reactContext?: React.Context<ReactSdkContext>;
}
/**
* The possible props the wrapped component can receive from the `LDConsumer` HOC.
*/
interface LDProps {
/**
* A map of feature flags from their keys to their values.
* Keys are camelCased using `lodash.camelcase`.
*/
flags?: LDFlagSet;
/**
* An instance of `LDClient` from the LaunchDarkly JS SDK (`launchdarkly-js-client-sdk`)
*
* @see https://docs.launchdarkly.com/sdk/client-side/javascript
*/
ldClient?: LDClient;
}
/**
* withLDConsumer is a function which accepts an optional options object and returns a function
* which accepts your React component. This function returns a HOC with flags
* and the ldClient instance injected via props.
*
* @param options - If you need only the `ldClient` instance and not flags, then set `{ clientOnly: true }`
* to only pass the ldClient prop to your component. Defaults to `{ clientOnly: false }`.
* @return A HOC with flags and the `ldClient` instance injected via props
*/
declare function withLDConsumer(options?: ConsumerOptions): <P>(WrappedComponent: React.ComponentType<P & LDProps>) => (props: P) => React.JSX.Element;
/**
* Initialization options for the LaunchDarkly React SDK. These are in addition to the options exposed
* by [[LDOptions]] which are common to both the JavaScript and React SDKs.
*/
interface LDReactOptions {
/**
* Whether the React SDK should transform flag keys into camel-cased format.
* Using camel-cased flag keys allow for easier use as prop values, however,
* these keys won't directly match the flag keys as known to LaunchDarkly.
* Consequently, flag key collisions may be possible and the Code References feature
* will not function properly.
*
* This is true by default, meaning that keys will automatically be converted to camel-case.
*
* For more information, see the React SDK Reference Guide on
* [flag keys](https://docs.launchdarkly.com/sdk/client-side/react/react-web#flag-keys).
*
* @see https://docs.launchdarkly.com/sdk/client-side/react/react-web#flag-keys
*/
useCamelCaseFlagKeys?: boolean;
/**
* Whether to send flag evaluation events when a flag is read from the `flags` object
* returned by the `useFlags` hook. This is true by default, meaning flag evaluation
* events will be sent by default.
*/
sendEventsOnFlagRead?: boolean;
/**
* The react context to use within the provider objects.
*/
reactContext?: React.Context<ReactSdkContext>;
}
/**
* Contains default values for the `reactOptions` object.
*/
declare const defaultReactOptions: {
useCamelCaseFlagKeys: boolean;
sendEventsOnFlagRead: boolean;
reactContext: React.Context<ReactSdkContext>;
};
/**
* Configuration object used to initialise LaunchDarkly's JS client.
*/
interface ProviderConfig {
/**
* Your project and environment specific client side ID. You can find
* this in your LaunchDarkly portal under Account settings. This is
* the only mandatory property required to use the React SDK.
*/
clientSideID: string;
/**
* A LaunchDarkly context object. If unspecified, an anonymous context
* with kind: 'user' will be created and used.
*/
context?: LDContext;
/**
* @deprecated The `user` property will be removed in a future version,
* please update your code to use context instead.
*/
user?: LDContext;
/**
* If set to true, the ldClient will not be initialized until the context prop has been defined.
*/
deferInitialization?: boolean;
/**
* LaunchDarkly initialization options. These options are common between LaunchDarkly's JavaScript and React SDKs.
*
* @see https://docs.launchdarkly.com/sdk/features/config#javascript
*/
options?: LDOptions;
/**
* Additional initialization options specific to the React SDK.
*
* @see options
*/
reactOptions?: LDReactOptions;
/**
* If specified, `launchdarkly-react-client-sdk` will only listen for changes to these flags.
* Otherwise, all flags will be requested and listened to.
* Flag keys must be in their original form as known to LaunchDarkly rather than in their camel-cased form.
*/
flags?: LDFlagSet;
/**
* Optionally, the ldClient can be initialized outside of the provider
* and passed in, instead of being initialized by the provider.
*
* Note: it should only be passed in when it has emitted the 'ready'
* event when using withLDProvider, to ensure that the flags are properly set.
* If using with asyncWithLDProvider, then it will wait internally, so
* it is not required that the client have emitted the 'ready' event.
*/
ldClient?: LDClient | Promise<LDClient | undefined>;
/**
* The amount of time, in seconds, to wait for initialization before rejecting the promise.
* Using a large timeout is not recommended. If you use a large timeout and await it, then
* any network delays will cause your application to wait a long time before continuing
* execution. This gets passed to the underlying Javascript SDK `waitForInitialization`
* function.
*/
timeout?: number;
}
/**
* Configuration object used to initialize LaunchDarkly's JS client asynchronously.
*/
type AsyncProviderConfig = Omit<ProviderConfig, 'deferInitialization'> & {
/**
* @deprecated - `asyncWithLDProvider` does not support the `deferInitialization` config option because
* `asyncWithLDProvider` needs to be initialized at the app entry point prior to render to ensure flags and the
* ldClient are ready at the beginning of the app.
*/
deferInitialization?: boolean;
};
/**
* The return type of withLDProvider HOC. Exported for testing purposes only.
*
* @ignore
*/
interface EnhancedComponent extends React.Component {
subscribeToChanges(ldClient: LDClient): void;
componentDidMount(): Promise<void>;
componentDidUpdate(prevProps: ProviderConfig): Promise<void>;
}
/**
* Return type of `initLDClient`.
*/
interface AllFlagsLDClient {
/**
* Contains all flags from LaunchDarkly.
*/
flags: LDFlagSet;
/**
* An instance of `LDClient` from the LaunchDarkly JS SDK (`launchdarkly-js-client-sdk`).
*
* @see https://docs.launchdarkly.com/sdk/client-side/javascript
*/
ldClient: LDClient;
/**
* LaunchDarkly client initialization error, if there was one.
*/
error?: Error;
}
/**
* Map of camelized flag keys to original unmodified flag keys.
*/
type LDFlagKeyMap = Record<string, string>;
/**
* The sdk context stored in the Provider state and passed to consumers.
*/
interface ReactSdkContext {
/**
* JavaScript proxy that will trigger a LDClient#variation call on flag read in order
* to register a flag evaluation event in LaunchDarkly. Empty {} initially
* until flags are fetched from the LaunchDarkly servers.
*/
flags: LDFlagSet;
/**
* Map of camelized flag keys to their original unmodified form. Empty if useCamelCaseFlagKeys option is false.
*/
flagKeyMap: LDFlagKeyMap;
/**
* An instance of `LDClient` from the LaunchDarkly JS SDK (`launchdarkly-js-client-sdk`).
* This will be be undefined initially until initialization is complete.
*
* @see https://docs.launchdarkly.com/sdk/client-side/javascript
*/
ldClient?: LDClient;
/**
* LaunchDarkly client initialization error, if there was one.
*/
error?: Error;
}
interface ProviderState {
error?: Error;
flagKeyMap: LDFlagKeyMap;
flags: LDFlagSet;
ldClient?: LDClient;
unproxiedFlags: LDFlagSet;
}
/**
* The `LDProvider` is a component which accepts a config object which is used to
* initialize `launchdarkly-js-client-sdk`.
*
* This Provider does three things:
* - It initializes the ldClient instance by calling `launchdarkly-js-client-sdk` initialize on `componentDidMount`
* - It saves all flags and the ldClient instance in the context API
* - It subscribes to flag changes and propagate them through the context API
*
* Because the `launchdarkly-js-client-sdk` in only initialized on `componentDidMount`, your flags and the
* ldClient are only available after your app has mounted. This can result in a flicker due to flag changes at
* startup time.
*
* This component can be used as a standalone provider. However, be mindful to only include the component once
* within your application. This provider is used inside the `withLDProviderHOC` and can be used instead to initialize
* the `launchdarkly-js-client-sdk`. For async initialization, check out the `asyncWithLDProvider` function
*/
declare class LDProvider extends Component<PropsWithChildren<ProviderConfig>, ProviderState> implements EnhancedComponent {
readonly state: Readonly<ProviderState>;
constructor(props: ProviderConfig);
getReactOptions: () => {
useCamelCaseFlagKeys: boolean;
sendEventsOnFlagRead: boolean;
reactContext: React__default.Context<ReactSdkContext>;
};
subscribeToChanges: (ldClient: LDClient) => void;
onFailed: (_ldClient: LDClient, e: Error) => void;
onReady: (ldClient: LDClient, reactOptions: LDReactOptions, targetFlags?: LDFlagSet) => void;
prepareLDClient: () => Promise<void>;
componentDidMount(): Promise<void>;
componentDidUpdate(prevProps: ProviderConfig): Promise<void>;
render(): React__default.JSX.Element;
}
/**
* `withLDProvider` is a function which accepts a config object which is used to
* initialize `launchdarkly-js-client-sdk`.
*
* This HOC handles passing configuration to the `LDProvider`, which does the following:
* - It initializes the ldClient instance by calling `launchdarkly-js-client-sdk` initialize on `componentDidMount`
* - It saves all flags and the ldClient instance in the context API
* - It subscribes to flag changes and propagate them through the context API
*
* The difference between `withLDProvider` and `asyncWithLDProvider` is that `withLDProvider` initializes
* `launchdarkly-js-client-sdk` at `componentDidMount`. This means your flags and the ldClient are only available after
* your app has mounted. This can result in a flicker due to flag changes at startup time.
*
* `asyncWithLDProvider` initializes `launchdarkly-js-client-sdk` at the entry point of your app prior to render.
* This means that your flags and the ldClient are ready at the beginning of your app. This ensures your app does not
* flicker due to flag changes at startup time.
*
* @param config - The configuration used to initialize LaunchDarkly's JS SDK
* @return A function which accepts your root React component and returns a HOC
*/
declare function withLDProvider<T extends JSX.IntrinsicAttributes = {}>(config: ProviderConfig): (WrappedComponent: React.ComponentType<T>) => React.ComponentType<T>;
/**
* This is an async function which initializes LaunchDarkly's JS SDK (`launchdarkly-js-client-sdk`)
* and awaits it so all flags and the ldClient are ready before the consumer app is rendered.
*
* The difference between `withLDProvider` and `asyncWithLDProvider` is that `withLDProvider` initializes
* `launchdarkly-js-client-sdk` at componentDidMount. This means your flags and the ldClient are only available after
* your app has mounted. This can result in a flicker due to flag changes at startup time.
*
* `asyncWithLDProvider` initializes `launchdarkly-js-client-sdk` at the entry point of your app prior to render.
* This means that your flags and the ldClient are ready at the beginning of your app. This ensures your app does not
* flicker due to flag changes at startup time.
*
* `asyncWithLDProvider` accepts a config object which is used to initialize `launchdarkly-js-client-sdk`.
*
* `asyncWithLDProvider` does not support the `deferInitialization` config option because `asyncWithLDProvider` needs
* to be initialized at the entry point prior to render to ensure your flags and the ldClient are ready at the beginning
* of your app.
*
* It returns a provider which is a React FunctionComponent which:
* - saves all flags and the ldClient instance in the context API
* - subscribes to flag changes and propagate them through the context API
*
* @param config - The configuration used to initialize LaunchDarkly's JS SDK
*/
declare function asyncWithLDProvider(config: AsyncProviderConfig): Promise<({ children }: {
children: ReactNode;
}) => React__default.JSX.Element>;
/**
* `useFlags` is a custom hook which returns all feature flags. It uses the `useContext` primitive
* to access the LaunchDarkly context set up by `withLDProvider`. As such you will still need to
* use the `withLDProvider` HOC at the root of your app to initialize the React SDK and populate the
* context with `ldClient` and your flags.
*
* @param reactContext If specified, the provided React context will be used.
*
* @return All the feature flags configured in your LaunchDarkly project
*/
declare const useFlags: <T extends LDFlagSet = LDFlagSet>(reactContext?: React__default.Context<ReactSdkContext>) => T;
/**
* `useLDClient` is a custom hook which returns the underlying [LaunchDarkly JavaScript SDK client object](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html).
* Like the `useFlags` custom hook, `useLDClient` also uses the `useContext` primitive to access the LaunchDarkly
* context set up by `withLDProvider`. You will still need to use the `withLDProvider` HOC
* to initialise the react sdk to use this custom hook.
*
* @param reactContext If specified, the custom React context will be used.
*
* @return The `launchdarkly-js-client-sdk` `LDClient` object
*/
declare const useLDClient: (reactContext?: React__default.Context<ReactSdkContext>) => launchdarkly_js_client_sdk.LDClient | undefined;
/**
* Provides the LaunchDarkly client initialization error, if there was one.
*
* @param reactContext If specified, the custom React context will be used.
*
* @return The `launchdarkly-js-client-sdk` `LDClient` initialization error
*/
declare function useLDClientError(reactContext?: React__default.Context<ReactSdkContext>): Error | undefined;
/**
* Transforms a set of flags so that their keys are camelCased. This function ignores
* flag keys which start with `$`.
*
* @param rawFlags A mapping of flag keys and their values
* @return A transformed `LDFlagSet` with camelCased flag keys
*/
declare const camelCaseKeys: {
(rawFlags: LDFlagSet): LDFlagSet;
/**
* @deprecated The `camelCaseKeys.camelCaseKeys` property will be removed in a future version,
* please update your code to use the `camelCaseKeys` function directly.
*/
camelCaseKeys: any;
};
/**
* `reactSdkContextFactory` is a function useful for creating a React context for use with
* all the providers and consumers in this library.
*
* @return a React Context
*/
declare const reactSdkContextFactory: () => React.Context<ReactSdkContext>;
export { type AllFlagsLDClient, type AsyncProviderConfig, type EnhancedComponent, type LDFlagKeyMap, type LDProps, LDProvider, type LDReactOptions, type ProviderConfig, type ReactSdkContext, asyncWithLDProvider, camelCaseKeys, defaultReactOptions, reactSdkContextFactory, useFlags, useLDClient, useLDClientError, withLDConsumer, withLDProvider };