Skip to content

Commit e2253bc

Browse files
authored
prepare 2.2.0 release (#98)
1 parent 04c5ce9 commit e2253bc

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
All notable changes to the LaunchDarkly client-side JavaScript SDK will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org).
55

6+
## [2.2.0] - 2018-06-22
7+
### Added:
8+
- New event `goalsReady` (and new method `waitUntilGoalsReady`, which returns a Promise based on that event) indicates when the client has loaded goals-- i.e. when it is possible for pageview events and click events to be triggered.
9+
10+
### Fixed:
11+
- Fixed a bug where calling `variation` would throw an error if the client was bootstrapped from local storage and there were no flags in local storage yet, and the initial HTTP request for flags from LaunchDarkly had not yet completed. (thanks, [mpcowan](https://github.com/launchdarkly/js-client/pull/97)!)
12+
613
## [2.1.2] - 2018-06-08
714
### Fixed:
815
- Fix the TypeScript definitions to properly support the ES default export.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ldclient-js",
3-
"version": "2.1.2",
3+
"version": "2.2.0",
44
"description": "LaunchDarkly SDK for JavaScript",
55
"author": "LaunchDarkly <[email protected]>",
66
"license": "Apache-2.0",

src/__tests__/LDClient-test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ describe('LDClient', () => {
100100
});
101101
});
102102

103+
it('should resolve waitUntilGoalsReady when goals are loaded', done => {
104+
const handleGoalsReady = jest.fn();
105+
const client = LDClient.initialize(envName, user, {
106+
bootstrap: {},
107+
});
108+
109+
client.waitUntilGoalsReady().then(handleGoalsReady);
110+
111+
client.on('goalsReady', () => {
112+
setTimeout(() => {
113+
expect(handleGoalsReady).toHaveBeenCalled();
114+
done();
115+
}, 0);
116+
});
117+
118+
getLastRequest().respond(200);
119+
});
120+
103121
it('should emit an error when an invalid samplingInterval is specified', done => {
104122
const client = LDClient.initialize(envName, user, {
105123
bootstrap: {},
@@ -187,6 +205,24 @@ describe('LDClient', () => {
187205
});
188206
});
189207

208+
it('should start with empty flags if we tried to use cached settings and there are none', done => {
209+
window.localStorage.removeItem(lsKey);
210+
211+
const client = LDClient.initialize(envName, user, {
212+
bootstrap: 'localstorage',
213+
});
214+
215+
// don't wait for ready event - verifying that variation() doesn't throw an error if called before ready
216+
expect(client.variation('flag-key', 0)).toEqual(0);
217+
218+
// verify that the flags get requested from LD
219+
client.on('ready', () => {
220+
expect(client.variation('flag-key')).toEqual(1);
221+
done();
222+
});
223+
requests[0].respond(200, { 'Content-Type': 'application/json' }, '{"flag-key":{"value":1,"version":1}}');
224+
});
225+
190226
it('should handle localStorage getItem throwing an exception', done => {
191227
// sandbox.restore(window.localStorage.__proto__, 'getItem');
192228
// sandbox.stub(window.localStorage.__proto__, 'getItem').throws();

src/index.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as errors from './errors';
1111

1212
const readyEvent = 'ready';
1313
const changeEvent = 'change';
14+
const goalsEvent = 'goalsReady';
1415
const locationWatcherInterval = 300;
1516

1617
function initialize(env, user, options = {}) {
@@ -405,7 +406,7 @@ function initialize(env, user, options = {}) {
405406
flags = store.loadFlags();
406407

407408
if (flags === null) {
408-
flags = {}
409+
flags = {};
409410
requestor.fetchFlagSettings(ident.getUser(), hash, (err, settings) => {
410411
if (err) {
411412
emitter.maybeReportError(new errors.LDFlagFetchError(messages.errorFetchingFlags(err)));
@@ -494,6 +495,7 @@ function initialize(env, user, options = {}) {
494495
goalTracker = GoalTracker(goals, sendGoalEvent);
495496
watchLocation(locationWatcherInterval, refreshGoalTracker);
496497
}
498+
emitter.emit(goalsEvent);
497499
});
498500

499501
function start() {
@@ -524,8 +526,16 @@ function initialize(env, user, options = {}) {
524526
});
525527
});
526528

529+
const goalsPromise = new Promise(resolve => {
530+
const onGoals = emitter.on(goalsEvent, () => {
531+
emitter.off(goalsEvent, onGoals);
532+
resolve();
533+
});
534+
});
535+
527536
const client = {
528537
waitUntilReady: () => readyPromise,
538+
waitUntilGoalsReady: () => goalsPromise,
529539
identify: identify,
530540
variation: variation,
531541
track: track,

0 commit comments

Comments
 (0)