Skip to content

Commit c90509f

Browse files
Merge branch 'development' into FME-10595-add-evaluation-hooks
2 parents f75708f + 3ced1c1 commit c90509f

13 files changed

+65
-109
lines changed

CHANGES.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
2.6.0 (October XX, 2025)
1+
2.6.0 (October 31, 2025)
22
- Added `useTreatment`, `useTreatments`, `useTreatmentWithConfig` and `useTreatmentsWithConfig` hooks to replace the now deprecated `useSplitTreatments` hook.
3-
- Updated @splitsoftware/splitio package to version 11.7.1 that includes minor updates:
3+
- Updated @splitsoftware/splitio package to version 11.8.0 that includes minor updates:
4+
- 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.
45
- Added support for custom loggers: added `logger` configuration option and `factory.Logger.setLogger` method to allow the SDK to use a custom logger.
6+
- Updated the SDK_READY_FROM_CACHE event to be emitted alongside the SDK_READY event if it hasn’t already been emitted.
57

68
2.5.0 (September 18, 2025)
79
- Updated @splitsoftware/splitio package to version 11.6.0 that includes minor updates:

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
},
6464
"homepage": "https://github.com/splitio/react-client#readme",
6565
"dependencies": {
66-
"@splitsoftware/splitio": "11.7.1",
66+
"@splitsoftware/splitio": "11.7.2-rc.4",
6767
"memoize-one": "^5.1.1",
6868
"shallowequal": "^1.1.0",
6969
"tslib": "^2.3.1"

src/__tests__/SplitClient.test.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ describe('SplitClient', () => {
5656
client: outerFactory.client(),
5757
isReady: true,
5858
isReadyFromCache: true,
59+
isOperational: true,
5960
lastUpdate: getStatus(outerFactory.client()).lastUpdate
6061
});
6162

@@ -141,7 +142,7 @@ describe('SplitClient', () => {
141142
expect(statusProps).toStrictEqual([false, false, true, true]);
142143
break;
143144
case 2: // Updated. Although `updateOnSdkReady` is false, status props must reflect the current status of the client.
144-
expect(statusProps).toStrictEqual([true, false, true, false]);
145+
expect(statusProps).toStrictEqual([true, true, true, false]);
145146
break;
146147
default:
147148
fail('Child must not be rerendered');
@@ -182,7 +183,7 @@ describe('SplitClient', () => {
182183
expect(statusProps).toStrictEqual([false, false, false, false]);
183184
break;
184185
case 1: // Ready
185-
expect(statusProps).toStrictEqual([true, false, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
186+
expect(statusProps).toStrictEqual([true, true, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
186187
break;
187188
default:
188189
fail('Child must not be rerendered');
@@ -214,7 +215,7 @@ describe('SplitClient', () => {
214215
count++;
215216

216217
// side effect in the render phase
217-
if (!(client as any).__getStatus().isReady) {
218+
if (!client!.getStatus().isReady) {
218219
(client as any).__emitter__.emit(Event.SDK_READY);
219220
}
220221

@@ -318,11 +319,11 @@ describe('SplitClient', () => {
318319
break;
319320
case 4:
320321
expect(client).toBe(outerFactory.client('user3'));
321-
expect(statusProps).toStrictEqual([true, false, false, false]);
322+
expect(statusProps).toStrictEqual([true, true, false, false]);
322323
break;
323324
case 5:
324325
expect(client).toBe(outerFactory.client('user3'));
325-
expect(statusProps).toStrictEqual([true, false, false, false]);
326+
expect(statusProps).toStrictEqual([true, true, false, false]);
326327
break;
327328
default:
328329
fail('Child must not be rerendered');
@@ -501,7 +502,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
501502
expect(statusProps).toStrictEqual([false, false, true, true]);
502503
break;
503504
case 2: // Updated. Although `updateOnSdkReady` is false, status props must reflect the current status of the client.
504-
expect(statusProps).toStrictEqual([true, false, true, false]);
505+
expect(statusProps).toStrictEqual([true, true, true, false]);
505506
break;
506507
default:
507508
fail('Child must not be rerendered');
@@ -542,7 +543,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
542543
expect(statusProps).toStrictEqual([false, false, true, true]);
543544
break;
544545
case 2: // Updated. Although `updateOnSdkReady` is false, status props must reflect the current status of the client.
545-
expect(statusProps).toStrictEqual([true, false, true, false]);
546+
expect(statusProps).toStrictEqual([true, true, true, false]);
546547
break;
547548
default:
548549
fail('Child must not be rerendered');
@@ -578,7 +579,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
578579
expect(statusProps).toStrictEqual([false, false, false, false]);
579580
break;
580581
case 1: // Ready
581-
expect(statusProps).toStrictEqual([true, false, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
582+
expect(statusProps).toStrictEqual([true, true, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
582583
break;
583584
default:
584585
fail('Child must not be rerendered');
@@ -615,7 +616,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
615616
expect(statusProps).toStrictEqual([false, false, false, false]);
616617
break;
617618
case 1: // Ready
618-
expect(statusProps).toStrictEqual([true, false, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
619+
expect(statusProps).toStrictEqual([true, true, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
619620
break;
620621
default:
621622
fail('Child must not be rerendered');

src/__tests__/SplitFactoryProvider.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ describe('SplitFactoryProvider', () => {
7070
client: outerFactory.client(),
7171
isReady: true,
7272
isReadyFromCache: true,
73+
isOperational: true,
7374
lastUpdate: getStatus(outerFactory.client()).lastUpdate
7475
});
7576
return null;

src/__tests__/SplitTreatments.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('SplitTreatments', () => {
6969
expect(clientMock.getTreatmentsWithConfig.mock.calls.length).toBe(1);
7070
expect(treatments).toBe(clientMock.getTreatmentsWithConfig.mock.results[0].value);
7171
expect(featureFlagNames).toBe(clientMock.getTreatmentsWithConfig.mock.calls[0][0]);
72-
expect([isReady2, isReadyFromCache, hasTimedout, isTimedout, isDestroyed, lastUpdate]).toStrictEqual([true, false, false, false, false, getStatus(outerFactory.client()).lastUpdate]);
72+
expect([isReady2, isReadyFromCache, hasTimedout, isTimedout, isDestroyed, lastUpdate]).toStrictEqual([true, true, false, false, false, getStatus(outerFactory.client()).lastUpdate]);
7373
return null;
7474
}}
7575
</SplitTreatments>

src/__tests__/testUtils/mockSplitFactory.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function mockSdk() {
5454
}
5555

5656
const __emitter__ = new EventEmitter();
57-
__emitter__.on(Event.SDK_READY, () => { isReady = true; syncLastUpdate(); });
57+
__emitter__.on(Event.SDK_READY, () => { isReady = true; isReadyFromCache = true; syncLastUpdate(); });
5858
__emitter__.on(Event.SDK_READY_FROM_CACHE, () => { isReadyFromCache = true; syncLastUpdate(); });
5959
__emitter__.on(Event.SDK_READY_TIMED_OUT, () => { hasTimedout = true; syncLastUpdate(); });
6060
__emitter__.on(Event.SDK_UPDATE, () => { syncLastUpdate(); });
@@ -96,13 +96,13 @@ export function mockSdk() {
9696
else { __emitter__.on(Event.SDK_READY_TIMED_OUT, rej); }
9797
});
9898
});
99-
const __getStatus = () => ({
99+
const getStatus = () => ({
100100
isReady,
101101
isReadyFromCache,
102102
isTimedout: hasTimedout && !isReady,
103103
hasTimedout,
104104
isDestroyed,
105-
isOperational: (isReady || isReadyFromCache) && !isDestroyed,
105+
isOperational: isReadyFromCache && !isDestroyed,
106106
lastUpdate,
107107
});
108108
const destroy: jest.Mock = jest.fn(() => {
@@ -122,10 +122,9 @@ export function mockSdk() {
122122
setAttributes,
123123
clearAttributes,
124124
getAttributes,
125+
getStatus,
125126
// EventEmitter exposed to trigger events manually
126127
__emitter__,
127-
// Clients expose a `__getStatus` method, that is not considered part of the public API, to get client readiness status (isReady, isReadyFromCache, isOperational, hasTimedout, isDestroyed)
128-
__getStatus,
129128
// Restore the mock client to its initial NO-READY status.
130129
// Useful when you want to reuse the same mock between tests after emitting events or destroying the instance.
131130
__restore() {

src/__tests__/testUtils/utils.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ export const INITIAL_STATUS: ISplitStatus & IUpdateProps = {
123123
hasTimedout: false,
124124
lastUpdate: 0,
125125
isDestroyed: false,
126+
isOperational: false,
126127
updateOnSdkReady: true,
127128
updateOnSdkReadyFromCache: true,
128129
updateOnSdkTimedout: true,

src/__tests__/useSplitClient.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ describe('useSplitClient', () => {
207207

208208
// side effect in the render phase
209209
const client = outerFactory.client('some_user') as any;
210-
if (!client.__getStatus().isReady) client.__emitter__.emit(Event.SDK_READY);
210+
if (!client.getStatus().isReady) client.__emitter__.emit(Event.SDK_READY);
211211

212212
return null;
213213
})}
@@ -256,7 +256,7 @@ describe('useSplitClient', () => {
256256

257257
act(() => mainClient.__emitter__.emit(Event.SDK_READY)); // trigger re-render
258258
expect(rendersCount).toBe(5);
259-
expect(currentStatus).toMatchObject({ isReady: true, isReadyFromCache: false, hasTimedout: true });
259+
expect(currentStatus).toMatchObject({ isReady: true, isReadyFromCache: true, hasTimedout: true });
260260

261261
act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // do not trigger re-render because updateOnSdkUpdate is false
262262
expect(rendersCount).toBe(5);

src/__tests__/useSplitManager.test.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ describe('useSplitManager', () => {
4848
hasTimedout: false,
4949
isDestroyed: false,
5050
isReady: true,
51-
isReadyFromCache: false,
51+
isReadyFromCache: true,
5252
isTimedout: false,
53+
isOperational: true,
5354
lastUpdate: getStatus(outerFactory.client()).lastUpdate,
5455
});
5556
});
@@ -98,8 +99,9 @@ describe('useSplitManager', () => {
9899
hasTimedout: false,
99100
isDestroyed: false,
100101
isReady: true,
101-
isReadyFromCache: false,
102+
isReadyFromCache: true,
102103
isTimedout: false,
104+
isOperational: true,
103105
lastUpdate: getStatus(outerFactory.client()).lastUpdate,
104106
});
105107
});

0 commit comments

Comments
 (0)