Skip to content

Commit 4bf9ebe

Browse files
Merge pull request #909 from splitio/fme-12310
update commons - events with metadata
2 parents 5fd9d6e + d6f77d8 commit 4bf9ebe

File tree

12 files changed

+197
-46
lines changed

12 files changed

+197
-46
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
11.10.0 (January 28, 2026)
2+
- Updated @splitsoftware/splitio-commons package to version 2.11.0, which:
3+
- Added functionality to provide metadata alongside SDK update and READY events. Read more in our docs.
4+
15
11.9.1 (December 18, 2025)
26
- Bugfix - Updated @splitsoftware/splitio-commons package to version 2.10.1 to handle `null` prerequisites properly
37

package-lock.json

Lines changed: 38 additions & 19 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",
3-
"version": "11.9.1",
3+
"version": "11.10.0",
44
"description": "Split SDK",
55
"files": [
66
"README.md",
@@ -38,7 +38,7 @@
3838
"node": ">=14.0.0"
3939
},
4040
"dependencies": {
41-
"@splitsoftware/splitio-commons": "2.10.1",
41+
"@splitsoftware/splitio-commons": "2.11.0",
4242
"bloom-filters": "^3.0.4",
4343
"ioredis": "^4.28.0",
4444
"js-yaml": "^3.13.1",

src/__tests__/browserSuites/push-corner-cases.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export function testSplitKillOnReadyFromCache(fetchMock, assert) {
9797
});
9898
client.on(client.Event.SDK_READY, () => {
9999
const lapse = Date.now() - start;
100-
assert.true(nearlyEqual(lapse, MILLIS_SPLIT_CHANGES_RESPONSE), 'SDK_READY once split changes arrives');
100+
assert.true(nearlyEqual(lapse, MILLIS_SPLIT_CHANGES_RESPONSE, 200), 'SDK_READY once split changes arrives');
101101

102102
client.destroy().then(() => { assert.end(); });
103103
});

