Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare release v1.10.0 #169

Merged
merged 101 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
000345c
rename getSplitSharedClient to getSplitClient
EmilianoSanchez Jul 8, 2023
6d2e878
remove asserts on internal event listeners, unit test should not vali…
EmilianoSanchez Jul 8, 2023
2d04ca8
Updated getSplitClient util to set client lastUpdate timestamp, and u…
EmilianoSanchez Jul 8, 2023
67aeb8b
fix useSplitClient to update when the client is ready or ready from c…
EmilianoSanchez Jul 8, 2023
c002bf6
support update options in useSplitClient and useSplitTreatments
EmilianoSanchez Jul 8, 2023
23bd2ea
removed unnecessary non-null assertion operator
EmilianoSanchez Jul 17, 2023
172a78b
added unit test for useSplitTreatments
EmilianoSanchez Jul 17, 2023
a9b2662
added extra asserts
EmilianoSanchez Jul 17, 2023
d98568f
Merge branch 'hooks_rerender' into hooks_update_options
EmilianoSanchez Jul 17, 2023
637934a
update unit tests for useSplitTreatments
EmilianoSanchez Jul 17, 2023
509ba9a
export new hooks. add 'options' param to useClient and useTreatments …
EmilianoSanchez Jul 17, 2023
9cb112d
update type definitions
EmilianoSanchez Jul 17, 2023
44f0d13
optimize evaluation on useSplitTreatments using a memoized version of…
EmilianoSanchez Jul 17, 2023
7f64178
adding a delay on test, to reduce flakiness
EmilianoSanchez Jul 17, 2023
1239b3e
Rename getSplitSharedClient to getSplitClient, and reuse in SplitFact…
EmilianoSanchez Jul 18, 2023
91e4cc1
fix useSplitClient
EmilianoSanchez Jul 18, 2023
a72c49f
added eslint-plugin-react-hooks to linter, to enforce rules of hooks
EmilianoSanchez Jul 21, 2023
4ee1f42
removed unused string messages
EmilianoSanchez Jul 22, 2023
b2bc62d
Merge branch 'rules_of_hooks' into client_lastUpdate
EmilianoSanchez Jul 22, 2023
3f1d6c7
simplify ternary expression
EmilianoSanchez Jul 22, 2023
15069cf
Merge branch 'client_lastUpdate' into hooks_rerender
EmilianoSanchez Jul 22, 2023
d3def5b
Merge branch 'hooks_rerender' into hooks_update_options
EmilianoSanchez Jul 22, 2023
3bf15e9
Merge branch 'hooks_update_options' into hooks_export
EmilianoSanchez Jul 22, 2023
07cceca
fixed useSplitClient to support changes on update options
EmilianoSanchez Jul 22, 2023
8345e49
Merge branch 'hooks_update_options' into hooks_polishing
EmilianoSanchez Jul 22, 2023
306b522
update comments
EmilianoSanchez Jul 22, 2023
2fdf2f0
added optimization tests
EmilianoSanchez Jul 22, 2023
f0ce66a
remove unnecessary delays and setTimeout in tests
EmilianoSanchez Jul 22, 2023
261c038
test polishing
EmilianoSanchez Jul 22, 2023
9dfa4bf
add useTreatments test
EmilianoSanchez Jul 23, 2023
38d5119
changelog
EmilianoSanchez Jul 23, 2023
8d45e0f
Merge branch 'hooks_polishing' into hooks_export
EmilianoSanchez Jul 23, 2023
567ed42
update test
EmilianoSanchez Jul 23, 2023
6b37b37
useTrack update
EmilianoSanchez Aug 15, 2023
7d0f0a8
polishing
EmilianoSanchez Jul 23, 2023
ad77048
Merge branch 'hooks_baseline' into rules_of_hooks
EmilianoSanchez Sep 11, 2023
4485bdf
Merge pull request #159 from splitio/rules_of_hooks
EmilianoSanchez Sep 11, 2023
9cccbed
Merge branch 'hooks_baseline' into client_lastUpdate
EmilianoSanchez Sep 11, 2023
a99c456
Merge pull request #160 from splitio/client_lastUpdate
EmilianoSanchez Sep 13, 2023
0cee224
Merge branch 'hooks_baseline' into hooks_rerender
EmilianoSanchez Sep 13, 2023
0cff3eb
reuse DEFAULT_UPDATE_OPTIONS const
EmilianoSanchez Sep 13, 2023
c7ceb17
Merge pull request #151 from splitio/hooks_rerender
EmilianoSanchez Sep 13, 2023
01ef2db
export TypeScript types and interfaces from the library index
EmilianoSanchez Sep 13, 2023
0fce4b5
Merge pull request #163 from splitio/export_types
EmilianoSanchez Sep 13, 2023
032d849
Merge branch 'hooks_baseline' into hooks_update_options
EmilianoSanchez Sep 14, 2023
f1cc018
Remove unnecessary 'async' keyword from tests
EmilianoSanchez Sep 14, 2023
7eb452f
Merge branch 'hooks_update_options' into hooks_polishing
EmilianoSanchez Sep 14, 2023
70c4a97
Add changelog entry
EmilianoSanchez Sep 14, 2023
70023d6
Merge branch 'hooks_polishing' into hooks_export
EmilianoSanchez Sep 14, 2023
7828904
prepare rc
EmilianoSanchez Sep 14, 2023
a85623b
Fix typo
EmilianoSanchez Sep 14, 2023
1eed73d
Merge pull request #152 from splitio/hooks_update_options
EmilianoSanchez Sep 19, 2023
6d8bd73
fix typo
EmilianoSanchez Oct 5, 2023
5c5274b
add comment about useTrack implementation
EmilianoSanchez Oct 5, 2023
6e94a5b
Merge pull request #154 from splitio/hooks_polishing
EmilianoSanchez Nov 2, 2023
f41f1c6
Merge branch 'development' into hooks_baseline
EmilianoSanchez Nov 2, 2023
d15e1b3
implementation of new hooks with options object
EmilianoSanchez Nov 2, 2023
fe6bc13
Merge branch 'hooks_options_object' into hooks_export
EmilianoSanchez Nov 2, 2023
064a872
update CHANGES log entry
EmilianoSanchez Nov 2, 2023
3af2878
update README and do some polishing
EmilianoSanchez Nov 2, 2023
a30854b
add useSplitManager
EmilianoSanchez Nov 2, 2023
7318154
add useSplitManager test
EmilianoSanchez Nov 2, 2023
ec5a663
add flagSets prop to SplitTreatments component and flagSets property …
EmilianoSanchez Nov 2, 2023
601f7dc
using union to restrict that either 'names' or 'flagSets' is required…
EmilianoSanchez Nov 2, 2023
fe25859
update tests to avoid duplicated
EmilianoSanchez Nov 10, 2023
9d2ba00
Merge pull request #166 from splitio/hooks_options_object
EmilianoSanchez Nov 10, 2023
3629879
Merge branch 'hooks_baseline' into hooks_export
EmilianoSanchez Nov 10, 2023
72ad79a
Merge branch 'hooks_export' into hooks_useSplitManager
EmilianoSanchez Nov 10, 2023
f8c13c3
update useManager test to avoid duplication of tests
EmilianoSanchez Nov 10, 2023
7bbe38f
Merge branch 'hooks_baseline' into flagSets
EmilianoSanchez Nov 10, 2023
fe02e05
Add tests
EmilianoSanchez Nov 13, 2023
50299e7
Add test to validate that the useSplitManager hook updates when the c…
EmilianoSanchez Nov 13, 2023
75bddec
Update test
EmilianoSanchez Nov 13, 2023
af209f8
Update deprecation comment
EmilianoSanchez Nov 13, 2023
209a412
Update doc comments
EmilianoSanchez Nov 13, 2023
01746e3
Merge branch 'hooks_export' into hooks_useSplitManager
EmilianoSanchez Nov 13, 2023
43f7213
Update deprecation comment
EmilianoSanchez Nov 13, 2023
91aeb65
changelog polishing
EmilianoSanchez Nov 13, 2023
815b49b
replace the 'split' term with 'feature flag'
EmilianoSanchez Nov 13, 2023
6fd7c7e
Add changelog entry
EmilianoSanchez Nov 13, 2023
3f24e24
Update JS SDK version
EmilianoSanchez Nov 13, 2023
dadcdc6
Add 'types' folder to .gitignore, because it's generated by the build…
EmilianoSanchez Nov 14, 2023
ecd1b0c
Stop versioning 'types' folder. No need to track since it's auto-gene…
EmilianoSanchez Nov 14, 2023
3e726f9
Merge pull request #153 from splitio/hooks_export
EmilianoSanchez Nov 14, 2023
cc66cad
Merge branch 'hooks_baseline' into hooks_useSplitManager
EmilianoSanchez Nov 14, 2023
20091ca
Merge branch 'hooks_baseline' into flagSets
EmilianoSanchez Nov 14, 2023
902c38b
polishing
EmilianoSanchez Nov 14, 2023
9ea53a0
Update type definition comment for names and flagSets params
EmilianoSanchez Nov 14, 2023
2a59f36
Reuse GetTreatmentsOptions type
EmilianoSanchez Nov 14, 2023
accf9d2
Specialize the GetTreatmentsOptions type to mutually exclude names an…
EmilianoSanchez Nov 14, 2023
ff6e4a3
Merge branch 'hooks_useSplitManager' into flagSets_xor
EmilianoSanchez Nov 14, 2023
44c4b90
prepare rc
EmilianoSanchez Nov 14, 2023
a46a180
polishing
EmilianoSanchez Nov 15, 2023
9d01751
Fix indentation in CHANGES.txt file
EmilianoSanchez Nov 15, 2023
c42fd8c
Replace @return with @returns, which is the correct JSDoc tag
EmilianoSanchez Nov 15, 2023
1424ab3
Merge pull request #167 from splitio/hooks_useSplitManager
EmilianoSanchez Nov 15, 2023
78bece2
Merge branch 'hooks_baseline' into flagSets
EmilianoSanchez Nov 15, 2023
9dd8b46
Merge branch 'flagSets_xor' into flagSets
EmilianoSanchez Nov 15, 2023
fab73a0
prepare stable version
EmilianoSanchez Nov 15, 2023
263ee5c
update changes entry
EmilianoSanchez Nov 15, 2023
45c9b7e
Merge pull request #168 from splitio/flagSets
EmilianoSanchez Nov 15, 2023
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
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module.exports = {
'extends': [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended'
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended'
],
'parser': '@typescript-eslint/parser',
'parserOptions': {
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
/lib
/es
/umd
/types
/coverage
.scannerwork
16 changes: 14 additions & 2 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
1.9.1 (October XX, 2023)
- Updated type definitions of the library components to not restrict the type of the `children` prop to ReactElement, allowing to pass any valid ReactNode value (Related to issue https://github.com/splitio/react-client/issues/164).
1.10.0 (November 16, 2023)
- Added support for Flag Sets on the SDK, which enables grouping feature flags and interacting with the group rather than individually (more details in our documentation):
- Added a new `flagSets` prop to the `SplitTreatments` component and `flagSets` option to the `useSplitTreatments` hook options object, to support evaluating flags in given flag set/s. Either `names` or `flagSets` must be provided to the component and hook. If both are provided, `names` will be used.
- Added a new optional Split Filter configuration option. This allows the SDK and Split services to only synchronize the flags in the specified flag sets, avoiding unused or unwanted flags from being synced on the SDK instance, bringing all the benefits from a reduced payload.
- Added `sets` property to the `SplitView` object returned by the `split` and `splits` methods of the SDK manager to expose flag sets on flag views.
- Added new `useSplitClient`, `useSplitTreatments` and `useSplitManager` hooks as replacements for the now deprecated `useClient`, `useTreatments` and `useManager` hooks.
- These new hooks return the Split context object along with the SDK client, treatments and manager respectively, enabling direct access to status properties like `isReady`, eliminating the need for using the `useContext` hook or the client's `ready` promise.
- `useSplitClient` and `useSplitTreatments` accept an options object as parameter, which support the same arguments as their predecessors, with additional boolean options for controlling re-rendering: `updateOnSdkReady`, `updateOnSdkReadyFromCache`, `updateOnSdkTimedout`, and `updateOnSdkUpdate`.
- `useSplitTreatments` optimizes feature flag evaluations by using the `useMemo` hook to memoize `getTreatmentsWithConfig` method calls from the SDK. This avoids re-evaluating feature flags when the hook is called with the same options and the feature flag definitions have not changed.
- They fixed a bug in the deprecated `useClient` and `useTreatments` hooks, which caused them to not re-render and re-evaluate feature flags when they access a different SDK client than the context and its status updates (i.e., when it emits SDK_READY or other event).
- Added TypeScript types and interfaces to the library index exports, allowing them to be imported from the library index, e.g., `import type { ISplitFactoryProps } from '@splitsoftware/splitio-react'` (Related to issue https://github.com/splitio/react-client/issues/162).
- Updated type declarations of the library components to not restrict the type of the `children` prop to ReactElement, allowing to pass any valid ReactNode value (Related to issue https://github.com/splitio/react-client/issues/164).
- Updated linter and other dependencies for vulnerability fixes.
- Bugfixing - Removed conditional code within hooks to adhere to the rules of hooks and prevent React warnings. Previously, this code checked for the availability of the hooks API (available in React version 16.8.0 or above) and logged an error message. Now, using hooks with React versions below 16.8.0 will throw an error.
- Bugfixing - Updated `useClient` and `useTreatments` hooks to re-render and re-evaluate feature flags when they consume a different SDK client than the context and its status updates (i.e., when it emits SDK_READY or other event).

1.9.0 (July 18, 2023)
- Updated some transitive dependencies for vulnerability fixes.
Expand Down
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Below is a simple example that describes the instantiation and most basic usage
import React from 'react';

// Import SDK functions
import { SplitFactory, SplitTreatments } from '@splitsoftware/splitio-react';
import { SplitFactory, useSplitTreatments } from '@splitsoftware/splitio-react';

// Define your config object
const CONFIG = {
Expand All @@ -30,25 +30,27 @@ const CONFIG = {
}
};

function MyReactComponent() {
function MyComponent() {
// Evaluate feature flags with useSplitTreatments hook
const { treatments: { FEATURE_FLAG_NAME }, isReady } = useSplitTreatments({ names: ['FEATURE_FLAG_NAME'] });

// Check SDK readiness using isReady prop
if (!isReady) return <div>Loading SDK ...</div>;

if (FEATURE_FLAG_NAME.treatment === 'on') {
// return JSX for on treatment
} else if (FEATURE_FLAG_NAME.treatment === 'off') {
// return JSX for off treatment
} else {
// return JSX for control treatment
};
}

function MyApp() {
return (
/* Use SplitFactory to instantiate the SDK and makes it available to nested components */
// Use SplitFactory to instantiate the SDK and makes it available to nested components
<SplitFactory config={CONFIG} >
{/* Evaluate feature flags with SplitTreatments component */}
<SplitTreatments names={['FEATURE_FLAG_NAME']} >
{({ treatments: { FEATURE_FLAG_NAME }, isReady }) => {
// Check SDK readiness using isReady prop
if (!isReady)
return <div>Loading SDK ...</div>;
if (FEATURE_FLAG_NAME.treatment === 'on') {
// return JSX for on treatment
} else if (FEATURE_FLAG_NAME.treatment === 'off') {
// return JSX for off treatment
} else {
// return JSX for control treatment
}
}}
</SplitTreatments>
<MyComponent />
</SplitFactory>
);
}
Expand Down
66 changes: 43 additions & 23 deletions package-lock.json

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

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio-react",
"version": "1.9.0",
"version": "1.10.0",
"description": "A React library to easily integrate and use Split JS SDK",
"main": "lib/index.js",
"module": "es/index.js",
Expand Down Expand Up @@ -62,7 +62,7 @@
},
"homepage": "https://github.com/splitio/react-client#readme",
"dependencies": {
"@splitsoftware/splitio": "10.23.0",
"@splitsoftware/splitio": "10.24.0-beta",
"memoize-one": "^5.1.1",
"shallowequal": "^1.1.0"
},
Expand All @@ -81,6 +81,7 @@
"eslint-plugin-compat": "^4.2.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^3.1.0",
"jest": "^27.2.3",
"react": "^18.0.0",
Expand Down
24 changes: 10 additions & 14 deletions src/SplitClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from 'react';
import { SplitContext } from './SplitContext';
import { ISplitClientProps, ISplitContextValues, IUpdateProps } from './types';
import { ERROR_SC_NO_FACTORY } from './constants';
import { getStatus, getSplitSharedClient, initAttributes } from './utils';
import { getStatus, getSplitClient, initAttributes, IClientWithContext } from './utils';
import { DEFAULT_UPDATE_OPTIONS } from './useSplitClient';

/**
* Common component used to handle the status and events of a Split client passed as prop.
Expand All @@ -11,13 +12,10 @@ import { getStatus, getSplitSharedClient, initAttributes } from './utils';
export class SplitComponent extends React.Component<IUpdateProps & { factory: SplitIO.IBrowserSDK | null, client: SplitIO.IBrowserClient | null, attributes?: SplitIO.Attributes, children: any }, ISplitContextValues> {

static defaultProps = {
updateOnSdkUpdate: false,
updateOnSdkTimedout: false,
updateOnSdkReady: true,
updateOnSdkReadyFromCache: true,
children: null,
factory: null,
client: null,
...DEFAULT_UPDATE_OPTIONS,
}

// Using `getDerivedStateFromProps` since the state depends on the status of the client in props, which might change over time.
Expand Down Expand Up @@ -58,7 +56,6 @@ export class SplitComponent extends React.Component<IUpdateProps & { factory: Sp
factory,
client,
...getStatus(client),
lastUpdate: 0,
};
}

Expand All @@ -83,21 +80,20 @@ export class SplitComponent extends React.Component<IUpdateProps & { factory: Sp
}
}

// NOTE: assuming that SDK events are scatered enough in time, so that Date.now() result is unique per event and triggers an update
setReady = () => {
if (this.props.updateOnSdkReady) this.setState({ lastUpdate: Date.now() });
if (this.props.updateOnSdkReady) this.setState({ lastUpdate: (this.state.client as IClientWithContext).lastUpdate });
}

setReadyFromCache = () => {
if (this.props.updateOnSdkReadyFromCache) this.setState({ lastUpdate: Date.now() });
if (this.props.updateOnSdkReadyFromCache) this.setState({ lastUpdate: (this.state.client as IClientWithContext).lastUpdate });
}

setTimedout = () => {
if (this.props.updateOnSdkTimedout) this.setState({ lastUpdate: Date.now() });
if (this.props.updateOnSdkTimedout) this.setState({ lastUpdate: (this.state.client as IClientWithContext).lastUpdate });
}

setUpdate = () => {
if (this.props.updateOnSdkUpdate) this.setState({ lastUpdate: Date.now() });
if (this.props.updateOnSdkUpdate) this.setState({ lastUpdate: (this.state.client as IClientWithContext).lastUpdate });
}

componentDidMount() {
Expand All @@ -112,7 +108,7 @@ export class SplitComponent extends React.Component<IUpdateProps & { factory: Sp
}

componentWillUnmount() {
// unsubscrite to SDK client events, to remove references to SplitClient instance methods
// unsubscribe from events, to remove references to SplitClient instance methods
this.unsubscribeFromEvents(this.props.client);
}

Expand Down Expand Up @@ -145,8 +141,8 @@ export function SplitClient(props: ISplitClientProps) {
<SplitContext.Consumer>
{(splitContext: ISplitContextValues) => {
const { factory } = splitContext;
// getSplitSharedClient is idempotent like factory.client: it returns the same client given the same factory, Split Key and TT
const client = factory ? getSplitSharedClient(factory, props.splitKey, props.trafficType) : null;
// getSplitClient is idempotent like factory.client: it returns the same client given the same factory, Split Key and TT
const client = factory ? getSplitClient(factory, props.splitKey, props.trafficType) : null;
return (
<SplitComponent {...props} factory={factory} client={client} attributes={props.attributes} />
);
Expand Down
10 changes: 4 additions & 6 deletions src/SplitFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import React from 'react';
import { SplitComponent } from './SplitClient';
import { ISplitFactoryProps } from './types';
import { WARN_SF_CONFIG_AND_FACTORY, ERROR_SF_NO_CONFIG_AND_FACTORY } from './constants';
import { getSplitFactory, destroySplitFactory, IFactoryWithClients } from './utils';
import { getSplitFactory, destroySplitFactory, IFactoryWithClients, getSplitClient } from './utils';
import { DEFAULT_UPDATE_OPTIONS } from './useSplitClient';

/**
* SplitFactory will initialize the Split SDK and its main client, listen for its events in order to update the Split Context,
Expand All @@ -18,11 +19,8 @@ import { getSplitFactory, destroySplitFactory, IFactoryWithClients } from './uti
export class SplitFactory extends React.Component<ISplitFactoryProps, { factory: SplitIO.IBrowserSDK | null, client: SplitIO.IBrowserClient | null }> {

static defaultProps: ISplitFactoryProps = {
updateOnSdkUpdate: false,
updateOnSdkTimedout: false,
updateOnSdkReady: true,
updateOnSdkReadyFromCache: true,
children: null,
...DEFAULT_UPDATE_OPTIONS,
};

readonly state: Readonly<{ factory: SplitIO.IBrowserSDK | null, client: SplitIO.IBrowserClient | null }>;
Expand Down Expand Up @@ -54,7 +52,7 @@ export class SplitFactory extends React.Component<ISplitFactoryProps, { factory:
this.isFactoryExternal = propFactory ? true : false;

// Instantiate main client. Attributes are set on `SplitComponent.getDerivedStateFromProps`
const client = factory ? factory.client() : null;
const client = factory ? getSplitClient(factory) : null;

this.state = {
client,
Expand Down
Loading