Skip to content

Commit 56cd1e4

Browse files
authored
prepare 2.7.4 release (#125)
1 parent 47db0f2 commit 56cd1e4

File tree

7 files changed

+41
-14
lines changed

7 files changed

+41
-14
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
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.7.4] - 2018-11-21
7+
### Fixed:
8+
- When using the [`event-source-polyfill`](https://github.com/Yaffle/EventSource) package to allow streaming mode in browsers with no native EventSource support, the polyfill was using a default read timeout of 45 seconds, so if no updates arrived within 45 seconds it would log an error and reconnect the stream. The SDK now sets its own timeout (5 minutes) which will be used if this particular polyfill is active. LaunchDarkly normally sends a heartbeat every 3 minutes, so you should not see a timeout happen unless the connection has been lost.
9+
- The SDK's use of the "Base64" package caused problems for build tools that strictly enforce the lowercase package name rule. It now uses the "base64-js" package instead. ([#124](https://github.com/launchdarkly/js-client/issues/124))
10+
611
## [2.7.3] - 2018-11-09
712
### Fixed:
813
- The TypeScript definitions were incorrectly restricting the possible values for event types in `on()` and `off()`. Also, added documentation for event types which were not documented before. ([#122](https://github.com/launchdarkly/js-client/issues/122))

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ when `client.on('change')` is called.
2929

3030
If you need streaming support, and you wish to support browsers that do not
3131
support `EventSource` natively, you can install a polyfill such as
32-
[EventSource](https://github.com/Yaffle/EventSource).
32+
[event-source-polyfill](https://github.com/Yaffle/EventSource).
3333

3434
#### CDN
3535

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ldclient-js",
3-
"version": "2.7.3",
3+
"version": "2.7.4",
44
"description": "LaunchDarkly SDK for JavaScript",
55
"author": "LaunchDarkly <[email protected]>",
66
"license": "Apache-2.0",
@@ -78,7 +78,7 @@
7878
"typescript": "3.0.1"
7979
},
8080
"dependencies": {
81-
"Base64": "1.0.1",
81+
"base64-js": "1.3.0",
8282
"escape-string-regexp": "1.0.5"
8383
},
8484
"repository": {

src/Stream.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default function Stream(baseUrl, environment, hash, config) {
66
const useReport = (config && config.useReport) || false;
77
const withReasons = (config && config.evaluationReasons) || false;
88
const streamReconnectDelay = (config && config.streamReconnectDelay) || 1000;
9+
const timeoutMillis = 300000; // 5 minutes (same as other SDKs) - note, this only has an effect on polyfills
910
let es = null;
1011
let reconnectTimeoutReference = null;
1112
let user = null;
@@ -62,7 +63,17 @@ export default function Stream(baseUrl, environment, hash, config) {
6263
url = url + (query ? '?' : '') + query;
6364

6465
closeConnection();
65-
es = new window.EventSource(url);
66+
67+
// The standard EventSource constructor doesn't take any options, just a URL. However, some
68+
// EventSource polyfills allow us to specify a timeout interval, and in some cases they will
69+
// default to a too-short timeout if we don't specify one. So, here, we are setting the
70+
// timeout properties that are used by several popular polyfills.
71+
const options = {
72+
heartbeatTimeout: timeoutMillis, // used by "event-source-polyfill" package
73+
silentTimeout: timeoutMillis, // used by "eventsource-polyfill" package
74+
};
75+
76+
es = new window.EventSource(url, options);
6677
for (const key in handlers) {
6778
if (handlers.hasOwnProperty(key)) {
6879
es.addEventListener(key, handlers[key]);

src/__tests__/EventSender-test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Base64 from 'Base64';
1+
import * as base64 from 'base64-js';
22
import sinon from 'sinon';
33

44
import EventSender from '../EventSender';
@@ -44,7 +44,9 @@ describe('EventSender', () => {
4444
s = s + '=';
4545
}
4646
s = s.replace(/_/g, '/').replace(/-/g, '+');
47-
return decodeURIComponent(escape(Base64.atob(s)));
47+
const decodedBytes = base64.toByteArray(s);
48+
const decodedStr = String.fromCharCode.apply(String, decodedBytes);
49+
return decodeURIComponent(escape(decodedStr));
4850
}
4951

5052
function decodeOutputFromUrl(url) {

src/utils.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
import Base64 from 'Base64';
1+
import * as base64 from 'base64-js';
22

33
// See http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
44
export function btoa(s) {
5-
return Base64.btoa(unescape(encodeURIComponent(s)));
5+
const escaped = unescape(encodeURIComponent(s));
6+
return base64.fromByteArray(stringToBytes(escaped));
7+
}
8+
9+
function stringToBytes(s) {
10+
const b = [];
11+
for (let i = 0; i < s.length; i++) {
12+
b.push(s.charCodeAt(i));
13+
}
14+
return b;
615
}
716

817
export function base64URLEncode(s) {

0 commit comments

Comments
 (0)