diff --git a/src/provider.test.tsx b/src/provider.test.tsx
index 4bc7e49..7a62ee2 100644
--- a/src/provider.test.tsx
+++ b/src/provider.test.tsx
@@ -4,6 +4,7 @@ jest.mock('./context', () => ({ Provider: 'Provider' }));
import * as React from 'react';
import { create } from 'react-test-renderer';
import { shallow } from 'enzyme';
+import type { LDClient } from 'launchdarkly-js-client-sdk';
import { LDFlagChangeset, LDFlagSet, LDOptions, LDUser } from 'launchdarkly-js-client-sdk';
import initLDClient from './initLDClient';
import { LDReactOptions, EnhancedComponent, defaultReactOptions, ProviderConfig } from './types';
@@ -18,6 +19,7 @@ const mockLDClient = {
on: jest.fn((e: string, cb: () => void) => {
cb();
}),
+ allFlags: jest.fn().mockReturnValue({}),
};
describe('LDProvider', () => {
@@ -58,6 +60,61 @@ describe('LDProvider', () => {
expect(mockInitLDClient).toHaveBeenCalledWith(clientSideID, user, defaultReactOptions, options, undefined);
});
+ test('ld client is used if passed in', async () => {
+ const user: LDUser = { key: 'yus', name: 'yus ng' };
+ const options: LDOptions = { bootstrap: {} };
+ const ldClient = (await initLDClient(clientSideID, user, defaultReactOptions, options, undefined)).ldClient;
+ mockInitLDClient.mockClear();
+ const props: ProviderConfig = { clientSideID, ldClient };
+ const LaunchDarklyApp = (
+
+
+
+ );
+ const instance = create(LaunchDarklyApp).root.findByType(LDProvider).instance as EnhancedComponent;
+
+ await instance.componentDidMount();
+ expect(mockInitLDClient).not.toHaveBeenCalled();
+ });
+
+ test('ld client is used if passed in as promise', async () => {
+ const user1: LDUser = { key: 'yus', name: 'yus ng' };
+ const user2: LDUser = { key: 'launch', name: 'darkly' };
+ const options: LDOptions = { bootstrap: {} };
+ const ldClient: Promise = new Promise(async resolve =>
+ resolve((await initLDClient(clientSideID, user1, defaultReactOptions, options, undefined)).ldClient),
+ );
+ const props: ProviderConfig = { clientSideID, ldClient, user: user2 };
+ const LaunchDarklyApp = (
+
+
+
+ );
+ const instance = create(LaunchDarklyApp).root.findByType(LDProvider).instance as EnhancedComponent;
+
+ await instance.componentDidMount();
+ expect(mockInitLDClient).toBeCalledTimes(1);
+ expect(mockInitLDClient).toHaveBeenCalledWith(clientSideID, user1, defaultReactOptions, options, undefined);
+ });
+
+ test('ld client is created if passed in promise resolves as undefined', async () => {
+ const user: LDUser = { key: 'yus', name: 'yus ng' };
+ const options: LDOptions = { bootstrap: {} };
+ const ldClient: Promise = new Promise(async resolve =>
+ resolve(undefined),
+ );
+ const props: ProviderConfig = { clientSideID, ldClient, user, options };
+ const LaunchDarklyApp = (
+
+
+
+ );
+ const instance = create(LaunchDarklyApp).root.findByType(LDProvider).instance as EnhancedComponent;
+
+ await instance.componentDidMount();
+ expect(mockInitLDClient).toHaveBeenCalledWith(clientSideID, user, defaultReactOptions, options, undefined);
+ });
+
test('ldClient bootstraps with empty flags', () => {
const user: LDUser = { key: 'yus', name: 'yus ng' };
const options: LDOptions = {
diff --git a/src/provider.tsx b/src/provider.tsx
index cceddb9..1b1b10e 100644
--- a/src/provider.tsx
+++ b/src/provider.tsx
@@ -3,7 +3,7 @@ import { LDClient, LDFlagSet, LDFlagChangeset } from 'launchdarkly-js-client-sdk
import { EnhancedComponent, ProviderConfig, defaultReactOptions } from './types';
import { Provider, LDContext as HocState } from './context';
import initLDClient from './initLDClient';
-import { camelCaseKeys, getFlattenedFlagsFromChangeset } from './utils';
+import { camelCaseKeys, fetchFlags, getFlattenedFlagsFromChangeset } from './utils';
/**
* The `LDProvider` is a component which accepts a config object which is used to
@@ -62,8 +62,16 @@ class LDProvider extends React.Component implements En
initLDClient = async () => {
const { clientSideID, flags, options, user } = this.props;
+ let ldClient = await this.props.ldClient;
const reactOptions = this.getReactOptions();
- const { flags: fetchedFlags, ldClient } = await initLDClient(clientSideID, user, reactOptions, options, flags);
+ let fetchedFlags;
+ if (ldClient) {
+ fetchedFlags = await fetchFlags(ldClient, reactOptions, flags);
+ } else {
+ const initialisedOutput = await initLDClient(clientSideID, user, reactOptions, options, flags);
+ fetchedFlags = initialisedOutput.flags;
+ ldClient = initialisedOutput.ldClient;
+ }
this.setState({ flags: fetchedFlags, ldClient });
this.subscribeToChanges(ldClient);
};
diff --git a/src/types.ts b/src/types.ts
index fc5de48..f7b1b75 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -71,6 +71,14 @@ export interface ProviderConfig {
* Otherwise, all flags will be requested and listened to.
*/
flags?: LDFlagSet;
+
+ /**
+ * Optionally, the ldClient can be initialised outside of the provider
+ * and passed in, instead of being initialised by the provider.
+ * Note: it should only be passed in when it has emitted the 'ready'
+ * event, to ensure that the flags are properly set.
+ */
+ ldClient?: LDClient | Promise;
}
/**