@kameleoon/javascript-sdk-core 5.14.5 → 5.16.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/CHANGELOG.md +23 -0
- package/dist/browser.d.ts +1 -0
- package/dist/clientConfiguration/types.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/javascript-sdk-core-browser.cjs.js +117 -30
- package/dist/javascript-sdk-core-browser.cjs.js.map +1 -1
- package/dist/javascript-sdk-core-browser.es.js +117 -30
- package/dist/javascript-sdk-core-browser.es.js.map +1 -1
- package/dist/javascript-sdk-core.cjs.js +117 -30
- package/dist/javascript-sdk-core.cjs.js.map +1 -1
- package/dist/javascript-sdk-core.es.js +117 -30
- package/dist/javascript-sdk-core.es.js.map +1 -1
- package/dist/kameleoonClient.d.ts +5 -4
- package/dist/kameleoonClientInterface.d.ts +13 -7
- package/dist/kameleoonData/customData.d.ts +35 -10
- package/dist/kameleoonData/dataManager.d.ts +3 -0
- package/dist/kameleoonData/types.d.ts +2 -0
- package/dist/types.d.ts +36 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 5.16.0 (2025-10-22)
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Introduced a new [`getDataFile`](getDataFile) method. This method returns the current SDK configuration (also known as the **data file**) used for evaluation and targeting. It is **not** intended for production use to fetch variations for every feature flag in the returned list, as it is not optimized for performance. For that purpose, use [`getVariations`](getVariations) instead. `getDataFile` is mainly useful for debugging or QA, for example to let internal users manually select a variant for a specific feature flag in production.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Addressed an issue where tracking data was sent for visitors who had not provided [consent](setLegalConsent).
|
|
12
|
+
|
|
13
|
+
[setLegalConsent]: https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#setLegalConsent
|
|
14
|
+
[getDataFile]: https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getdatafile
|
|
15
|
+
|
|
16
|
+
## 5.15.0 (2025-09-01)
|
|
17
|
+
|
|
18
|
+
> [!WARNING]
|
|
19
|
+
> If you're upgrading from a version earlier than 5.14.0 and run into any unexpected build or SDK-related issues, please reach out to the Kameleoon Support Team. We're here to ensure your transition is smooth and will promptly address any concerns.
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
- Added an `overwrite` flag to [`CustomData`](CustomData), used as the `overwrite` parameter during tracking.
|
|
24
|
+
- [`CustomData`](CustomData) can now be created using a `name`, in addition to the existing method of using an `index`.
|
|
25
|
+
|
|
3
26
|
## 5.14.5 (2025-08-20)
|
|
4
27
|
|
|
5
28
|
> [!WARNING]
|
package/dist/browser.d.ts
CHANGED
|
@@ -23,3 +23,4 @@ export { MappingIdentifierType } from './storage/types';
|
|
|
23
23
|
export { CustomDataConfigurationType, CustomDataScope, } from './clientConfiguration';
|
|
24
24
|
export { ListUtilities, Utilities } from './utilities';
|
|
25
25
|
export { BrowserDataType, CustomDataType, DataFilterType, DataManagerParametersType, DeviceDataType, GeolocationDataType, KameleoonVisitorDataType, MutUpdateTargetingDataParametersType, OperatingSystemDataType, PageViewDataType, ProcessCustomDataManagerParametersType, VisitDataType, VisitorsDataType, } from './kameleoonData/types';
|
|
26
|
+
export { FeatureFlag, Rule, DataFile, Variable, Variation } from './types';
|
|
@@ -70,6 +70,7 @@ export type ExperimentType = {
|
|
|
70
70
|
variationByExposition: VariationByExpositionType[];
|
|
71
71
|
};
|
|
72
72
|
export type FeatureVariationType = {
|
|
73
|
+
name?: string;
|
|
73
74
|
key: string;
|
|
74
75
|
variables: FeatureVariableType[];
|
|
75
76
|
};
|
|
@@ -119,6 +120,7 @@ export type ClientConfigurationDataType = Omit<ConfigurationDataType, 'featureFl
|
|
|
119
120
|
export type CustomDataConfigurationType = {
|
|
120
121
|
id?: number;
|
|
121
122
|
index: number;
|
|
123
|
+
name?: string;
|
|
122
124
|
localOnly: boolean;
|
|
123
125
|
isMappingIdentifier: boolean;
|
|
124
126
|
scope: CustomDataScope;
|
package/dist/index.d.ts
CHANGED
|
@@ -23,3 +23,4 @@ export { MappingIdentifierType } from './storage/types';
|
|
|
23
23
|
export { CustomDataConfigurationType, CustomDataScope, } from './clientConfiguration';
|
|
24
24
|
export { ListUtilities, Utilities } from './utilities';
|
|
25
25
|
export { BrowserDataType, CustomDataType, DataFilterType, DataManagerParametersType, DeviceDataType, GeolocationDataType, KameleoonVisitorDataType, MutUpdateTargetingDataParametersType, OperatingSystemDataType, PageViewDataType, ProcessCustomDataManagerParametersType, VisitDataType, VisitorsDataType, } from './kameleoonData/types';
|
|
26
|
+
export { FeatureFlag, Rule, DataFile, Variable, Variation } from './types';
|
|
@@ -2296,25 +2296,22 @@ class PageView {
|
|
|
2296
2296
|
* CustomData - a class for creating an instance for user's custom data
|
|
2297
2297
|
* */
|
|
2298
2298
|
let CustomData$1 = class CustomData {
|
|
2299
|
-
|
|
2300
|
-
* @param {number} index - an index of custom data to be stored under in a state, an index of custom data can be specified in `Advanced Tools` section of Kameleoon Application
|
|
2301
|
-
* @param {string[]} value - custom value to store under the specified id, value can be anything but has to be stringified to match the `string` type. *Note* value is variadic parameter and can be used as follows
|
|
2302
|
-
* @example
|
|
2303
|
-
* ```ts
|
|
2304
|
-
* // - Single value
|
|
2305
|
-
* const customData = new CustomData(0, 'value_1');
|
|
2306
|
-
* // - Variadic number of values
|
|
2307
|
-
* const customData = new CustomData(0, 'value_1', 'value_2', 'value_3');
|
|
2308
|
-
* // - Array of values
|
|
2309
|
-
* const values = ['value_1', 'value_2', 'value_3'];
|
|
2310
|
-
* const customData = new CustomData(0, ...values);
|
|
2311
|
-
* ```
|
|
2312
|
-
* */
|
|
2313
|
-
constructor(index, ...value) {
|
|
2314
|
-
this.index = index;
|
|
2315
|
-
this.value = value;
|
|
2299
|
+
constructor(first, second, ...rest) {
|
|
2316
2300
|
this._status = exports.TrackingStatus.Unsent;
|
|
2317
2301
|
this.isIdentifier = false;
|
|
2302
|
+
const isNumber = typeof first === 'number';
|
|
2303
|
+
const isBoolean = typeof second === 'boolean';
|
|
2304
|
+
if (isNumber) {
|
|
2305
|
+
this.index = first;
|
|
2306
|
+
}
|
|
2307
|
+
else {
|
|
2308
|
+
this.name = first;
|
|
2309
|
+
this.index = -1;
|
|
2310
|
+
}
|
|
2311
|
+
this.overwrite = isBoolean ? second : true;
|
|
2312
|
+
this.value = isBoolean
|
|
2313
|
+
? rest
|
|
2314
|
+
: [second, ...rest].filter((v) => v != null);
|
|
2318
2315
|
}
|
|
2319
2316
|
get url() {
|
|
2320
2317
|
// --- Note ---
|
|
@@ -2341,17 +2338,11 @@ let CustomData$1 = class CustomData {
|
|
|
2341
2338
|
UrlParameter.ValuesCountMap +
|
|
2342
2339
|
encodeURIComponent(JSON.stringify(resultValue)) +
|
|
2343
2340
|
UrlParameter.Overwrite +
|
|
2344
|
-
String(
|
|
2341
|
+
String(this.overwrite) +
|
|
2345
2342
|
identifierParameter);
|
|
2346
2343
|
}
|
|
2347
2344
|
get data() {
|
|
2348
|
-
return {
|
|
2349
|
-
index: this.index,
|
|
2350
|
-
value: this.value,
|
|
2351
|
-
type: exports.KameleoonData.CustomData,
|
|
2352
|
-
isIdentifier: this.isIdentifier,
|
|
2353
|
-
status: this.status,
|
|
2354
|
-
};
|
|
2345
|
+
return Object.assign(Object.assign({ index: this.index }, (this.name !== undefined ? { name: this.name } : {})), { value: this.value, type: exports.KameleoonData.CustomData, isIdentifier: this.isIdentifier, status: this.status, overwrite: this.overwrite });
|
|
2355
2346
|
}
|
|
2356
2347
|
get status() {
|
|
2357
2348
|
if (this._isMappingIdentifier) {
|
|
@@ -2366,8 +2357,15 @@ let CustomData$1 = class CustomData {
|
|
|
2366
2357
|
* @return {CustomData} a CustomData instance
|
|
2367
2358
|
* */
|
|
2368
2359
|
static _fromRaw(data) {
|
|
2369
|
-
const { index, value, status, isIdentifier } = data;
|
|
2370
|
-
|
|
2360
|
+
const { index, value, status, isIdentifier, name, overwrite } = data;
|
|
2361
|
+
let customData;
|
|
2362
|
+
if (name) {
|
|
2363
|
+
customData = new CustomData(name, overwrite !== null && overwrite !== void 0 ? overwrite : true, ...value);
|
|
2364
|
+
customData._index = index;
|
|
2365
|
+
}
|
|
2366
|
+
else {
|
|
2367
|
+
customData = new CustomData(index, overwrite !== null && overwrite !== void 0 ? overwrite : true, ...value);
|
|
2368
|
+
}
|
|
2371
2369
|
customData.status = status;
|
|
2372
2370
|
customData._isMappingIdentifier = isIdentifier;
|
|
2373
2371
|
return customData;
|
|
@@ -2398,6 +2396,14 @@ let CustomData$1 = class CustomData {
|
|
|
2398
2396
|
}
|
|
2399
2397
|
}
|
|
2400
2398
|
}
|
|
2399
|
+
/**
|
|
2400
|
+
* @private
|
|
2401
|
+
* @method _index - an internal setter for setting index of custom data
|
|
2402
|
+
* @param {number} value - an index value
|
|
2403
|
+
* */
|
|
2404
|
+
set _index(value) {
|
|
2405
|
+
this.index = value;
|
|
2406
|
+
}
|
|
2401
2407
|
};
|
|
2402
2408
|
|
|
2403
2409
|
/**
|
|
@@ -5143,7 +5149,7 @@ class ConditionFactory {
|
|
|
5143
5149
|
case TargetingType.HEAT_SLICE:
|
|
5144
5150
|
return buildExports.Ok(new ConversionLikelihood(data));
|
|
5145
5151
|
default:
|
|
5146
|
-
KameleoonLogger.
|
|
5152
|
+
KameleoonLogger.info `Unsupported targeted condition type found: ${targetingType}`;
|
|
5147
5153
|
return buildExports.Err(new KameleoonError(exports.KameleoonException.TargetingCondition, targetingType));
|
|
5148
5154
|
}
|
|
5149
5155
|
}
|
|
@@ -5532,6 +5538,7 @@ class DataManager {
|
|
|
5532
5538
|
this.mappingIdentifierCustomDataIndex = null;
|
|
5533
5539
|
this.persistentCustomDataIndexes = new Set();
|
|
5534
5540
|
this.localCustomDataIndexes = new Set();
|
|
5541
|
+
this.customDataIndexByName = new Map();
|
|
5535
5542
|
this.cleanupIntervalId = null;
|
|
5536
5543
|
KameleoonLogger.debug `CALL: new DataManager(dataStorage, infoStorage, cleanupInterval: ${cleanupInterval})`;
|
|
5537
5544
|
this.dataStorage = dataStorage;
|
|
@@ -5866,12 +5873,15 @@ class DataManager {
|
|
|
5866
5873
|
mutUpdateTargetingData({ infoData, visitorCode, kameleoonData, targetingData, }) {
|
|
5867
5874
|
for (const dataItem of kameleoonData) {
|
|
5868
5875
|
if (dataItem.data.type === exports.KameleoonData.CustomData) {
|
|
5869
|
-
this.processCustomData({
|
|
5876
|
+
const customDataIsValid = this.processCustomData({
|
|
5870
5877
|
infoData,
|
|
5871
5878
|
customData: dataItem,
|
|
5872
5879
|
mutData: targetingData,
|
|
5873
5880
|
visitorCode,
|
|
5874
5881
|
});
|
|
5882
|
+
if (!customDataIsValid) {
|
|
5883
|
+
continue;
|
|
5884
|
+
}
|
|
5875
5885
|
}
|
|
5876
5886
|
const expirationTime = this.dataProcessor.mutUpdateData({
|
|
5877
5887
|
infoData,
|
|
@@ -5912,6 +5922,14 @@ class DataManager {
|
|
|
5912
5922
|
var _a;
|
|
5913
5923
|
const { data } = customData;
|
|
5914
5924
|
const isDataValid = Boolean(data.value.length && data.value[0].length);
|
|
5925
|
+
if (data.name) {
|
|
5926
|
+
const cdIndex = this.customDataIndexByName.get(data.name);
|
|
5927
|
+
if (cdIndex === undefined) {
|
|
5928
|
+
return false;
|
|
5929
|
+
}
|
|
5930
|
+
data.index = cdIndex;
|
|
5931
|
+
customData._index = cdIndex;
|
|
5932
|
+
}
|
|
5915
5933
|
if (this.mappingIdentifierCustomDataIndex === data.index && isDataValid) {
|
|
5916
5934
|
customData._isMappingIdentifier = true;
|
|
5917
5935
|
const userId = data.value[0];
|
|
@@ -5935,6 +5953,7 @@ class DataManager {
|
|
|
5935
5953
|
if (this.localCustomDataIndexes.has(data.index)) {
|
|
5936
5954
|
customData.status = exports.TrackingStatus.Sent;
|
|
5937
5955
|
}
|
|
5956
|
+
return true;
|
|
5938
5957
|
}
|
|
5939
5958
|
get unsentDataVisitors() {
|
|
5940
5959
|
const infoResult = this.infoStorage.read();
|
|
@@ -5967,6 +5986,7 @@ class DataManager {
|
|
|
5967
5986
|
set customDataIndexes(customData) {
|
|
5968
5987
|
var _a;
|
|
5969
5988
|
const [customDataLocalOnlyIndexes, persistentCustomDataIndexes] = [[], []];
|
|
5989
|
+
const customDataIndexByName = new Map();
|
|
5970
5990
|
customData.forEach((customData) => {
|
|
5971
5991
|
if (customData.localOnly) {
|
|
5972
5992
|
customDataLocalOnlyIndexes.push(customData.index);
|
|
@@ -5974,12 +5994,19 @@ class DataManager {
|
|
|
5974
5994
|
if (customData.scope === exports.CustomDataScope.Visitor) {
|
|
5975
5995
|
persistentCustomDataIndexes.push(customData.index);
|
|
5976
5996
|
}
|
|
5997
|
+
if (customData.name) {
|
|
5998
|
+
customDataIndexByName.set(customData.name, customData.index);
|
|
5999
|
+
}
|
|
5977
6000
|
});
|
|
5978
6001
|
this.mappingIdentifierCustomDataIndex =
|
|
5979
6002
|
((_a = customData.find((customData) => customData.isMappingIdentifier)) === null || _a === void 0 ? void 0 : _a.index) ||
|
|
5980
6003
|
null;
|
|
5981
6004
|
this.localCustomDataIndexes = new Set(customDataLocalOnlyIndexes);
|
|
5982
6005
|
this.persistentCustomDataIndexes = new Set(persistentCustomDataIndexes);
|
|
6006
|
+
this.customDataIndexByName = customDataIndexByName;
|
|
6007
|
+
}
|
|
6008
|
+
getCustomDataIndexByName(name) {
|
|
6009
|
+
return this.customDataIndexByName.get(name);
|
|
5983
6010
|
}
|
|
5984
6011
|
}
|
|
5985
6012
|
|
|
@@ -7780,7 +7807,7 @@ class BodyProvider {
|
|
|
7780
7807
|
const identifier = isMappingIdentifier
|
|
7781
7808
|
? UrlParameter.MappingValue
|
|
7782
7809
|
: UrlParameter.VisitorCode;
|
|
7783
|
-
return identifier + visitorCode;
|
|
7810
|
+
return identifier + encodeURIComponent(visitorCode);
|
|
7784
7811
|
}
|
|
7785
7812
|
}
|
|
7786
7813
|
|
|
@@ -8364,6 +8391,7 @@ class KameleoonClient {
|
|
|
8364
8391
|
}
|
|
8365
8392
|
const resultVariables = variables.map((variable) => Parser.parseFeatureVariable(variable).throw());
|
|
8366
8393
|
resultFeatureList.set(variation.featureKey, {
|
|
8394
|
+
name: '',
|
|
8367
8395
|
key: variationKey,
|
|
8368
8396
|
id: variationId,
|
|
8369
8397
|
experimentId,
|
|
@@ -8584,6 +8612,62 @@ class KameleoonClient {
|
|
|
8584
8612
|
this.flush(visitorCode);
|
|
8585
8613
|
KameleoonLogger.info `RETURN: KameleoonClient.evaluateAudiences(visitorCode: ${visitorCode})`;
|
|
8586
8614
|
}
|
|
8615
|
+
getDataFile() {
|
|
8616
|
+
const dataFile = {
|
|
8617
|
+
featureFlags: new Map(),
|
|
8618
|
+
};
|
|
8619
|
+
if (this.stubMode) {
|
|
8620
|
+
return dataFile;
|
|
8621
|
+
}
|
|
8622
|
+
KameleoonLogger.debug `CALL: KameleoonClient.getDataFile()`;
|
|
8623
|
+
this.clientConfiguration.featureFlags.forEach((featureFlag, key) => {
|
|
8624
|
+
const variationsMap = new Map();
|
|
8625
|
+
featureFlag.variations.forEach((sourceVariation) => {
|
|
8626
|
+
var _a;
|
|
8627
|
+
const variablesMap = new Map();
|
|
8628
|
+
sourceVariation.variables.forEach((variable) => {
|
|
8629
|
+
try {
|
|
8630
|
+
const parsedVariable = Parser.parseFeatureVariable(variable).throw();
|
|
8631
|
+
variablesMap.set(variable.key, parsedVariable);
|
|
8632
|
+
}
|
|
8633
|
+
catch (err) {
|
|
8634
|
+
KameleoonLogger.error `Error parsing variable ${variable.key} of feature flag ${featureFlag.featureKey}: ${err}`;
|
|
8635
|
+
}
|
|
8636
|
+
});
|
|
8637
|
+
variationsMap.set(sourceVariation.key, {
|
|
8638
|
+
name: (_a = sourceVariation.name) !== null && _a !== void 0 ? _a : '',
|
|
8639
|
+
key: sourceVariation.key,
|
|
8640
|
+
id: null,
|
|
8641
|
+
experimentId: null,
|
|
8642
|
+
variables: variablesMap,
|
|
8643
|
+
});
|
|
8644
|
+
});
|
|
8645
|
+
const rules = featureFlag.rules.map((rule) => {
|
|
8646
|
+
const ruleVariations = new Map();
|
|
8647
|
+
rule.variationByExposition.forEach((varByExp) => {
|
|
8648
|
+
const baseVariation = variationsMap.get(varByExp.variationKey);
|
|
8649
|
+
if (!baseVariation)
|
|
8650
|
+
return;
|
|
8651
|
+
ruleVariations.set(baseVariation.key, {
|
|
8652
|
+
name: baseVariation.name,
|
|
8653
|
+
key: baseVariation.key,
|
|
8654
|
+
id: varByExp.variationId,
|
|
8655
|
+
experimentId: rule.experimentId,
|
|
8656
|
+
variables: baseVariation.variables,
|
|
8657
|
+
});
|
|
8658
|
+
});
|
|
8659
|
+
return { variations: ruleVariations };
|
|
8660
|
+
});
|
|
8661
|
+
dataFile.featureFlags.set(key, {
|
|
8662
|
+
variations: variationsMap,
|
|
8663
|
+
environmentEnabled: featureFlag.environmentEnabled,
|
|
8664
|
+
rules,
|
|
8665
|
+
defaultVariationKey: featureFlag.defaultVariationKey,
|
|
8666
|
+
});
|
|
8667
|
+
});
|
|
8668
|
+
KameleoonLogger.debug `RETURN: KameleoonClient.getDataFile() -> (dataFile: ${dataFile})`;
|
|
8669
|
+
return dataFile;
|
|
8670
|
+
}
|
|
8587
8671
|
setUserConsent({ visitorCode, consent, setData, }) {
|
|
8588
8672
|
if (this.stubMode) {
|
|
8589
8673
|
return;
|
|
@@ -8770,6 +8854,7 @@ class KameleoonClient {
|
|
|
8770
8854
|
return selected;
|
|
8771
8855
|
}
|
|
8772
8856
|
_getFeatureVariation({ visitorCode, featureKey, track, }) {
|
|
8857
|
+
var _a, _b;
|
|
8773
8858
|
KameleoonLogger.debug `CALL: KameleoonClient._getFeatureVariation(visitorCode: ${visitorCode}, featureKey: ${featureKey}, track: ${track})`;
|
|
8774
8859
|
if (!this.initialized) {
|
|
8775
8860
|
return buildExports.Err(new KameleoonError(exports.KameleoonException.Initialization));
|
|
@@ -8820,7 +8905,9 @@ class KameleoonClient {
|
|
|
8820
8905
|
if (track && !isSimulated) {
|
|
8821
8906
|
this.tracker.scheduleVisitor(visitorCode, this._isConsentProvided(visitorCode));
|
|
8822
8907
|
}
|
|
8908
|
+
const variationName = (_b = (_a = featureFlag.variations.find((item) => item.key === variationKey)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '';
|
|
8823
8909
|
const resultData = {
|
|
8910
|
+
name: variationName,
|
|
8824
8911
|
key: variationKey,
|
|
8825
8912
|
id: variationId,
|
|
8826
8913
|
experimentId,
|