Skip to content

Commit e46921a

Browse files
Merge pull request #165 from splitio/release-v1.6.1
Prepare release v1.6.1
2 parents dcbe505 + 13d2470 commit e46921a

File tree

7 files changed

+83
-38
lines changed

7 files changed

+83
-38
lines changed

CHANGES.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
1.6.1 (December 30, 2025)
2+
- Updated @splitsoftware/splitio-commons package to version 2.10.1 and other transitive dependencies for vulnerability fixes.
3+
- Updated the order of storage operations to prevent inconsistent states when using the `InLocalStorage` module and the browser’s `localStorage` fails due to quota limits.
4+
- Bugfix - Handle `null` prerequisites properly.
5+
16
1.6.0 (October 30, 2025)
27
- Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs.
38
- Added `client.getStatus()` method to retrieve the client readiness status properties (`isReady`, `isReadyFromCache`, etc).

package-lock.json

Lines changed: 30 additions & 27 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": "@splitsoftware/splitio-browserjs",
3-
"version": "1.6.0",
3+
"version": "1.6.1",
44
"description": "Split SDK for JavaScript on Browser",
55
"main": "cjs/index.js",
66
"module": "esm/index.js",
@@ -59,7 +59,7 @@
5959
"bugs": "https://github.com/splitio/javascript-browser-client/issues",
6060
"homepage": "https://github.com/splitio/javascript-browser-client#readme",
6161
"dependencies": {
62-
"@splitsoftware/splitio-commons": "2.8.0",
62+
"@splitsoftware/splitio-commons": "2.10.1",
6363
"tslib": "^2.3.1",
6464
"unfetch": "^4.2.0"
6565
},

src/__tests__/browserSuites/ready-from-cache.spec.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,34 @@ export const expectedHashWithFilter = '2ce5cc38'; // for SDK key '<fake-token-rf
107107

108108
export default function (fetchMock, assert) {
109109

110-
assert.test(t => { // Testing when we start from scratch
110+
assert.test(t => { // Testing when we start from scratch, with an initial localStorage write operation fail (should retry splitChanges with -1)
111111
const testUrls = {
112112
sdk: 'https://sdk.baseurl/readyFromCacheEmpty',
113113
events: 'https://events.baseurl/readyFromCacheEmpty'
114114
};
115115
localStorage.clear();
116+
117+
// simulate a localStorage failure when saving a FF and a membership
118+
const originalSetItem = localStorage.setItem;
119+
localStorage.setItem = (key, value) => {
120+
if (key.includes('.nicolas@split.io.')) {
121+
throw new Error('localStorage.setItem failed');
122+
}
123+
if (key.includes('.split.')) {
124+
localStorage.setItem = originalSetItem;
125+
throw new Error('localStorage.setItem failed');
126+
}
127+
return originalSetItem.call(localStorage, key, value);
128+
};
129+
116130
t.plan(4);
117131

118-
fetchMock.get(testUrls.sdk + '/splitChanges?s=1.3&since=-1&rbSince=-1', { status: 200, body: splitChangesMock1 });
119-
fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: membershipsNicolas });
120-
fetchMock.get(testUrls.sdk + '/memberships/nicolas2%40split.io', { status: 200, body: { 'ms': {} } });
121-
fetchMock.get(testUrls.sdk + '/memberships/nicolas3%40split.io', { status: 200, body: { 'ms': {} } });
132+
fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.3&since=-1&rbSince=-1', { status: 200, body: splitChangesMock1 });
133+
fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.3&since=-1&rbSince=-1', { status: 200, body: splitChangesMock1 }); // retry
134+
fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: membershipsNicolas });
135+
fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: membershipsNicolas }); // retry
136+
fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas2%40split.io', { status: 200, body: { 'ms': {} } });
137+
fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas3%40split.io', { status: 200, body: { 'ms': {} } });
122138

123139
const splitio = SplitFactory({
124140
...baseConfig,

src/__tests__/consumer/browser_consumer_partial.spec.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,14 @@ tape('Browser Consumer Partial mode with pluggable storage', function (t) {
351351
sinon.stub(wrapperInstance, 'connect').callsFake(() => { Promise.reject(); });
352352
const getSpy = sinon.spy(wrapperInstance, 'get');
353353

354-
const sdk = SplitFactory(config);
354+
const sdk = SplitFactory({
355+
...config,
356+
fallbackTreatments: {
357+
byFlag: {
358+
'UT_IN_SEGMENT': 'fallback_treatment'
359+
}
360+
}
361+
});
355362

356363
const client = sdk.client();
357364

@@ -366,15 +373,15 @@ tape('Browser Consumer Partial mode with pluggable storage', function (t) {
366373
assert.true(nearlyEqual(Date.now() - start, 0), 'SDK_READY_TIMED_OUT event is emitted immediately');
367374

368375
// Client methods behave as if the SDK is not ready
369-
assert.equal(await client.getTreatment('UT_IN_SEGMENT'), 'control', 'treatment is control with label not ready.');
376+
assert.equal(await client.getTreatment('UT_IN_SEGMENT'), 'fallback_treatment', 'treatment is fallback_treatment with label not ready.');
370377
assert.true(await client.track('user', 'test.event', 18), 'event is tracked in memory (partial consumer mode).');
371378

372379
// Shared clients will also timeout immediately and behave as if the SDK is not ready
373380
const otherClient = sdk.client('other_user');
374381
otherClient.on(otherClient.Event.SDK_READY_TIMED_OUT, async () => {
375382
assert.true(nearlyEqual(Date.now() - start, 0), 'SDK_READY_TIMED_OUT event is emitted immediately in shared client');
376383

377-
assert.equal(await otherClient.getTreatment('UT_IN_SEGMENT'), 'control', 'treatment is control with label not ready.');
384+
assert.equal(await otherClient.getTreatment('UT_IN_SEGMENT'), 'fallback_treatment', 'treatment is fallback_treatment with label not ready.');
378385
assert.true(await otherClient.track('user', 'test.event', 18), 'event is tracked in memory (partial consumer mode).');
379386

380387
await client.destroy();

src/settings/defaults.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type SplitIO from '@splitsoftware/splitio-commons/types/splitio';
22
import { LogLevels, isLogLevelString } from '@splitsoftware/splitio-commons/src/logger/index';
33
import { CONSENT_GRANTED } from '@splitsoftware/splitio-commons/src/utils/constants';
44

5-
const packageVersion = '1.6.0';
5+
const packageVersion = '1.6.1';
66

77
/**
88
* In browser, the default debug level, can be set via the `localStorage.splitio_debug` item.

ts-tests/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,24 @@ client = client.removeAllListeners();
278278

279279
// Ready and destroy
280280
let promise: Promise<void> = client.ready();
281+
promise = client.whenReady();
281282
promise = client.destroy();
282283
promise = SDK.destroy();
283284
// @TODO not public yet
284285
// promise = client.flush();
286+
const promiseWhenReadyFromCache: Promise<boolean> = client.whenReadyFromCache();
287+
288+
// Get readiness status
289+
let status: SplitIO.ReadinessStatus = client.getStatus();
290+
status = {
291+
isReady: false,
292+
isReadyFromCache: false,
293+
isTimedout: false,
294+
isDestroyed: false,
295+
isOperational: false,
296+
hasTimedout: false,
297+
lastUpdate: 0
298+
};
285299

286300
// We can call getTreatment without a key.
287301
// treatment = client.getTreatment(splitKey, 'mySplit');

0 commit comments

Comments
 (0)