Skip to content

Commit b919cb8

Browse files
Merge pull request #230 from splitio/development
Release v2.1.0
2 parents bbe40c5 + 05d9f67 commit b919cb8

25 files changed

+167
-187
lines changed

CHANGES.txt

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2.1.0 (March 28, 2025)
2+
- Added a new optional `properties` argument to the options object of the `useSplitTreatments` hook, allowing to pass a map of properties to append to the generated impressions sent to Split backend. Read more in our docs.
3+
- Updated @splitsoftware/splitio package to version 11.2.0 that includes some minor updates:
4+
- 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.
5+
- 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:
6+
- `storage.expirationDays` to specify the validity period of the rollout plan cache in days.
7+
- `storage.clearOnInit` to clear the rollout plan cache on SDK initialization.
8+
- 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.
9+
- Updated the internal imports of React library from default to namespace imports as this is the recommended approach for better compatibility with React, TypeScript, ES modules, and tree shaking (https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports).
10+
111
2.0.1 (December 4, 2024)
212
- Updated @splitsoftware/splitio package to version 11.0.3 that includes some improvements and bugfixes.
313
- Updated internal handling of the `updateOnSdkTimedout` param to remove the wrong log "[ERROR] A listener was added for SDK_READY_TIMED_OUT on the SDK, which has already fired and won't be emitted again".

package-lock.json

+115-151
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@splitsoftware/splitio-react",
3-
"version": "2.0.1",
3+
"version": "2.1.0",
44
"description": "A React library to easily integrate and use Split JS SDK",
55
"main": "cjs/index.js",
66
"module": "esm/index.js",
@@ -63,7 +63,7 @@
6363
},
6464
"homepage": "https://github.com/splitio/react-client#readme",
6565
"dependencies": {
66-
"@splitsoftware/splitio": "11.0.3",
66+
"@splitsoftware/splitio": "11.2.0",
6767
"memoize-one": "^5.1.1",
6868
"shallowequal": "^1.1.0",
6969
"tslib": "^2.3.1"

src/SplitClient.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { SplitContext } from './SplitContext';
33
import { ISplitClientProps } from './types';
44
import { useSplitClient } from './useSplitClient';

src/SplitContext.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { ISplitContextValues } from './types';
33
import { EXCEPTION_NO_SFP } from './constants';
44

src/SplitFactoryProvider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22

33
import { ISplitFactoryProviderProps } from './types';
44
import { VERSION, WARN_SF_CONFIG_AND_FACTORY } from './constants';

src/SplitTreatments.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22

33
import { SplitContext } from './SplitContext';
44
import { ISplitTreatmentsProps } from './types';

src/__tests__/SplitClient.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render, act } from '@testing-library/react';
33

44
/** Mocks and test utils */

src/__tests__/SplitContext.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render } from '@testing-library/react';
33
import { SplitContext } from '../SplitContext';
44
import { SplitFactoryProvider } from '../SplitFactoryProvider';

src/__tests__/SplitFactoryProvider.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render, act } from '@testing-library/react';
33

44
/** Mocks */

src/__tests__/SplitTreatments.test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render, RenderResult, act } from '@testing-library/react';
33

44
/** Mocks */
@@ -189,7 +189,7 @@ describe('SplitTreatments', () => {
189189
// once operational (SDK_READY_FROM_CACHE), it evaluates feature flags
190190
act(() => client.__emitter__.emit(Event.SDK_READY_FROM_CACHE));
191191

192-
expect(client.getTreatmentsWithConfig).toBeCalledWith(featureFlagNames, attributes);
192+
expect(client.getTreatmentsWithConfig).toBeCalledWith(featureFlagNames, attributes, undefined);
193193
expect(client.getTreatmentsWithConfig).toHaveReturnedWith(treatments);
194194
});
195195
});

src/__tests__/testUtils/utils.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render } from '@testing-library/react';
33
import { ISplitStatus } from '../../types';
44
const { SplitFactory: originalSplitFactory } = jest.requireActual('@splitsoftware/splitio/client');

src/__tests__/useSplitClient.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { act, render } from '@testing-library/react';
33

44
/** Mocks */

src/__tests__/useSplitManager.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { act, render } from '@testing-library/react';
33

44
/** Mocks */

src/__tests__/useSplitTreatments.test.tsx

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { act, render } from '@testing-library/react';
33

