@ninetailed/experience.js-react 7.22.0-alpha.3 → 7.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +10 -6
- package/index.esm.js +11 -7
- package/package.json +4 -5
- package/src/lib/NinetailedProvider.d.ts +3 -0
package/index.cjs.js
CHANGED
|
@@ -4,7 +4,6 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var experience_js = require('@ninetailed/experience.js');
|
|
6
6
|
var experience_jsShared = require('@ninetailed/experience.js-shared');
|
|
7
|
-
var radash = require('radash');
|
|
8
7
|
var reactIs = require('react-is');
|
|
9
8
|
|
|
10
9
|
const NinetailedContext = /*#__PURE__*/React.createContext(undefined);
|
|
@@ -126,7 +125,7 @@ const useProfile = () => {
|
|
|
126
125
|
const unsubscribe = ninetailed.onProfileChange(changedProfileState => {
|
|
127
126
|
// Skip update if the profile hasn't actually changed
|
|
128
127
|
// Here we compare the entire profile including experiences and changes
|
|
129
|
-
if (
|
|
128
|
+
if (experience_jsShared.isPlainDeepEqual(changedProfileState, profileStateRef.current)) {
|
|
130
129
|
experience_jsShared.logger.debug('Profile State Did Not Change', changedProfileState);
|
|
131
130
|
return;
|
|
132
131
|
}
|
|
@@ -168,7 +167,7 @@ function useFlagWithManualTracking(flagKey, defaultValue) {
|
|
|
168
167
|
});
|
|
169
168
|
// Reset if inputs change
|
|
170
169
|
React.useEffect(() => {
|
|
171
|
-
if (!
|
|
170
|
+
if (!experience_jsShared.isPlainDeepEqual(defaultValueRef.current, defaultValue) || flagKeyRef.current !== flagKey) {
|
|
172
171
|
defaultValueRef.current = defaultValue;
|
|
173
172
|
flagKeyRef.current = flagKey;
|
|
174
173
|
lastProcessedState.current = null;
|
|
@@ -183,7 +182,7 @@ function useFlagWithManualTracking(flagKey, defaultValue) {
|
|
|
183
182
|
// Listen for personalization state changes
|
|
184
183
|
React.useEffect(() => {
|
|
185
184
|
const unsubscribe = ninetailed.onChangesChange(changesState => {
|
|
186
|
-
if (lastProcessedState.current &&
|
|
185
|
+
if (lastProcessedState.current && experience_jsShared.isPlainDeepEqual(lastProcessedState.current, changesState)) {
|
|
187
186
|
return;
|
|
188
187
|
}
|
|
189
188
|
lastProcessedState.current = changesState;
|
|
@@ -365,11 +364,14 @@ const generateSelectors = id => {
|
|
|
365
364
|
};
|
|
366
365
|
const selectValueFromProfile = (profile, id) => {
|
|
367
366
|
const selectors = generateSelectors(id);
|
|
368
|
-
|
|
367
|
+
// Selectors are matched by truthiness.
|
|
368
|
+
// Existing falsy values (e.g. 0, false, '') are treated as unresolved.
|
|
369
|
+
// It is currently unclear whether this is desired behavior or an accidental one.
|
|
370
|
+
const matchingSelector = selectors.find(selector => experience_jsShared.getByPath(profile, selector));
|
|
369
371
|
if (!matchingSelector) {
|
|
370
372
|
return null;
|
|
371
373
|
}
|
|
372
|
-
return
|
|
374
|
+
return experience_jsShared.getByPath(profile, matchingSelector);
|
|
373
375
|
};
|
|
374
376
|
|
|
375
377
|
const MergeTag = ({
|
|
@@ -383,6 +385,8 @@ const MergeTag = ({
|
|
|
383
385
|
if (loading || !profile) {
|
|
384
386
|
return null;
|
|
385
387
|
}
|
|
388
|
+
// Uses truthy fallback behavior: falsy resolved values (e.g. 0, false, '')
|
|
389
|
+
// are treated the same as unresolved values and will trigger the fallback if provided.
|
|
386
390
|
const value = selectValueFromProfile(profile, id) || fallback;
|
|
387
391
|
return value ? jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
388
392
|
children: value
|
package/index.esm.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React, { createContext, useMemo, useContext, useState, useRef, useEffect, useCallback, createElement, forwardRef } from 'react';
|
|
3
3
|
import { Ninetailed, selectVariant, selectHasExperienceVariants } from '@ninetailed/experience.js';
|
|
4
|
-
import { logger, ChangeTypes, isBrowser, circularJsonStringify } from '@ninetailed/experience.js-shared';
|
|
5
|
-
import { isEqual, get } from 'radash';
|
|
4
|
+
import { isPlainDeepEqual, logger, ChangeTypes, isBrowser, getByPath, circularJsonStringify } from '@ninetailed/experience.js-shared';
|
|
6
5
|
import { isForwardRef } from 'react-is';
|
|
7
6
|
|
|
8
7
|
const NinetailedContext = /*#__PURE__*/createContext(undefined);
|
|
@@ -124,7 +123,7 @@ const useProfile = () => {
|
|
|
124
123
|
const unsubscribe = ninetailed.onProfileChange(changedProfileState => {
|
|
125
124
|
// Skip update if the profile hasn't actually changed
|
|
126
125
|
// Here we compare the entire profile including experiences and changes
|
|
127
|
-
if (
|
|
126
|
+
if (isPlainDeepEqual(changedProfileState, profileStateRef.current)) {
|
|
128
127
|
logger.debug('Profile State Did Not Change', changedProfileState);
|
|
129
128
|
return;
|
|
130
129
|
}
|
|
@@ -166,7 +165,7 @@ function useFlagWithManualTracking(flagKey, defaultValue) {
|
|
|
166
165
|
});
|
|
167
166
|
// Reset if inputs change
|
|
168
167
|
useEffect(() => {
|
|
169
|
-
if (!
|
|
168
|
+
if (!isPlainDeepEqual(defaultValueRef.current, defaultValue) || flagKeyRef.current !== flagKey) {
|
|
170
169
|
defaultValueRef.current = defaultValue;
|
|
171
170
|
flagKeyRef.current = flagKey;
|
|
172
171
|
lastProcessedState.current = null;
|
|
@@ -181,7 +180,7 @@ function useFlagWithManualTracking(flagKey, defaultValue) {
|
|
|
181
180
|
// Listen for personalization state changes
|
|
182
181
|
useEffect(() => {
|
|
183
182
|
const unsubscribe = ninetailed.onChangesChange(changesState => {
|
|
184
|
-
if (lastProcessedState.current &&
|
|
183
|
+
if (lastProcessedState.current && isPlainDeepEqual(lastProcessedState.current, changesState)) {
|
|
185
184
|
return;
|
|
186
185
|
}
|
|
187
186
|
lastProcessedState.current = changesState;
|
|
@@ -363,11 +362,14 @@ const generateSelectors = id => {
|
|
|
363
362
|
};
|
|
364
363
|
const selectValueFromProfile = (profile, id) => {
|
|
365
364
|
const selectors = generateSelectors(id);
|
|
366
|
-
|
|
365
|
+
// Selectors are matched by truthiness.
|
|
366
|
+
// Existing falsy values (e.g. 0, false, '') are treated as unresolved.
|
|
367
|
+
// It is currently unclear whether this is desired behavior or an accidental one.
|
|
368
|
+
const matchingSelector = selectors.find(selector => getByPath(profile, selector));
|
|
367
369
|
if (!matchingSelector) {
|
|
368
370
|
return null;
|
|
369
371
|
}
|
|
370
|
-
return
|
|
372
|
+
return getByPath(profile, matchingSelector);
|
|
371
373
|
};
|
|
372
374
|
|
|
373
375
|
const MergeTag = ({
|
|
@@ -381,6 +383,8 @@ const MergeTag = ({
|
|
|
381
383
|
if (loading || !profile) {
|
|
382
384
|
return null;
|
|
383
385
|
}
|
|
386
|
+
// Uses truthy fallback behavior: falsy resolved values (e.g. 0, false, '')
|
|
387
|
+
// are treated the same as unresolved values and will trigger the fallback if provided.
|
|
384
388
|
const value = selectValueFromProfile(profile, id) || fallback;
|
|
385
389
|
return value ? jsx(Fragment, {
|
|
386
390
|
children: value
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ninetailed/experience.js-react",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.23.0",
|
|
4
4
|
"description": "Ninetailed SDK for React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,10 +28,9 @@
|
|
|
28
28
|
},
|
|
29
29
|
"sideEffects": false,
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@ninetailed/experience.js": "7.
|
|
32
|
-
"@ninetailed/experience.js-shared": "7.
|
|
33
|
-
"@ninetailed/experience.js-plugin-analytics": "7.
|
|
34
|
-
"radash": "10.9.0",
|
|
31
|
+
"@ninetailed/experience.js": "7.23.0",
|
|
32
|
+
"@ninetailed/experience.js-shared": "7.23.0",
|
|
33
|
+
"@ninetailed/experience.js-plugin-analytics": "7.23.0",
|
|
35
34
|
"react-is": "19.2.4"
|
|
36
35
|
},
|
|
37
36
|
"peerDependencies": {
|
|
@@ -17,6 +17,9 @@ export type NinetailedProviderInstantiationProps = {
|
|
|
17
17
|
buildClientContext?: () => NinetailedRequestContext;
|
|
18
18
|
onInitProfileId?: OnInitProfileId;
|
|
19
19
|
storageImpl?: Storage;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated This option is deprecated and will be removed in a future major version.
|
|
22
|
+
*/
|
|
20
23
|
useSDKEvaluation?: boolean;
|
|
21
24
|
};
|
|
22
25
|
export type NinetailedProviderProps = NinetailedProviderInstantiationProps | {
|