Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
11.8.0 (October 28, 2025)
- 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.
- Added `client.getStatus()` method to retrieve the client readiness status properties (`isReady`, `isReadyFromCache`, etc).
- Added `client.whenReady()` and `client.whenReadyFromCache()` methods to replace the deprecated `client.ready()` method, which has an issue causing the returned promise to hang when using async/await syntax if it was rejected.
- Updated the SDK_READY_FROM_CACHE event to be emitted alongside the SDK_READY event if it hasn’t already been emitted.
- Updated @splitsoftware/splitio-commons package to version 2.8.0.

11.7.1 (October 8, 2025)
- Bugfix - Updated @splitsoftware/splitio-commons package to version 2.7.1, which fixes the `debug` option to support log levels when the `logger` option is used.

Expand Down
2 changes: 1 addition & 1 deletion karma/e2e.online.karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const assign = require('lodash/assign');

module.exports = function(config) {
module.exports = function (config) {
'use strict';

config.set(assign({}, require('./config'), {
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio",
"version": "11.7.1",
"version": "11.7.2-rc.4",
"description": "Split SDK",
"files": [
"README.md",
Expand Down Expand Up @@ -38,7 +38,7 @@
"node": ">=14.0.0"
},
"dependencies": {
"@splitsoftware/splitio-commons": "2.7.9-rc.1",
"@splitsoftware/splitio-commons": "2.7.9-rc.3",
"bloom-filters": "^3.0.4",
"ioredis": "^4.28.0",
"js-yaml": "^3.13.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,17 @@ export default function (fetchMock, assert) {
t.end();
});
client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
});

client.on(client.Event.SDK_READY, () => {
t.true(client.__getStatus().isReadyFromCache, 'Client should emit SDK_READY and it should be ready from cache');
t.true(client.getStatus().isReadyFromCache, 'Client should emit SDK_READY and it should be ready from cache');
});
client2.on(client.Event.SDK_READY, () => {
t.true(client2.__getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
t.true(client2.getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
});
client3.on(client.Event.SDK_READY, () => {
t.true(client2.__getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
t.true(client2.getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
});

});
Expand Down Expand Up @@ -356,7 +356,7 @@ export default function (fetchMock, assert) {
let manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
});

await client.whenReady();
Expand Down Expand Up @@ -400,7 +400,7 @@ export default function (fetchMock, assert) {
manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
});

await new Promise(res => client.once(client.Event.SDK_READY, res));
Expand Down
32 changes: 18 additions & 14 deletions src/__tests__/browserSuites/ready-from-cache.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,17 @@ export default function (fetchMock, assert) {
t.end();
});
client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
});

client.on(client.Event.SDK_READY, () => {
t.true(client.__getStatus().isReadyFromCache, 'Client should emit SDK_READY and it should be ready from cache');
t.true(client.getStatus().isReadyFromCache, 'Client should emit SDK_READY and it should be ready from cache');
});
client2.on(client.Event.SDK_READY, () => {
t.true(client2.__getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
t.true(client2.getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
});
client3.on(client.Event.SDK_READY, () => {
t.true(client2.__getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
t.true(client2.getStatus().isReadyFromCache, 'Non-default client should emit SDK_READY and it should be ready from cache');
});

});
Expand Down Expand Up @@ -331,7 +331,7 @@ export default function (fetchMock, assert) {

client.on(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(Date.now() - startTime < 400, 'It should emit SDK_READY_FROM_CACHE on every client if there was data in the cache and we subscribe on time. Should be considerably faster than actual readiness from the cloud.');
t.false(client.__getStatus().isReady, 'It should not be ready yet');
t.false(client.getStatus().isReady, 'It should not be ready yet');

t.equal(client.getTreatment('always_on'), 'off', 'It should evaluate treatments with data from cache instead of control due to Input Validation');

Expand Down Expand Up @@ -515,13 +515,13 @@ export default function (fetchMock, assert) {
});
});

assert.test(t => { // Testing when we start with initial rollout plan data and sync storage type (is ready from cache immediately)
assert.test(async t => { // Testing when we start with initial rollout plan data and sync storage type (is ready from cache immediately)
const testUrls = {
sdk: 'https://sdk.baseurl/readyFromCacheWithInitialRolloutPlan',
events: 'https://events.baseurl/readyFromCacheWithInitialRolloutPlan'
};

t.plan(5);
t.plan(6);

fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.3&since=25&rbSince=-1', { status: 200, body: { ff: { ...splitChangesMock1.ff, s: 25 } } });
fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: membershipsNicolas });
Expand Down Expand Up @@ -552,7 +552,7 @@ export default function (fetchMock, assert) {
const client = splitio.client();
const client2 = splitio.client('emi@split.io');

t.equal(client.__getStatus().isReadyFromCache, true, 'Client is ready from cache');
t.equal(client.getStatus().isReadyFromCache, true, 'Client is ready from cache');

t.equal(client.getTreatment('always_on'), 'off', 'It should evaluate treatments with data from cache. Key without memberships');
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with data from cache. Key with memberships');
Expand All @@ -577,6 +577,10 @@ export default function (fetchMock, assert) {
t.end();
});
});

const startTime = Date.now();
await client.whenReadyFromCache();
t.true(nearlyEqual(Date.now() - startTime, 0), 'whenReadyFromCache should be resolved immediately');
});

/** Fetch specific splits **/
Expand Down Expand Up @@ -613,7 +617,7 @@ export default function (fetchMock, assert) {
const manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
});

client.once(client.Event.SDK_READY, () => {
Expand Down Expand Up @@ -657,7 +661,7 @@ export default function (fetchMock, assert) {
const manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
});

client.once(client.Event.SDK_READY, () => {
Expand Down Expand Up @@ -758,7 +762,7 @@ export default function (fetchMock, assert) {
const manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
});

client.once(client.Event.SDK_READY, () => {
Expand Down Expand Up @@ -819,7 +823,7 @@ export default function (fetchMock, assert) {
const manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
});

client.once(client.Event.SDK_READY, () => {
Expand Down Expand Up @@ -919,7 +923,7 @@ export default function (fetchMock, assert) {
let manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
});

await client.whenReady();
Expand Down Expand Up @@ -959,7 +963,7 @@ export default function (fetchMock, assert) {
manager = splitio.manager();

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
t.true(client.getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
});

await new Promise(res => client.once(client.Event.SDK_READY, res));
Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/errorCatching/browser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ tape('Error catching on callbacks - Browsers', assert => {
}

client.on(client.Event.SDK_READY_TIMED_OUT, () => {
assert.true(client.__getStatus().hasTimedout); // SDK status should be already updated
assert.true(client.getStatus().hasTimedout); // SDK status should be already updated
attachErrorHandlerIfApplicable();
null.willThrowForTimedOut();
});

client.once(client.Event.SDK_READY, () => {
assert.true(client.__getStatus().isReady); // SDK status should be already updated
assert.true(client.getStatus().isReady); // SDK status should be already updated
attachErrorHandlerIfApplicable();
null.willThrowForReady();
});
Expand All @@ -108,7 +108,7 @@ tape('Error catching on callbacks - Browsers', assert => {
});

client.once(client.Event.SDK_READY_FROM_CACHE, () => {
assert.true(client.__getStatus().isReadyFromCache); // SDK status should be already updated
assert.true(client.getStatus().isReadyFromCache); // SDK status should be already updated
attachErrorHandlerIfApplicable();
null.willThrowForReadyFromCache();
});
Expand Down
Loading