src/__tests__/browserSuites/push-synchronization.spec.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const EXPECTED_DELAY_AND_BACKOFF = 241 + 100;
9191
export function testSynchronization(fetchMock, assert) {
9292
// Force the backoff base of UpdateWorkers to reduce test time
9393
Backoff.__TEST__BASE_MILLIS = 100;
94-
assert.plan(34);
94+
assert.plan(39); // +3 for FLAGS_UPDATE metadata, +2 for SEGMENTS_UPDATE metadata
9595
fetchMock.reset();
9696

9797
let start, splitio, client, otherClient, keylistAddClient, keylistRemoveClient, bitmapTrueClient, sharedClients = [];
@@ -108,7 +108,10 @@ export function testSynchronization(fetchMock, assert) {
108108

109109
setTimeout(() => {
110110
assert.equal(client.getTreatment('whitelist'), 'not_allowed', 'evaluation of initial Split');
111-
client.once(client.Event.SDK_UPDATE, () => {
111+
client.once(client.Event.SDK_UPDATE, (metadata) => {
112+
assert.equal(metadata.type, 'FLAGS_UPDATE', 'SDK_UPDATE for SPLIT_UPDATE should have type FLAGS_UPDATE');
113+
assert.true(Array.isArray(metadata.names), 'metadata.names should be an array');
114+
assert.true(metadata.names.includes('whitelist'), 'metadata.names should include the updated whitelist split');
112115
const lapse = Date.now() - start;
113116
assert.true(nearlyEqual(lapse, MILLIS_FIRST_SPLIT_UPDATE_EVENT), 'SDK_UPDATE due to SPLIT_UPDATE event');
114117
assert.equal(client.getTreatment('whitelist'), 'allowed', 'evaluation of updated Split');
@@ -202,7 +205,9 @@ export function testSynchronization(fetchMock, assert) {
202205

203206
const timestampUnboundEvent = Date.now();
204207

205-
client.once(client.Event.SDK_UPDATE, () => {
208+
client.once(client.Event.SDK_UPDATE, (metadata) => {
209+
assert.equal(metadata.type, 'SEGMENTS_UPDATE', 'SDK_UPDATE for MEMBERSHIPS_LS_UPDATE should have type SEGMENTS_UPDATE');
210+
assert.true(Array.isArray(metadata.names), 'metadata.names should be an array');
206211
assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY_AND_BACKOFF), 'SDK_UPDATE after fetching memberships with a delay');
207212
assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation after myLargeSegment fetch');
208213
});

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export default function (fetchMock, assert) {
179179
events: 'https://events.baseurl/readyFromCacheWithData'
180180
};
181181
localStorage.clear();
182-
t.plan(12 * 2 + 3);
182+
t.plan(12 * 2 + 3 + 2); // +2 for SDK_READY and SDK_READY_FROM_CACHE metadata.initialCacheLoad asserts
183183

184184
fetchMock.get(testUrls.sdk + '/splitChanges?s=1.3&since=25&rbSince=-1', () => {
185185
return new Promise(res => { setTimeout(() => res({ status: 200, body: { ff: { ...splitChangesMock1.ff, s: 25 } }, headers: {} }), 200); }); // 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that.
@@ -225,7 +225,8 @@ export default function (fetchMock, assert) {
225225
t.end();
226226
});
227227

228-
client.on(client.Event.SDK_READY_FROM_CACHE, () => {
228+
client.on(client.Event.SDK_READY_FROM_CACHE, (metadata) => {
229+
t.false(metadata.initialCacheLoad, 'SDK_READY_FROM_CACHE from cache should have initialCacheLoad false');
229230
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.');
230231
t.equal(client.getTreatment('always_on'), 'off', 'It should evaluate treatments with data from cache instead of control due to Input Validation');
231232
});
@@ -238,7 +239,8 @@ export default function (fetchMock, assert) {
238239
t.equal(client3.getTreatment('always_on'), 'off', 'It should evaluate treatments with data from cache instead of control due to Input Validation');
239240
});
240241

241-
client.on(client.Event.SDK_READY, () => {
242+
client.on(client.Event.SDK_READY, (metadata) => {
243+
t.false(metadata.initialCacheLoad, 'SDK_READY when from cache first should have initialCacheLoad false');
242244
t.true(Date.now() - startTime >= 400, 'It should emit SDK_READY too but after syncing with the cloud.');
243245
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
244246
});
@@ -371,8 +373,8 @@ export default function (fetchMock, assert) {
371373
t.true(Date.now() - startTime >= 400, 'It should emit SDK_READY too but after syncing with the cloud.');
372374
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
373375
});
374-
client.whenReadyFromCache().then((isReady) => {
375-
t.false(isReady, 'It should be ready from cache before ready (syncing with the cloud).');
376+
client.whenReadyFromCache().then((metadata) => {
377+
t.false(metadata.initialCacheLoad, 'It should be ready from cache before ready (syncing with the cloud).');
376378
t.true(Date.now() - startTime < 50, 'It should resolve ready from cache promise almost immediately.');
377379
});
378380
client.whenReady().then(() => {
@@ -383,8 +385,8 @@ export default function (fetchMock, assert) {
383385
t.true(Date.now() - startTime >= 700, 'It should emit SDK_READY too but after syncing with the cloud.');
384386
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
385387
});
386-
client2.whenReadyFromCache().then((isReady) => {
387-
t.false(isReady, 'It should be ready from cache before ready (syncing with the cloud).');
388+
client2.whenReadyFromCache().then((metadata) => {
389+
t.false(metadata.initialCacheLoad, 'It should be ready from cache before ready (syncing with the cloud).');
388390
});
389391
client2.whenReady().then(() => {
390392
t.true(Date.now() - startTime >= 700, 'It should resolve ready promise after syncing with the cloud.');
@@ -474,7 +476,9 @@ export default function (fetchMock, assert) {
474476
t.end();
475477
});
476478

477-
client.once(client.Event.SDK_READY_FROM_CACHE, () => {
479+
client.once(client.Event.SDK_READY_FROM_CACHE, (metadata) => {
480+
t.true(metadata.initialCacheLoad, 'SDK_READY_FROM_CACHE on fresh install should have initialCacheLoad true');
481+
t.equal(metadata.lastUpdateTimestamp, undefined, 'lastUpdateTimestamp should be undefined when initialCacheLoad is true');
478482
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should emit SDK_READY_FROM_CACHE alongside SDK_READY');
479483
});
480484
client2.once(client2.Event.SDK_READY_FROM_CACHE, () => {
@@ -484,12 +488,13 @@ export default function (fetchMock, assert) {
484488
t.true(nearlyEqual(Date.now() - startTime, CLIENT3_READY_MS), 'It should emit SDK_READY_FROM_CACHE alongside SDK_READY');
485489
});
486490

487-
client.on(client.Event.SDK_READY, () => {
491+
client.on(client.Event.SDK_READY, (metadata) => {
492+
t.true(metadata.initialCacheLoad, 'SDK_READY on fresh install should have initialCacheLoad true');
488493
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should emit SDK_READY after syncing with the cloud.');
489494
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
490495
});
491-
client.whenReadyFromCache().then((isReady) => {
492-
t.true(isReady, 'It should be ready from cache and ready.');
496+
client.whenReadyFromCache().then((metadata) => {
497+
t.true(metadata.initialCacheLoad, 'It should be ready from cache and ready.');
493498
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should resolve ready from cache promise after syncing with the cloud.');
494499
});
495500
client.whenReady().then(() => {

src/__tests__/browserSuites/ready-promise.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ export default function readyPromiseAssertions(fetchMock, assert) {
521521

522522
consoleSpy.log.resetHistory();
523523
setTimeout(() => {
524-
client.whenReadyFromCache().then((isReady) => t.true(isReady, 'SDK IS READY (& READY FROM CACHE) - Should resolve')).catch(() => t.fail('SDK TIMED OUT - Should not reject'));
524+
client.whenReadyFromCache().then((metadata) => t.true(metadata.initialCacheLoad, 'SDK IS READY (& READY FROM CACHE) - Should resolve')).catch(() => t.fail('SDK TIMED OUT - Should not reject'));
525525

526526
assertGetTreatmentWhenReady(t, client);
527527

0 commit comments

Comments
 (0)