You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGES.txt
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,7 @@
2
2
- Added two new configuration options for the SDK's `LOCALSTORAGE` storage type to control the behavior of the persisted rollout plan cache in the browser:
3
3
- `storage.expirationDays` to specify the validity period of the rollout plan cache in days.
4
4
- `storage.clearOnInit` to clear the rollout plan cache on SDK initialization.
5
+
- Updated SDK_READY_FROM_CACHE event when using the `LOCALSTORAGE` storage type to be emitted alongside the SDK_READY event if it has not already been emitted.
5
6
6
7
11.1.0 (January 17, 2025)
7
8
- Added support for the new impressions tracking toggle available on feature flags, both respecting the setting and including the new field being returned on `SplitView` type objects. Read more in our docs.
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: { ...splitChangesMock1,since: 25},headers: {}}),200);});// 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that.
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: membershipsNicolas,headers: {}}),400);});// First client gets segments before splits. No segment cache loading (yet)
t.equal(localStorage.getItem('readyFromCache_3.SPLITIO.split.always_on'),alwaysOnSplitInverted,'feature flags must not be cleaned from cache');
260
259
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: { ...splitChangesMock1,since: 25},headers: {}}),200);});// 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that.
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: membershipsNicolas,headers: {}}),400);});// First client gets segments before splits. No segment cache loading (yet)
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: membershipsNicolas,headers: {}}),400);});// First client gets segments before splits. No segment cache loading (yet)
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: membershipsNicolas,headers: {}}),CLIENT_READY_MS);});// First client gets segments before splits. No segment cache loading (yet)
returnnewPromise(res=>{setTimeout(()=>res({status: 200,body: {'ms': {}},headers: {}}),CLIENT3_READY_MS);});// Third client memberships will come after 1s
t.fail('It should not emit SDK_READY_FROM_CACHE if there is expired cache.');
435
-
t.end();
433
+
t.true(nearlyEqual(Date.now()-startTime,CLIENT3_READY_MS),'It should emit SDK_READY_FROM_CACHE alongside SDK_READY');
436
434
});
437
435
438
436
client.on(client.Event.SDK_READY,()=>{
439
-
t.true(Date.now()-startTime>=400,'It should emit SDK_READY after syncing with the cloud.');
437
+
t.true(nearlyEqual(Date.now()-startTime,CLIENT_READY_MS),'It should emit SDK_READY after syncing with the cloud.');
440
438
t.equal(client.getTreatment('always_on'),'on','It should evaluate treatments with updated data after syncing with the cloud.');
441
439
});
442
440
client.ready().then(()=>{
443
-
t.true(Date.now()-startTime>=400,'It should resolve ready promise after syncing with the cloud.');
441
+
t.true(nearlyEqual(Date.now()-startTime,CLIENT_READY_MS),'It should resolve ready promise after syncing with the cloud.');
444
442
t.equal(client.getTreatment('always_on'),'on','It should evaluate treatments with updated data after syncing with the cloud.');
445
443
});
446
444
client2.on(client2.Event.SDK_READY,()=>{
447
-
t.true(Date.now()-startTime>=700,'It should emit SDK_READY after syncing with the cloud.');
445
+
t.true(nearlyEqual(Date.now()-startTime,CLIENT2_READY_MS),'It should emit SDK_READY after syncing with the cloud.');
448
446
t.equal(client2.getTreatment('always_on'),'on','It should evaluate treatments with updated data after syncing with the cloud.');
449
447
});
450
448
client2.ready().then(()=>{
451
-
t.true(Date.now()-startTime>=700,'It should resolve ready promise after syncing with the cloud.');
449
+
t.true(nearlyEqual(Date.now()-startTime,CLIENT2_READY_MS),'It should resolve ready promise after syncing with the cloud.');
452
450
t.equal(client2.getTreatment('always_on'),'on','It should evaluate treatments with updated data after syncing with the cloud.');
453
451
});
454
452
client3.on(client3.Event.SDK_READY,()=>{
455
453
client3.ready().then(()=>{
456
-
t.true(Date.now()-startTime>=1000,'It should resolve ready promise after syncing with the cloud.');
454
+
t.true(nearlyEqual(Date.now()-startTime,CLIENT3_READY_MS),'It should resolve ready promise after syncing with the cloud.');
457
455
t.equal(client3.getTreatment('always_on'),'on','It should evaluate treatments with updated data after syncing with the cloud.');
458
456
459
457
// Last cb: destroy clients and check that localstorage has the expected items
@@ -486,7 +484,7 @@ export default function (fetchMock, assert) {
486
484
events: 'https://events.baseurl/readyFromCache_5'
487
485
};
488
486
localStorage.clear();
489
-
t.plan(7);
487
+
t.plan(8);
490
488
491
489
fetchMock.getOnce(testUrls.sdk+'/splitChanges?s=1.2&since=-1&names=p1__split,p2__split',{status: 200,body: {splits: [splitDeclarations.p1__split,splitDeclarations.p2__split],since: -1,till: 1457552620999}},{delay: 10});// short delay to let emit SDK_READY_FROM_CACHE
fetchMock.getOnce(testUrls.sdk+'/splitChanges?s=1.2&since=-1&names=p1__split,p2__split',{status: 200,body: {splits: [splitDeclarations.p1__split,splitDeclarations.p2__split],since: -1,till: 1457552620999}},{delay: 10});// short delay to let emit SDK_READY_FROM_CACHE
t.fail('It should not emit SDK_READY_FROM_CACHE if cache is empty.');
561
-
t.end();
557
+
t.true(client.__getStatus().isReady,'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
562
558
});
563
559
564
560
client.once(client.Event.SDK_READY,()=>{
@@ -630,7 +626,7 @@ export default function (fetchMock, assert) {
630
626
events: 'https://events.baseurl/readyFromCache_7'
631
627
};
632
628
localStorage.clear();
633
-
t.plan(6);
629
+
t.plan(7);
634
630
635
631
fetchMock.getOnce(testUrls.sdk+'/splitChanges?s=1.2&since=-1&prefixes=p1,p2',{status: 200,body: {splits: [splitDeclarations.p1__split,splitDeclarations.p2__split],since: -1,till: 1457552620999}},{delay: 10});// short delay to let emit SDK_READY_FROM_CACHE
t.fail('It should not emit SDK_READY_FROM_CACHE if cache has expired.');
663
-
t.end();
658
+
t.true(client.__getStatus().isReady,'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
664
659
});
665
660
666
661
client.once(client.Event.SDK_READY,()=>{
@@ -696,7 +691,7 @@ export default function (fetchMock, assert) {
696
691
events: 'https://events.baseurl/readyFromCache_8'
697
692
};
698
693
localStorage.clear();
699
-
t.plan(7);
694
+
t.plan(8);
700
695
701
696
fetchMock.getOnce(testUrls.sdk+'/splitChanges?s=1.2&since=-1',{status: 200,body: {splits: [splitDeclarations.p1__split,splitDeclarations.p2__split,splitDeclarations.p3__split],since: -1,till: 1457552620999}},{delay: 10});// short delay to let emit SDK_READY_FROM_CACHE
t.fail('It should not emit SDK_READY_FROM_CACHE because all feature flags were removed from cache since the filter query changed.');
725
-
t.end();
719
+
t.true(client.__getStatus().isReady,'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY');
726
720
});
727
721
728
722
client.once(client.Event.SDK_READY,()=>{
@@ -823,10 +817,12 @@ export default function (fetchMock, assert) {
823
817
824
818
t.true(console.log.calledWithMatch('clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache'),'It should log a message about cleaning up cache');
825
819
826
-
client.once(client.Event.SDK_READY_FROM_CACHE,()=>t.fail('It should not emit SDK_READY_FROM_CACHE because clearOnInit is true.'));
t.true(client.__getStatus().isReady,'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
822
+
});
827
823
828
824
awaitclient.ready();
829
-
t.equal(manager.names().sort().length,32,'active splits should be present for evaluation');
825
+
t.equal(manager.names().sort().length,33,'active splits should be present for evaluation');
830
826
831
827
awaitsplitio.destroy();
832
828
t.equal(localStorage.getItem('readyFromCache_10.SPLITIO.splits.till'),'1457552620999','splits.till must correspond to the till of the last successfully fetched Splits');
@@ -843,7 +839,7 @@ export default function (fetchMock, assert) {
t.equal(manager.names().sort().length,32,'active splits should be present for evaluation');
842
+
t.equal(manager.names().sort().length,33,'active splits should be present for evaluation');
847
843
t.false(console.log.calledWithMatch('clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache'),'It should log a message about cleaning up cache');
848
844
849
845
awaitsplitio.destroy();
@@ -858,11 +854,13 @@ export default function (fetchMock, assert) {
858
854
client=splitio.client();
859
855
manager=splitio.manager();
860
856
861
-
client.once(client.Event.SDK_READY_FROM_CACHE,()=>t.fail('It should not emit SDK_READY_FROM_CACHE because clearOnInit is true.'));
t.equal(manager.names().sort().length,32,'active splits should be present for evaluation');
863
+
t.equal(manager.names().sort().length,33,'active splits should be present for evaluation');
866
864
t.true(console.log.calledWithMatch('clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache'),'It should log a message about cleaning up cache');
0 commit comments