44
/** Mocks */
@@ -23,6 +23,7 @@ describe('useSplitTreatments', () => {
2323
const featureFlagNames = ['split1'];
2424
const flagSets = ['set1'];
2525
const attributes = { att1: 'att1' };
26+
const properties = { prop1: 'prop1' };
2627

2728
test('returns the treatments evaluated by the main client of the factory at Split context, or control if the client is not operational.', () => {
2829
const outerFactory = SplitFactory(sdkBrowser);
@@ -33,8 +34,8 @@ describe('useSplitTreatments', () => {
3334
render(
3435
<SplitFactoryProvider factory={outerFactory} >
3536
{React.createElement(() => {
36-
treatments = useSplitTreatments({ names: featureFlagNames, attributes }).treatments;
37-
treatmentsByFlagSets = useSplitTreatments({ flagSets, attributes }).treatments;
37+
treatments = useSplitTreatments({ names: featureFlagNames, attributes, properties }).treatments;
38+
treatmentsByFlagSets = useSplitTreatments({ flagSets, attributes, properties }).treatments;
3839

3940
// @ts-expect-error Options object must provide either names or flagSets
4041
expect(useSplitTreatments({}).treatments).toEqual({});
@@ -54,10 +55,10 @@ describe('useSplitTreatments', () => {
5455
// once operational (SDK_READY), it evaluates feature flags
5556
act(() => client.__emitter__.emit(Event.SDK_READY));
5657

57-
expect(client.getTreatmentsWithConfig).toBeCalledWith(featureFlagNames, attributes);
58+
expect(client.getTreatmentsWithConfig).toBeCalledWith(featureFlagNames, attributes, { properties });
5859
expect(client.getTreatmentsWithConfig).toHaveReturnedWith(treatments);
5960

60-
expect(client.getTreatmentsWithConfigByFlagSets).toBeCalledWith(flagSets, attributes);
61+
expect(client.getTreatmentsWithConfigByFlagSets).toBeCalledWith(flagSets, attributes, { properties });
6162
expect(client.getTreatmentsWithConfigByFlagSets).toHaveReturnedWith(treatmentsByFlagSets);
6263
});
6364

@@ -69,7 +70,7 @@ describe('useSplitTreatments', () => {
6970
render(
7071
<SplitFactoryProvider factory={outerFactory} >
7172
{React.createElement(() => {
72-
const treatments = useSplitTreatments({ names: featureFlagNames, attributes, splitKey: 'user2', updateOnSdkUpdate: false }).treatments;
73+
const treatments = useSplitTreatments({ names: featureFlagNames, attributes, properties, splitKey: 'user2', updateOnSdkUpdate: false }).treatments;
7374

7475
renderTimes++;
7576
switch (renderTimes) {
@@ -81,7 +82,7 @@ describe('useSplitTreatments', () => {
8182
case 2:
8283
case 3:
8384
// once operational (SDK_READY or SDK_READY_FROM_CACHE), it evaluates feature flags
84-
expect(client.getTreatmentsWithConfig).toHaveBeenLastCalledWith(featureFlagNames, attributes);
85+
expect(client.getTreatmentsWithConfig).toHaveBeenLastCalledWith(featureFlagNames, attributes, { properties });
8586
expect(client.getTreatmentsWithConfig).toHaveLastReturnedWith(treatments);
8687
break;
8788
default:
@@ -209,7 +210,7 @@ describe('useSplitTreatments', () => {
209210
// If useSplitTreatments evaluates with the main client and have default update options, it re-renders for each main client event.
210211
expect(countUseSplitTreatments).toEqual(4);
211212
expect(mainClient.getTreatmentsWithConfig).toHaveBeenCalledTimes(3); // when ready from cache, ready and update
212-
expect(mainClient.getTreatmentsWithConfig).toHaveBeenLastCalledWith(['split_test'], { att1: 'att1' });
213+
expect(mainClient.getTreatmentsWithConfig).toHaveBeenLastCalledWith(['split_test'], { att1: 'att1' }, undefined);
213214

214215
// If useSplitTreatments evaluates with a different client and have default update options, it re-renders for each event of the new client.
215216
expect(countUseSplitTreatmentsUser2).toEqual(4);
@@ -218,7 +219,7 @@ describe('useSplitTreatments', () => {
218219
expect(countUseSplitTreatmentsUser2WithoutUpdate).toEqual(3);
219220
expect(lastUpdateSetUser2WithUpdate.size).toEqual(3);
220221
expect(user2Client.getTreatmentsWithConfig).toHaveBeenCalledTimes(5); // when ready from cache x2, ready x2 and update x1
221-
expect(user2Client.getTreatmentsWithConfig).toHaveBeenLastCalledWith(['split_test'], undefined);
222+
expect(user2Client.getTreatmentsWithConfig).toHaveBeenLastCalledWith(['split_test'], undefined, undefined);
222223
});
223224

224225
test('ignores flagSets and logs a warning if both names and flagSets params are provided.', () => {

src/__tests__/withSplitClient.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render } from '@testing-library/react';
33

44
/** Mocks */

src/__tests__/withSplitFactory.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { render } from '@testing-library/react';
33

44
/** Mocks */

src/__tests__/withSplitTreatments.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { act, render } from '@testing-library/react';
33

44
/** Mocks */

src/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ export type GetTreatmentsOptions = ({
201201
* An object of type Attributes used to evaluate the feature flags.
202202
*/
203203
attributes?: SplitIO.Attributes;
204+
205+
/**
206+
* Optional properties to append to the generated impression object sent to Split backend.
207+
*/
208+
properties?: SplitIO.Properties;
204209
}
205210

206211
/**

src/useSplitClient.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { useSplitContext } from './SplitContext';
33
import { getSplitClient, initAttributes, getStatus } from './utils';
44
import { ISplitContextValues, IUseSplitClientOptions } from './types';

src/useSplitTreatments.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { memoizeGetTreatmentsWithConfig } from './utils';
33
import { ISplitTreatmentsChildProps, IUseSplitTreatmentsOptions } from './types';
44
import { useSplitClient } from './useSplitClient';
@@ -21,13 +21,13 @@ import { useSplitClient } from './useSplitClient';
2121
export function useSplitTreatments(options: IUseSplitTreatmentsOptions): ISplitTreatmentsChildProps {
2222
const context = useSplitClient({ ...options, attributes: undefined });
2323
const { client, lastUpdate } = context;
24-
const { names, flagSets, attributes } = options;
24+
const { names, flagSets, attributes, properties } = options;
2525

2626
const getTreatmentsWithConfig = React.useMemo(memoizeGetTreatmentsWithConfig, []);
2727

2828
// Shallow copy `client.getAttributes` result for memoization, as it returns the same reference unless `client.clearAttributes` is invoked.
2929
// Note: the same issue occurs with the `names` and `attributes` arguments if they are mutated directly by the user instead of providing a new object.
30-
const treatments = getTreatmentsWithConfig(client, lastUpdate, names, attributes, client ? { ...client.getAttributes() } : {}, flagSets);
30+
const treatments = getTreatmentsWithConfig(client, lastUpdate, names, attributes, client ? { ...client.getAttributes() } : {}, flagSets, properties && { properties });
3131

3232
return {
3333
...context,

src/utils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,13 @@ function argsAreEqual(newArgs: any[], lastArgs: any[]): boolean {
150150
shallowEqual(newArgs[5], lastArgs[5]); // flagSets
151151
}
152152

153-
function evaluateFeatureFlags(client: SplitIO.IBrowserClient | undefined, _lastUpdate: number, names?: SplitIO.SplitNames, attributes?: SplitIO.Attributes, _clientAttributes?: SplitIO.Attributes, flagSets?: string[]) {
153+
function evaluateFeatureFlags(client: SplitIO.IBrowserClient | undefined, _lastUpdate: number, names?: SplitIO.SplitNames, attributes?: SplitIO.Attributes, _clientAttributes?: SplitIO.Attributes, flagSets?: string[], options?: SplitIO.EvaluationOptions) {
154154
if (names && flagSets) console.log(WARN_NAMES_AND_FLAGSETS);
155155

156156
return client && (client as IClientWithContext).__getStatus().isOperational && (names || flagSets) ?
157157
names ?
158-
client.getTreatmentsWithConfig(names, attributes) :
159-
client.getTreatmentsWithConfigByFlagSets(flagSets!, attributes) :
158+
client.getTreatmentsWithConfig(names, attributes, options) :
159+
client.getTreatmentsWithConfigByFlagSets(flagSets!, attributes, options) :
160160
names ?
161161
getControlTreatmentsWithConfig(names) :
162162
{} // empty object when evaluating with flag sets and client is not ready

src/withSplitClient.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { ISplitClientChildProps } from './types';
33
import { SplitClient } from './SplitClient';
44

src/withSplitFactory.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { ISplitFactoryChildProps } from './types';
33
import { SplitFactoryProvider } from './SplitFactoryProvider';
44
import { SplitClient } from './SplitClient';

src/withSplitTreatments.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { ISplitTreatmentsChildProps } from './types';
33
import { SplitTreatments } from './SplitTreatments';
44

0 commit comments

Comments
 (0)