Skip to content

Commit becc1fd

Browse files
committed
fix: bootstrapped client can do evaluation when not ready
This commit will allow variation calls to use bootstrapped values during the client initialization process.
1 parent 0bafb28 commit becc1fd

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

packages/sdk/browser/src/BrowserClient.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Platform,
1919
} from '@launchdarkly/js-client-sdk-common';
2020

21+
import { readFlagsFromBootstrap } from './bootstrap';
2122
import { getHref } from './BrowserApi';
2223
import BrowserDataManager from './BrowserDataManager';
2324
import { BrowserIdentifyOptions as LDIdentifyOptions } from './BrowserIdentifyOptions';
@@ -32,6 +33,7 @@ import BrowserPlatform from './platform/BrowserPlatform';
3233
class BrowserClientImpl extends LDClientImpl {
3334
private readonly _goalManager?: GoalManager;
3435
private readonly _plugins?: LDPlugin[];
36+
private _bootstrapAttempted = false;
3537

3638
constructor(
3739
clientSideId: string,
@@ -197,6 +199,12 @@ class BrowserClientImpl extends LDClientImpl {
197199
);
198200
}
199201

202+
/**
203+
* @ignore
204+
* NOTE: this identify is not doing anything as the `makeClient` function maps the
205+
* identify function to identifyResults. We will need to consolidate this function
206+
* in the js-client-sdk-common package.
207+
*/
200208
override async identify(context: LDContext, identifyOptions?: LDIdentifyOptions): Promise<void> {
201209
return super.identify(context, identifyOptions);
202210
}
@@ -211,6 +219,21 @@ class BrowserClientImpl extends LDClientImpl {
211219
if (identifyOptions?.sheddable === undefined) {
212220
identifyOptionsWithUpdatedDefaults.sheddable = true;
213221
}
222+
223+
if (!this._bootstrapAttempted && identifyOptionsWithUpdatedDefaults.bootstrap) {
224+
try {
225+
const bootstrapData = readFlagsFromBootstrap(
226+
this.logger,
227+
identifyOptionsWithUpdatedDefaults.bootstrap,
228+
);
229+
this.setBootstrap(context, bootstrapData);
230+
} catch (e) {
231+
this.logger.error('failed to bootstrap data');
232+
} finally {
233+
this._bootstrapAttempted = true;
234+
}
235+
}
236+
214237
const res = await super.identifyResult(context, identifyOptionsWithUpdatedDefaults);
215238
this._goalManager?.startTracking();
216239
return res;

packages/shared/sdk-client/src/LDClientImpl.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import createEventProcessor from './events/createEventProcessor';
4343
import EventFactory from './events/EventFactory';
4444
import DefaultFlagManager, { FlagManager } from './flag-manager/FlagManager';
4545
import { FlagChangeType } from './flag-manager/FlagUpdater';
46+
import { ItemDescriptor } from './flag-manager/ItemDescriptor';
4647
import HookRunner from './HookRunner';
4748
import { getInspectorHook } from './inspection/getInspectorHook';
4849
import InspectorManager from './inspection/InspectorManager';
@@ -360,6 +361,19 @@ export default class LDClientImpl implements LDClient, LDClientIdentifyResult {
360361
return Promise.race([callSitePromise, timeoutPromise]);
361362
}
362363

364+
/**
365+
* Exposes the bootstrap functionality to the derived classes. This function is mainly used to help set
366+
* flag values for bootstrapped clients before the initialization is complete.
367+
*
368+
* @param pristineContext The LDContext object to be identified.
369+
* @param newFlags The new flags to set.
370+
*/
371+
protected setBootstrap(pristineContext: LDContext, newFlags: { [key: string]: ItemDescriptor }) {
372+
this._uncheckedContext = pristineContext;
373+
this._checkedContext = Context.fromLDContext(this._uncheckedContext);
374+
this._flagManager.setBootstrap(this._checkedContext, newFlags);
375+
}
376+
363377
on(eventName: EventName, listener: Function): void {
364378
this.emitter.on(eventName, listener);
365379
}

0 commit comments

Comments
 (0)