@kameleoon/javascript-sdk-core 3.6.1 → 4.0.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 +369 -0
- package/CHANGELOG_INTERNAL.md +3 -0
- package/dist/cacheManager/cacheManager.js +1 -1
- package/dist/cacheManager/cacheManager.js.map +1 -1
- package/dist/cacheManager/index.js +1 -1
- package/dist/clientConfiguration/clientConfiguration.d.ts +2 -3
- package/dist/clientConfiguration/clientConfiguration.js +1 -1
- package/dist/clientConfiguration/clientConfiguration.js.map +1 -1
- package/dist/clientConfiguration/constants.js +1 -1
- package/dist/clientConfiguration/constants.js.map +1 -1
- package/dist/clientConfiguration/index.js +1 -1
- package/dist/clientConfiguration/types.d.ts +7 -8
- package/dist/clientConfiguration/types.js +1 -1
- package/dist/clientConfiguration/types.js.map +1 -1
- package/dist/clientSettings/clientSettings.js +1 -1
- package/dist/clientSettings/clientSettings.js.map +1 -1
- package/dist/clientSettings/index.js +1 -1
- package/dist/constants.d.ts +0 -8
- package/dist/constants.js +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/eventSource/constants.js +1 -1
- package/dist/eventSource/constants.js.map +1 -1
- package/dist/eventSource/eventSource.d.ts +17 -0
- package/dist/eventSource/eventSource.js +2 -0
- package/dist/eventSource/eventSource.js.map +1 -0
- package/dist/eventSource/index.d.ts +2 -2
- package/dist/eventSource/index.js +1 -1
- package/dist/eventSource/index.js.map +1 -1
- package/dist/eventSource/types.d.ts +8 -19
- package/dist/eventSource/types.js.map +1 -1
- package/dist/hasher/hasher.js +1 -1
- package/dist/hasher/hasher.js.map +1 -1
- package/dist/hasher/index.js +1 -1
- package/dist/hasher/index.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/kameleoonClient.d.ts +2 -207
- package/dist/kameleoonClient.js +1 -1
- package/dist/kameleoonClient.js.map +1 -1
- package/dist/kameleoonClientInterface.d.ts +199 -0
- package/dist/kameleoonClientInterface.js +2 -0
- package/dist/kameleoonClientInterface.js.map +1 -0
- package/dist/kameleoonData/applicationVersion.js +1 -1
- package/dist/kameleoonData/applicationVersion.js.map +1 -1
- package/dist/kameleoonData/browser.js +1 -1
- package/dist/kameleoonData/browser.js.map +1 -1
- package/dist/kameleoonData/constants.js +1 -1
- package/dist/kameleoonData/constants.js.map +1 -1
- package/dist/kameleoonData/conversion.js +1 -1
- package/dist/kameleoonData/conversion.js.map +1 -1
- package/dist/kameleoonData/cookie.js +1 -1
- package/dist/kameleoonData/cookie.js.map +1 -1
- package/dist/kameleoonData/customData.js +1 -1
- package/dist/kameleoonData/customData.js.map +1 -1
- package/dist/kameleoonData/dataManager.js +1 -1
- package/dist/kameleoonData/dataManager.js.map +1 -1
- package/dist/kameleoonData/dataProcessor.d.ts +2 -2
- package/dist/kameleoonData/dataProcessor.js +1 -1
- package/dist/kameleoonData/dataProcessor.js.map +1 -1
- package/dist/kameleoonData/device.js +1 -1
- package/dist/kameleoonData/device.js.map +1 -1
- package/dist/kameleoonData/geolocation.js +1 -1
- package/dist/kameleoonData/geolocation.js.map +1 -1
- package/dist/kameleoonData/helpers.js +1 -1
- package/dist/kameleoonData/helpers.js.map +1 -1
- package/dist/kameleoonData/index.js +1 -1
- package/dist/kameleoonData/operatingSystem.js +1 -1
- package/dist/kameleoonData/operatingSystem.js.map +1 -1
- package/dist/kameleoonData/pageView.js +1 -1
- package/dist/kameleoonData/pageView.js.map +1 -1
- package/dist/kameleoonData/types.d.ts +2 -2
- package/dist/kameleoonData/types.js +1 -1
- package/dist/kameleoonData/types.js.map +1 -1
- package/dist/kameleoonData/userAgent.js +1 -1
- package/dist/kameleoonData/userAgent.js.map +1 -1
- package/dist/kameleoonData/visitsData.js +1 -1
- package/dist/kameleoonData/visitsData.js.map +1 -1
- package/dist/kameleoonError/constants.d.ts +1 -1
- package/dist/kameleoonError/constants.js +1 -1
- package/dist/kameleoonError/constants.js.map +1 -1
- package/dist/kameleoonError/helpers.js.map +1 -1
- package/dist/kameleoonError/index.js +1 -1
- package/dist/kameleoonError/kameleoonError.js +1 -1
- package/dist/kameleoonError/kameleoonError.js.map +1 -1
- package/dist/kameleoonError/types.d.ts +1 -1
- package/dist/kameleoonError/types.js +1 -1
- package/dist/kameleoonError/types.js.map +1 -1
- package/dist/kameleoonUtils.js +1 -1
- package/dist/kameleoonUtils.js.map +1 -1
- package/dist/requester/constants.js +1 -1
- package/dist/requester/constants.js.map +1 -1
- package/dist/requester/index.js +1 -1
- package/dist/requester/requester.js +1 -1
- package/dist/requester/requester.js.map +1 -1
- package/dist/requester/types.js +1 -1
- package/dist/requester/types.js.map +1 -1
- package/dist/storage/constants.js +1 -1
- package/dist/storage/constants.js.map +1 -1
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/storage.d.ts +13 -0
- package/dist/storage/storage.js +2 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/types.d.ts +15 -30
- package/dist/storage/types.js.map +1 -1
- package/dist/targeting/conditions/applicationVersion.js +1 -1
- package/dist/targeting/conditions/applicationVersion.js.map +1 -1
- package/dist/targeting/conditions/browser.js +1 -1
- package/dist/targeting/conditions/browser.js.map +1 -1
- package/dist/targeting/conditions/conditionFactory.js +1 -1
- package/dist/targeting/conditions/conditionFactory.js.map +1 -1
- package/dist/targeting/conditions/conversion.js +1 -1
- package/dist/targeting/conditions/conversion.js.map +1 -1
- package/dist/targeting/conditions/cookie.js +1 -1
- package/dist/targeting/conditions/cookie.js.map +1 -1
- package/dist/targeting/conditions/customData.js +1 -1
- package/dist/targeting/conditions/customData.js.map +1 -1
- package/dist/targeting/conditions/device.js +1 -1
- package/dist/targeting/conditions/device.js.map +1 -1
- package/dist/targeting/conditions/exclusiveCampaign.js +1 -1
- package/dist/targeting/conditions/exclusiveCampaign.js.map +1 -1
- package/dist/targeting/conditions/firstVisit.js +1 -1
- package/dist/targeting/conditions/firstVisit.js.map +1 -1
- package/dist/targeting/conditions/geolocation.js +1 -1
- package/dist/targeting/conditions/geolocation.js.map +1 -1
- package/dist/targeting/conditions/index.js +1 -1
- package/dist/targeting/conditions/lastVisit.js +1 -1
- package/dist/targeting/conditions/lastVisit.js.map +1 -1
- package/dist/targeting/conditions/newVisitor.js +1 -1
- package/dist/targeting/conditions/newVisitor.js.map +1 -1
- package/dist/targeting/conditions/operatingSystem.js +1 -1
- package/dist/targeting/conditions/operatingSystem.js.map +1 -1
- package/dist/targeting/conditions/pageTitle.js +1 -1
- package/dist/targeting/conditions/pageTitle.js.map +1 -1
- package/dist/targeting/conditions/pageUrl.js +1 -1
- package/dist/targeting/conditions/pageUrl.js.map +1 -1
- package/dist/targeting/conditions/previousPage.js +1 -1
- package/dist/targeting/conditions/previousPage.js.map +1 -1
- package/dist/targeting/conditions/sameDayVisits.js +1 -1
- package/dist/targeting/conditions/sameDayVisits.js.map +1 -1
- package/dist/targeting/conditions/sdkLanguage.js +1 -1
- package/dist/targeting/conditions/sdkLanguage.js.map +1 -1
- package/dist/targeting/conditions/segment.js +1 -1
- package/dist/targeting/conditions/segment.js.map +1 -1
- package/dist/targeting/conditions/targetFeatureFlag.js +1 -1
- package/dist/targeting/conditions/targetFeatureFlag.js.map +1 -1
- package/dist/targeting/conditions/visitedPages.js +1 -1
- package/dist/targeting/conditions/visitedPages.js.map +1 -1
- package/dist/targeting/conditions/visitorCode.js +1 -1
- package/dist/targeting/conditions/visitorCode.js.map +1 -1
- package/dist/targeting/conditions/visits.js +1 -1
- package/dist/targeting/conditions/visits.js.map +1 -1
- package/dist/targeting/index.js +1 -1
- package/dist/targeting/node.js +1 -1
- package/dist/targeting/node.js.map +1 -1
- package/dist/targeting/tree.js +1 -1
- package/dist/targeting/tree.js.map +1 -1
- package/dist/targeting/types.js +1 -1
- package/dist/targeting/types.js.map +1 -1
- package/dist/types.d.ts +14 -26
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/constants.js +1 -1
- package/dist/utilities/constants.js.map +1 -1
- package/dist/utilities/index.js +1 -1
- package/dist/utilities/types.d.ts +7 -7
- package/dist/utilities/types.js +1 -1
- package/dist/utilities/types.js.map +1 -1
- package/dist/utilities/utilities.js +1 -1
- package/dist/utilities/utilities.js.map +1 -1
- package/dist/variationConfiguration/index.js +1 -1
- package/dist/variationConfiguration/variationConfiguration.d.ts +3 -3
- package/dist/variationConfiguration/variationConfiguration.js +1 -1
- package/dist/variationConfiguration/variationConfiguration.js.map +1 -1
- package/dist/visitorCodeManager/constants.d.ts +3 -0
- package/dist/visitorCodeManager/constants.js +2 -0
- package/dist/visitorCodeManager/constants.js.map +1 -0
- package/dist/visitorCodeManager/index.d.ts +2 -0
- package/dist/visitorCodeManager/index.js +1 -1
- package/dist/visitorCodeManager/index.js.map +1 -1
- package/dist/visitorCodeManager/types.d.ts +7 -0
- package/dist/visitorCodeManager/types.js +2 -0
- package/dist/visitorCodeManager/types.js.map +1 -0
- package/dist/visitorCodeManager/visitorCodeManager.d.ts +11 -8
- package/dist/visitorCodeManager/visitorCodeManager.js +1 -1
- package/dist/visitorCodeManager/visitorCodeManager.js.map +1 -1
- package/package.json +4 -8
- package/dist/eventSource/externalEventSource.d.ts +0 -12
- package/dist/eventSource/externalEventSource.js +0 -2
- package/dist/eventSource/externalEventSource.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
## 4.0.0 (2024-02-16)
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- Previously deprecated `KameleoonUtils.getVisitorCode()` was removed
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
Added [External Dependencies](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#external-dependencies) capabilities
|
|
12
|
+
|
|
13
|
+
## 3.6.1 (2024-02-07)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
- Tracking wasn't sent if consent is required
|
|
18
|
+
|
|
19
|
+
## 3.6.0 (2024-02-01)
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
- Add environment support to `getClientConfigurationUrl`
|
|
24
|
+
|
|
25
|
+
## 3.5.0 (2024-01-18)
|
|
26
|
+
|
|
27
|
+
### Bug fixes
|
|
28
|
+
|
|
29
|
+
- SDK threw an error reading storage when migrating from older SDK versions
|
|
30
|
+
- React Native SDK visitor code couldn't be read from storage in certain React Native versions
|
|
31
|
+
- React SDK request headers caused CORS errors
|
|
32
|
+
|
|
33
|
+
### Features
|
|
34
|
+
|
|
35
|
+
- Added new SDK `configuration` parameter [`requestTimeout`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk/#1-initializing-the-kameleoon-client), which defines maximum time in _milliseconds_ after which any SDK network request will fail
|
|
36
|
+
|
|
37
|
+
## 3.4.1 (2023-12-15)
|
|
38
|
+
|
|
39
|
+
### Bug fixes
|
|
40
|
+
|
|
41
|
+
- Fix nonce for `Conversion` data
|
|
42
|
+
|
|
43
|
+
## 3.4.0 (2023-12-12)
|
|
44
|
+
|
|
45
|
+
### Features
|
|
46
|
+
|
|
47
|
+
- Updated the `getFeatureFlagVariable` method to return an object of type `FeatureFlagVariableType`
|
|
48
|
+
- Enhanced the `getFeatureFlagVariables` method to include the `key` field in its return value.
|
|
49
|
+
|
|
50
|
+
### Bug fixes
|
|
51
|
+
|
|
52
|
+
- Custom Data mapping identifier wasn't tracked correctly
|
|
53
|
+
|
|
54
|
+
## 3.3.0 (2023-12-11)
|
|
55
|
+
|
|
56
|
+
### Features
|
|
57
|
+
|
|
58
|
+
- [flush](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#flush) and [trackConversion](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#trackConversion) methods now have a new optional parameter `isUniqueIdentifier` used for extra [Kameleoon Cross-device Experimentation](https://developers.kameleoon.com/core-concepts/cross-device-experimentation) capabilities
|
|
59
|
+
- [getVisitorCode](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getvisitorcode) and [setLegalConsent](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#setlegalconsent) methods now have an overload allowing methods to be used without parameters (instead of providing and empty object `{}`)
|
|
60
|
+
|
|
61
|
+
### Bug fixes
|
|
62
|
+
|
|
63
|
+
- Targeting data cleanup caused `TypeError`
|
|
64
|
+
|
|
65
|
+
## 3.2.1 (2023-12-04)
|
|
66
|
+
|
|
67
|
+
### Bug fixes
|
|
68
|
+
|
|
69
|
+
- Client cookie is now set properly
|
|
70
|
+
|
|
71
|
+
## 3.2.0 (2023-11-30)
|
|
72
|
+
|
|
73
|
+
### Features
|
|
74
|
+
|
|
75
|
+
- [CustomData session merging](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#using-custom-data-for-session-merging) abilities for [Kameleoon Cross-device Experimentation](https://developers.kameleoon.com/core-concepts/cross-device-experimentation)
|
|
76
|
+
|
|
77
|
+
## 3.1.0 (2023-11-24)
|
|
78
|
+
|
|
79
|
+
### Features
|
|
80
|
+
|
|
81
|
+
- Added `setLegalConsent` method to determine the types data Kameleoon includes in tracking requests. This helps you adhere to legal and regulatory requirements while responsibly managing visitor data. You can find more information in the [Consent management policy](https://help.kameleoon.com/consent-management-policy).
|
|
82
|
+
|
|
83
|
+
## 3.0.0 (2023-11-16)
|
|
84
|
+
|
|
85
|
+
### Breaking change
|
|
86
|
+
|
|
87
|
+
- SDK stopped the support of the following methods were:
|
|
88
|
+
- `getExperiments`
|
|
89
|
+
- `getVisitorExperiments`
|
|
90
|
+
- `triggerExperiment`
|
|
91
|
+
- Previously deprecated `flushData` method was removed
|
|
92
|
+
- [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getremotevisitordata) method parameters were changed to an object with type [`RemoteVisitorDataParamsType`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#parameters-11) that has a new `filters` field
|
|
93
|
+
|
|
94
|
+
### Features
|
|
95
|
+
|
|
96
|
+
- New method for retrieving multiple feature flag variables - [`getFeatureFlagVariables`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getfeatureflagvariables)
|
|
97
|
+
- [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getremotevisitordata) is now capable of retrieving information from up to 25 visits along with some additional visit information configured by new `filters` field
|
|
98
|
+
- [`PageView`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#pageview) data items are now stored by unique URL with timestamps of visits - each visitor can have several `PageView` URLs stored
|
|
99
|
+
- [`Conversion`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#conversion) data items are now stored as a list of conversion for each visitor
|
|
100
|
+
- [Cross Device Synchronization](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#synchronizing-custom-data-across-devices) was improved - [`CustomData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#customdata) with `Visitor` scope is always re-sent with tracking calls allowing seamless synchronization using [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getremotevisitordata)
|
|
101
|
+
- [New targeting conditions](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#list-of-supported-targeting-conditions) are now available (some of them may require [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getremotevisitordata) pre-loaded data)
|
|
102
|
+
- `Browser Cookie`
|
|
103
|
+
- `Application Version`
|
|
104
|
+
- `Operating System`
|
|
105
|
+
- `IP Geolocation`
|
|
106
|
+
- `Segment`
|
|
107
|
+
- `Target Feature Flag`
|
|
108
|
+
- `Previous Page`
|
|
109
|
+
- `Number of Page Views`
|
|
110
|
+
- `Time since First Visit`
|
|
111
|
+
- `Time since Last Visit`
|
|
112
|
+
- `Number of Visits Today`
|
|
113
|
+
- `Total Number of Visits`
|
|
114
|
+
- `New or Returning Visitor`
|
|
115
|
+
- New Kameleoon Data types were introduced:
|
|
116
|
+
- [`ApplicationVersion`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#applicationversion)
|
|
117
|
+
- [`Cookie`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#cookie)
|
|
118
|
+
- [`OperatingSystem`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#operatingsystem)
|
|
119
|
+
- [`GeolocationData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#geolocationdata)
|
|
120
|
+
|
|
121
|
+
### Bug fixes
|
|
122
|
+
|
|
123
|
+
- `SDKParameters` type is now correctly exported from SDK
|
|
124
|
+
- SDK Polling re-tries mechanism was optimized - SDK will now try to obtain configuration again during the next poll after 3 failed configuration loading attempts
|
|
125
|
+
- [`onConfigurationUpdate`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#onconfigurationupdate) callback now fires on successful configuration update in storage (previously fired after network configuration retrieval)
|
|
126
|
+
|
|
127
|
+
## 2.10.1 (2023-10-20)
|
|
128
|
+
|
|
129
|
+
### Bug fixes
|
|
130
|
+
|
|
131
|
+
- Fix previous version deploy issue
|
|
132
|
+
|
|
133
|
+
## 2.10.0 (2023-10-20)
|
|
134
|
+
|
|
135
|
+
### Features
|
|
136
|
+
|
|
137
|
+
- Added new method [`getVisitorWarehouseAudience`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#getvisitorwarehouseaudience)
|
|
138
|
+
|
|
139
|
+
## 2.9.1 (2023-10-11)
|
|
140
|
+
|
|
141
|
+
### Bug fixes
|
|
142
|
+
|
|
143
|
+
- Storage data parse overhead optimization
|
|
144
|
+
|
|
145
|
+
## 2.9.0 (2023-09-25)
|
|
146
|
+
|
|
147
|
+
### Features
|
|
148
|
+
|
|
149
|
+
- Added `getClientConfigurationUrl` utility
|
|
150
|
+
|
|
151
|
+
## 2.8.3 (2023-09-05)
|
|
152
|
+
|
|
153
|
+
### Bug fixes
|
|
154
|
+
|
|
155
|
+
- `UserAgent` was not exported from SDK
|
|
156
|
+
|
|
157
|
+
## 2.8.2 (2023-08-31)
|
|
158
|
+
|
|
159
|
+
### Bug fixes
|
|
160
|
+
|
|
161
|
+
- `Custom Data Condition` now handles index `0` properly
|
|
162
|
+
|
|
163
|
+
## 2.8.1 (2023-08-25)
|
|
164
|
+
|
|
165
|
+
### Bug fixes
|
|
166
|
+
|
|
167
|
+
- Multiple `Real Time Update` connections are no longer created
|
|
168
|
+
- `Custom Data Condition` now handles all exceptions properly
|
|
169
|
+
|
|
170
|
+
## 2.8.0 (2023-08-11)
|
|
171
|
+
|
|
172
|
+
### Bug fixes
|
|
173
|
+
|
|
174
|
+
- Empty Custom Data is now sending activity tracking event
|
|
175
|
+
|
|
176
|
+
### Features
|
|
177
|
+
|
|
178
|
+
- Added [Tracking requests rate limit](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/nodejs-sdk#tracking-rate-limit) capabilities
|
|
179
|
+
- Added [Cross Device Custom Data Synchronization](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#cross-device-custom-data-synchronization) capabilities
|
|
180
|
+
|
|
181
|
+
## 2.7.1 (2023-07-26)
|
|
182
|
+
|
|
183
|
+
### Bug fixes
|
|
184
|
+
|
|
185
|
+
- [`flush`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#flush) now sends offline tracking requests even if there's no new data to track.
|
|
186
|
+
- Timestamps for offline requests are set correctly.
|
|
187
|
+
|
|
188
|
+
## 2.7.0 (2023-07-21)
|
|
189
|
+
|
|
190
|
+
### Features
|
|
191
|
+
|
|
192
|
+
- `flushData` has been deprecated in favor of [`flush`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#flush).
|
|
193
|
+
- [`flush`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#flush) sends failed tracking requests that were stored locally during the offline mode at first and then proceeds with the latest request.
|
|
194
|
+
|
|
195
|
+
## 2.6.0 (2023-07-17)
|
|
196
|
+
|
|
197
|
+
### Bug fixes
|
|
198
|
+
|
|
199
|
+
- Typescript `.d.ts` files have proper relative path resolution.
|
|
200
|
+
- Unused tracking parameters are no longer sent.
|
|
201
|
+
- Real-time update events now get the latest configuration.
|
|
202
|
+
|
|
203
|
+
### Features
|
|
204
|
+
|
|
205
|
+
- When the client is initialized in offline mode, in case of network issues failed tracking requests made by [`flushData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk/#flushdata), [`trackConversion`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk/#trackconversion), [`triggerExperiment`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk/#triggerexperiment), [`getFeatureFlagVariationKey`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk/#getfeatureflagvariationkey) or [`getFeatureFlagVariable`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk/#getfeatureflagvariable) will be sent anew once the client is back online.
|
|
206
|
+
- Minor optimization for checking [targeting conditions](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#list-of-supported-targeting-conditions) of a segment.
|
|
207
|
+
|
|
208
|
+
## 2.5.1 (2023-06-30)
|
|
209
|
+
|
|
210
|
+
### Bug fixes
|
|
211
|
+
|
|
212
|
+
- tracking data duplications
|
|
213
|
+
|
|
214
|
+
## 2.5.0 (2023-06-28)
|
|
215
|
+
|
|
216
|
+
### Bug fixes
|
|
217
|
+
|
|
218
|
+
- Improve error handling for [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#obtain-custom-data-from-kameleoon-data-api)
|
|
219
|
+
- Visitor code is now validated correctly in every method that uses it.
|
|
220
|
+
- Result bundle is now compatible with systems not using `ESM` and `CommonJS`. It's minimized and uses code splitting for `crypto-js` `sha256` function.
|
|
221
|
+
- Parameter `revenue` for [`Conversion`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#conversion) is now optional.
|
|
222
|
+
- Each visitor can now only have one type of associated [`Kameleoon Data Type`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#data-types), except for [`CustomData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#customdata), that a visitor can have one per `customDataIndex`.
|
|
223
|
+
|
|
224
|
+
### Features
|
|
225
|
+
|
|
226
|
+
- New conditions are now supported: `Device`, `Browser`, `SDKLanguage`, `Page Title`, `Page View`, `Visitor Code`, `Conversion`. See the [full list of supported conditions](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#list-of-supported-targeting-conditions).
|
|
227
|
+
- [`Browser`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#browser) now has new optional parameter `version`.
|
|
228
|
+
- [`flushData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#flush-tracking-data) `visitorCode` parameter is now optional.
|
|
229
|
+
- Custom data that is marked as `local only` on Kameleoon Platform is now only used for targeting (not flushed with tracking requests).
|
|
230
|
+
- JavaScript SDK is now available as a single file from the static server, see the [details](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#installation)
|
|
231
|
+
|
|
232
|
+
## 2.4.6 (2023-06-02)
|
|
233
|
+
|
|
234
|
+
### Bug fixes
|
|
235
|
+
|
|
236
|
+
- Custom data true/false match type should work when condition value is `null`
|
|
237
|
+
|
|
238
|
+
## 2.4.5 (2023-06-01)
|
|
239
|
+
|
|
240
|
+
### Bug fixes
|
|
241
|
+
|
|
242
|
+
- Empty visitor code is no more allowed
|
|
243
|
+
- Incorrect tracking body upon triggering an experiment
|
|
244
|
+
|
|
245
|
+
## 2.4.4 (2023-05-31)
|
|
246
|
+
|
|
247
|
+
### Bug fixes
|
|
248
|
+
|
|
249
|
+
- Improve targeting data cleanup interval handling
|
|
250
|
+
|
|
251
|
+
## 2.4.3 (2023-05-24)
|
|
252
|
+
|
|
253
|
+
### Bug fixes
|
|
254
|
+
|
|
255
|
+
- Fixed issue for sending unique `Nonce` parameter on tracking requests
|
|
256
|
+
|
|
257
|
+
## 2.4.2 (2023-05-21)
|
|
258
|
+
|
|
259
|
+
### Bug fixes
|
|
260
|
+
|
|
261
|
+
- [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#obtain-custom-data-from-kameleoon-data-api) current visits not being up-to-date
|
|
262
|
+
|
|
263
|
+
## 2.4.1 (2023-05-20)
|
|
264
|
+
|
|
265
|
+
### Bug fixes
|
|
266
|
+
|
|
267
|
+
- [`getRemoteVisitorData`](https://developers.kameleoon.com/feature-management-and-experimentation/web-sdks/js-sdk#obtain-custom-data-from-kameleoon-data-api) data parse error
|
|
268
|
+
|
|
269
|
+
## 2.4.0 (2023-05-19)
|
|
270
|
+
|
|
271
|
+
### Bug fixes
|
|
272
|
+
|
|
273
|
+
- more meaningful URL names for requester
|
|
274
|
+
- `updateInterval` was set to 30 minutes instead of 60 in some places
|
|
275
|
+
|
|
276
|
+
### Features
|
|
277
|
+
|
|
278
|
+
- New method `getRemoteVisitorData`
|
|
279
|
+
- New offline mode for `initialize` method
|
|
280
|
+
|
|
281
|
+
## 2.3.0 (2023-04-28)
|
|
282
|
+
|
|
283
|
+
### Bug fixes
|
|
284
|
+
|
|
285
|
+
- Unused optional chaining operator in `KameleoonUtils` was removed
|
|
286
|
+
- Experiments methods no more persist assigned variations
|
|
287
|
+
|
|
288
|
+
### Features
|
|
289
|
+
|
|
290
|
+
- Added retries for client initialization
|
|
291
|
+
|
|
292
|
+
## 2.2.1 (2023-04-24)
|
|
293
|
+
|
|
294
|
+
### Bug fixes
|
|
295
|
+
|
|
296
|
+
- Tracking feature flag rule with variation `off` wasn't displayed on result page
|
|
297
|
+
|
|
298
|
+
## 2.2.0 (2023-04-21)
|
|
299
|
+
|
|
300
|
+
### Features
|
|
301
|
+
|
|
302
|
+
- `getEngineTrackingCode` method is now public
|
|
303
|
+
|
|
304
|
+
## 2.1.1 (2023-04-18)
|
|
305
|
+
|
|
306
|
+
### Bug fixes
|
|
307
|
+
|
|
308
|
+
- visitor code cookie header
|
|
309
|
+
|
|
310
|
+
## 2.1.0 (2023-04-14)
|
|
311
|
+
|
|
312
|
+
### Bug fixes
|
|
313
|
+
|
|
314
|
+
- variation calculation logic
|
|
315
|
+
- remove sdk true parameter
|
|
316
|
+
- test regexp
|
|
317
|
+
|
|
318
|
+
### Features
|
|
319
|
+
|
|
320
|
+
- targeting cleanup interval
|
|
321
|
+
- get experiment variation data
|
|
322
|
+
- get engine tracking code
|
|
323
|
+
- api-ssx migration
|
|
324
|
+
- tracking requests and conditions
|
|
325
|
+
|
|
326
|
+
## 2.0.0 (2023-04-05)
|
|
327
|
+
|
|
328
|
+
### Bug fixes
|
|
329
|
+
|
|
330
|
+
- use correct top level domain for data
|
|
331
|
+
- remove kameleoon client headers
|
|
332
|
+
|
|
333
|
+
### Features
|
|
334
|
+
|
|
335
|
+
- integration of compute edge
|
|
336
|
+
- api-ssx migration
|
|
337
|
+
- tracking requests and conditions
|
|
338
|
+
|
|
339
|
+
## 1.1.1 (2023-03-24)
|
|
340
|
+
|
|
341
|
+
### Bug fixes
|
|
342
|
+
|
|
343
|
+
- change broken dependency
|
|
344
|
+
|
|
345
|
+
## 1.1.0 (2023-03-22)
|
|
346
|
+
|
|
347
|
+
### Features
|
|
348
|
+
|
|
349
|
+
- License changed from `GPL3.0` to `ISC`
|
|
350
|
+
|
|
351
|
+
## 1.0.0 (2023-03-21)
|
|
352
|
+
|
|
353
|
+
### Bug fixes
|
|
354
|
+
|
|
355
|
+
- remove xhr
|
|
356
|
+
|
|
357
|
+
### Features
|
|
358
|
+
|
|
359
|
+
- add feature flags v2
|
|
360
|
+
|
|
361
|
+
## 0.0.2 (2022-11-01)
|
|
362
|
+
|
|
363
|
+
### Bug fixes
|
|
364
|
+
|
|
365
|
+
- remove boolean case condition
|
|
366
|
+
|
|
367
|
+
## 0.0.1 (2022-10-13)
|
|
368
|
+
|
|
369
|
+
### Initial release
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var _types=require("../types");Object.defineProperty(exports,"__esModule",{value:!0}),exports.CacheManager=void 0;function
|
|
1
|
+
"use strict";var _types=require("../types");Object.defineProperty(exports,"__esModule",{value:!0}),exports.CacheManager=void 0;function _defineProperty(a,b,c){return b=_toPropertyKey(b),b in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==typeof b?b:b+""}function _toPrimitive(a,b){if("object"!=typeof a||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=typeof d)return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}class CacheManager{constructor(a){_defineProperty(this,"cacheMap",new Map),_defineProperty(this,"intervalId",null),_defineProperty(this,"cleanupTimeout",void 0),this.cleanupTimeout=a*_types.Milliseconds.Second}add(a){let{key:b,data:c,lifetime:d}=a;null===this.intervalId&&this.activate();const e=d*_types.Milliseconds.Second,f={data:c,expirationTime:Date.now()+e};this.cacheMap.set(b,f)}getAliveItem(a){const b=this.cacheMap.get(a);return b&&b.expirationTime>=Date.now()?b.data:(b&&this.cacheMap.delete(a),null)}activate(){this.intervalId=setInterval(()=>{const a=Date.now();for(const[b,c]of this.cacheMap)c.expirationTime<a&&this.cacheMap.delete(b);this.cacheMap.size||this.cleanupInterval()},this.cleanupTimeout)}cleanupInterval(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null)}}exports.CacheManager=CacheManager;
|
|
2
2
|
//# sourceMappingURL=cacheManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheManager.js","names":["_types","require","Object","defineProperty","exports","value","CacheManager","
|
|
1
|
+
{"version":3,"file":"cacheManager.js","names":["_types","require","Object","defineProperty","exports","value","CacheManager","_defineProperty","a","b","c","_toPropertyKey","enumerable","configurable","writable","_toPrimitive","Symbol","toPrimitive","d","call","TypeError","String","Number","constructor","cleanupTimeout","Map","Milliseconds","Second","add","key","data","lifetime","intervalId","activate","expirationTime","cacheItem","Date","now","cacheMap","set","getAliveItem","get","delete","setInterval","item","size","cleanupInterval","clearInterval"],"sources":["../../src/cacheManager/cacheManager.ts"],"sourcesContent":["import { Milliseconds } from 'src/types';\nimport { AddParametersType, CacheItemType } from './types';\n\ninterface ICacheManager<T> {\n /**\n * Add item to cache\n * @param {AddParametersType<T>} parameters - parameters for adding new item cache\n * @returns {void}\n */\n add({ key, data, lifetime }: AddParametersType<T>): void;\n /**\n * Get item that is not expired from cache\n * @param {string} key - key of item\n * @returns {T} an item that is not expired\n */\n getAliveItem(key: string): T | null;\n}\n\n/**\n * @class\n * CacheManager - a class for managing cache\n */\nexport class CacheManager<T> implements ICacheManager<T> {\n private cacheMap = new Map<string, CacheItemType<T>>();\n private intervalId: NodeJS.Timeout | null = null;\n private cleanupTimeout: number;\n\n /**\n * @param {number} cleanupTimeout - timeout for cleaning cache in seconds\n * generic type `T` is a type of data that will be stored in cache\n * @example\n * ```typescript\n * const cacheManager = new CacheManager<number>(60);\n * ```\n */\n constructor(cleanupTimeout: number) {\n this.cleanupTimeout = cleanupTimeout * Milliseconds.Second;\n }\n\n public add({ key, data, lifetime }: AddParametersType<T>): void {\n if (this.intervalId === null) {\n this.activate();\n }\n\n const expirationTime = lifetime * Milliseconds.Second;\n\n const cacheItem: CacheItemType<T> = {\n data,\n expirationTime: Date.now() + expirationTime,\n };\n\n this.cacheMap.set(key, cacheItem);\n }\n\n public getAliveItem(key: string): T | null {\n const cacheItem = this.cacheMap.get(key);\n\n if (cacheItem && cacheItem.expirationTime >= Date.now()) {\n return cacheItem.data;\n }\n\n cacheItem && this.cacheMap.delete(key);\n\n return null;\n }\n\n private activate(): void {\n this.intervalId = setInterval(() => {\n const now = Date.now();\n\n for (const [key, item] of this.cacheMap) {\n if (item.expirationTime < now) {\n this.cacheMap.delete(key);\n }\n }\n\n if (!this.cacheMap.size) {\n this.cleanupInterval();\n }\n }, this.cleanupTimeout);\n }\n\n private cleanupInterval(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"AddParametersType",{enumerable:!0,get:function
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"AddParametersType",{enumerable:!0,get:function(){return _types.AddParametersType}}),Object.defineProperty(exports,"CacheManager",{enumerable:!0,get:function(){return _cacheManager.CacheManager}});var _cacheManager=require("./cacheManager"),_types=require("./types");
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -20,13 +20,12 @@ export declare class ClientConfiguration implements IClientConfiguration {
|
|
|
20
20
|
private storage;
|
|
21
21
|
private offlineTrackingStorage;
|
|
22
22
|
private requester;
|
|
23
|
-
private eventSource
|
|
24
|
-
private externalEventSource;
|
|
23
|
+
private eventSource;
|
|
25
24
|
private externalClientConfiguration?;
|
|
26
25
|
private mappedRules;
|
|
27
26
|
private dataManager;
|
|
28
27
|
private visitorCodeManager;
|
|
29
|
-
constructor({ settings, storage, requester, dataManager, externalClientConfiguration, offlineTrackingStorage,
|
|
28
|
+
constructor({ settings, storage, requester, dataManager, externalClientConfiguration, offlineTrackingStorage, eventSource, externalVisitorCodeManager, }: ClientConfigurationParametersType);
|
|
30
29
|
initialize(): Promise<Result<void, KameleoonError>>;
|
|
31
30
|
private cleanupHandlers;
|
|
32
31
|
private handleExternalUpdates;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientConfiguration=void 0;var _tsRes=require("ts-res"),_eventSource=require("../eventSource"),_constants=require("./constants"),_types=require("./types"),_utilities=require("../utilities");function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _createForOfIteratorHelper(a,b){var c="undefined"!=typeof Symbol&&a[Symbol.iterator]||a["@@iterator"];if(!c){if(Array.isArray(a)||(c=_unsupportedIterableToArray(a))||b&&a&&"number"==typeof a.length){c&&(a=c);var d=0,e=function(){};return{s:e,n:function n(){return d>=a.length?{done:!0}:{done:!1,value:a[d++]}},e:function e(a){throw a},f:e}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var f,g=!0,h=!1;return{s:function s(){c=c.call(a)},n:function n(){var a=c.next();return g=a.done,a},e:function e(a){h=!0,f=a},f:function f(){try{g||null==c.return||c.return()}finally{if(h)throw f}}}}function _unsupportedIterableToArray(a,b){if(a){if("string"==typeof a)return _arrayLikeToArray(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);return"Object"===c&&a.constructor&&(c=a.constructor.name),"Map"===c||"Set"===c?Array.from(a):"Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)?_arrayLikeToArray(a,b):void 0}}function _arrayLikeToArray(a,b){(null==b||b>a.length)&&(b=a.length);for(var c=0,d=Array(b);c<b;c++)d[c]=a[c];return d}function _regeneratorRuntime(){"use strict";function a(a,b,c){return Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}),a[b]}function b(a,b,c,e){var f=b&&b.prototype instanceof d?b:d,g=Object.create(f.prototype),h=new m(e||[]);return s(g,"_invoke",{value:i(a,c,h)}),g}function c(a,b,c){try{return{type:"normal",arg:a.call(b,c)}}catch(a){return{type:"throw",arg:a}}}function d(){}function e(){}function f(){}function g(b){["next","throw","return"].forEach(function(c){a(b,c,function(a){return this._invoke(c,a)})})}function h(a,b){function d(e,f,g,h){var i=c(a[e],a,f);if("throw"!==i.type){var j=i.arg,k=j.value;return k&&"object"==_typeof(k)&&r.call(k,"__await")?b.resolve(k.__await).then(function(a){d("next",a,g,h)},function(a){d("throw",a,g,h)}):b.resolve(k).then(function(a){j.value=a,g(j)},function(a){return d("throw",a,g,h)})}h(i.arg)}var e;s(this,"_invoke",{value:function value(a,c){function f(){return new b(function(b,e){d(a,c,b,e)})}return e=e?e.then(f,f):f()}})}function i(a,b,d){var e="suspendedStart";return function(f,g){if("executing"==e)throw new Error("Generator is already running");if("completed"==e){if("throw"===f)throw g;return o()}for(d.method=f,d.arg=g;;){var h=d.delegate;if(h){var i=j(h,d);if(i){if(i===x)continue;return i}}if("next"===d.method)d.sent=d._sent=d.arg;else if("throw"===d.method){if("suspendedStart"==e)throw e="completed",d.arg;d.dispatchException(d.arg)}else"return"===d.method&&d.abrupt("return",d.arg);e="executing";var k=c(a,b,d);if("normal"===k.type){if(e=d.done?"completed":"suspendedYield",k.arg===x)continue;return{value:k.arg,done:d.done}}"throw"===k.type&&(e="completed",d.method="throw",d.arg=k.arg)}}}function j(a,b){var d=b.method,e=a.iterator[d];if(void 0===e)return b.delegate=null,"throw"===d&&a.iterator.return&&(b.method="return",b.arg=void 0,j(a,b),"throw"===b.method)||"return"!==d&&(b.method="throw",b.arg=new TypeError("The iterator does not provide a '"+d+"' method")),x;var f=c(e,a.iterator,b.arg);if("throw"===f.type)return b.method="throw",b.arg=f.arg,b.delegate=null,x;var g=f.arg;return g?g.done?(b[a.resultName]=g.value,b.next=a.nextLoc,"return"!==b.method&&(b.method="next",b.arg=void 0),b.delegate=null,x):g:(b.method="throw",b.arg=new TypeError("iterator result is not an object"),b.delegate=null,x)}function k(a){var b={tryLoc:a[0]};1 in a&&(b.catchLoc=a[1]),2 in a&&(b.finallyLoc=a[2],b.afterLoc=a[3]),this.tryEntries.push(b)}function l(a){var b=a.completion||{};b.type="normal",delete b.arg,a.completion=b}function m(a){this.tryEntries=[{tryLoc:"root"}],a.forEach(k,this),this.reset(!0)}function n(a){if(a){var b=a[u];if(b)return b.call(a);if("function"==typeof a.next)return a;if(!isNaN(a.length)){var c=-1,d=function b(){for(;++c<a.length;)if(r.call(a,c))return b.value=a[c],b.done=!1,b;return b.value=void 0,b.done=!0,b};return d.next=d}}return{next:o}}function o(){return{value:void 0,done:!0}}_regeneratorRuntime=function(){return p};var p={},q=Object.prototype,r=q.hasOwnProperty,s=Object.defineProperty||function(a,b,c){a[b]=c.value},t="function"==typeof Symbol?Symbol:{},u=t.iterator||"@@iterator",v=t.asyncIterator||"@@asyncIterator",w=t.toStringTag||"@@toStringTag";try{a({},"")}catch(b){a=function(a,b,c){return a[b]=c}}p.wrap=b;var x={},y={};a(y,u,function(){return this});var z=Object.getPrototypeOf,A=z&&z(z(n([])));A&&A!==q&&r.call(A,u)&&(y=A);var B=f.prototype=d.prototype=Object.create(y);return e.prototype=f,s(B,"constructor",{value:f,configurable:!0}),s(f,"constructor",{value:e,configurable:!0}),e.displayName=a(f,w,"GeneratorFunction"),p.isGeneratorFunction=function(a){var b="function"==typeof a&&a.constructor;return!!b&&(b===e||"GeneratorFunction"===(b.displayName||b.name))},p.mark=function(b){return Object.setPrototypeOf?Object.setPrototypeOf(b,f):(b.__proto__=f,a(b,w,"GeneratorFunction")),b.prototype=Object.create(B),b},p.awrap=function(a){return{__await:a}},g(h.prototype),a(h.prototype,v,function(){return this}),p.AsyncIterator=h,p.async=function(a,c,d,e,f){void 0===f&&(f=Promise);var g=new h(b(a,c,d,e),f);return p.isGeneratorFunction(c)?g:g.next().then(function(a){return a.done?a.value:g.next()})},g(B),a(B,w,"Generator"),a(B,u,function(){return this}),a(B,"toString",function(){return"[object Generator]"}),p.keys=function(a){var b=Object(a),c=[];for(var d in b)c.push(d);return c.reverse(),function a(){for(;c.length;){var d=c.pop();if(d in b)return a.value=d,a.done=!1,a}return a.done=!0,a}},p.values=n,m.prototype={constructor:m,reset:function reset(a){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(l),!a)for(var b in this)"t"===b.charAt(0)&&r.call(this,b)&&!isNaN(+b.slice(1))&&(this[b]=void 0)},stop:function stop(){this.done=!0;var a=this.tryEntries[0].completion;if("throw"===a.type)throw a.arg;return this.rval},dispatchException:function dispatchException(a){function b(b,d){return f.type="throw",f.arg=a,c.next=b,d&&(c.method="next",c.arg=void 0),!!d}if(this.done)throw a;for(var c=this,d=this.tryEntries.length-1;0<=d;--d){var e=this.tryEntries[d],f=e.completion;if("root"===e.tryLoc)return b("end");if(e.tryLoc<=this.prev){var g=r.call(e,"catchLoc"),h=r.call(e,"finallyLoc");if(g&&h){if(this.prev<e.catchLoc)return b(e.catchLoc,!0);if(this.prev<e.finallyLoc)return b(e.finallyLoc)}else if(!g){if(!h)throw new Error("try statement without catch or finally");if(this.prev<e.finallyLoc)return b(e.finallyLoc)}else if(this.prev<e.catchLoc)return b(e.catchLoc,!0)}}},abrupt:function abrupt(a,b){for(var c,d=this.tryEntries.length-1;0<=d;--d)if(c=this.tryEntries[d],c.tryLoc<=this.prev&&r.call(c,"finallyLoc")&&this.prev<c.finallyLoc){var e=c;break}e&&("break"===a||"continue"===a)&&e.tryLoc<=b&&b<=e.finallyLoc&&(e=null);var f=e?e.completion:{};return f.type=a,f.arg=b,e?(this.method="next",this.next=e.finallyLoc,x):this.complete(f)},complete:function complete(a,b){if("throw"===a.type)throw a.arg;return"break"===a.type||"continue"===a.type?this.next=a.arg:"return"===a.type?(this.rval=this.arg=a.arg,this.method="return",this.next="end"):"normal"===a.type&&b&&(this.next=b),x},finish:function finish(a){for(var b,c=this.tryEntries.length-1;0<=c;--c)if(b=this.tryEntries[c],b.finallyLoc===a)return this.complete(b.completion,b.afterLoc),l(b),x},catch:function _catch(a){for(var b,c=this.tryEntries.length-1;0<=c;--c)if(b=this.tryEntries[c],b.tryLoc===a){var d=b.completion;if("throw"===d.type){var e=d.arg;l(b)}return e}throw new Error("illegal catch attempt")},delegateYield:function delegateYield(a,b,c){return this.delegate={iterator:n(a),resultName:b,nextLoc:c},"next"===this.method&&(this.arg=void 0),x}},p}function asyncGeneratorStep(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){return void c(a)}h.done?b(i):Promise.resolve(i).then(d,e)}function _asyncToGenerator(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){function f(a){asyncGeneratorStep(h,d,e,f,g,"next",a)}function g(a){asyncGeneratorStep(h,d,e,f,g,"throw",a)}var h=a.apply(b,c);f(void 0)})}}function _classCallCheck(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function _defineProperties(a,b){for(var c,d=0;d<b.length;d++)c=b[d],c.enumerable=c.enumerable||!1,c.configurable=!0,"value"in c&&(c.writable=!0),Object.defineProperty(a,_toPropertyKey(c.key),c)}function _createClass(a,b,c){return b&&_defineProperties(a.prototype,b),c&&_defineProperties(a,c),Object.defineProperty(a,"prototype",{writable:!1}),a}function _defineProperty(a,b,c){return b=_toPropertyKey(b),b in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"===_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!==_typeof(a)||null===a)return a;var c=a[Symbol.toPrimitive];if(c!==void 0){var d=c.call(a,b||"default");if("object"!==_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}var ClientConfiguration=function(){function a(b){var c=b.settings,d=b.storage,e=b.requester,f=b.dataManager,g=b.externalClientConfiguration,h=b.offlineTrackingStorage,i=b.externalEventSource,j=b.externalVisitorCodeManager;_classCallCheck(this,a),_defineProperty(this,"configurationUpdateCallback",void 0),_defineProperty(this,"updateConfigurationIntervalId",null),_defineProperty(this,"updateType",_types.UpdateType.Idle),_defineProperty(this,"configurationData",_constants.DEFAULT_CONFIGURATION_DATA),_defineProperty(this,"settings",void 0),_defineProperty(this,"lastUpdate",void 0),_defineProperty(this,"storage",void 0),_defineProperty(this,"offlineTrackingStorage",void 0),_defineProperty(this,"requester",void 0),_defineProperty(this,"eventSource",void 0),_defineProperty(this,"externalEventSource",void 0),_defineProperty(this,"externalClientConfiguration",void 0),_defineProperty(this,"mappedRules",new Map),_defineProperty(this,"dataManager",void 0),_defineProperty(this,"visitorCodeManager",void 0),this.requester=e,this.settings=c,this.lastUpdate=new Date,this.storage=d,this.dataManager=f,this.externalClientConfiguration=g,this.offlineTrackingStorage=h,this.externalEventSource=i,this.visitorCodeManager=j}return _createClass(a,[{key:"initialize",value:function(){function a(){return b.apply(this,arguments)}var b=_asyncToGenerator(_regeneratorRuntime().mark(function a(){var b,c,d,e;return _regeneratorRuntime().wrap(function f(a){for(;1;)switch(a.prev=a.next){case 0:if(this.readStorageData(),b=!!this.externalClientConfiguration,c=this.checkShouldUpdate(b),!c){a.next=12;break}return a.next=6,this.updateClientConfiguration();case 6:if(d=a.sent,d.ok){a.next=9;break}return a.abrupt("return",d);case 9:if(e=d.data,!e){a.next=12;break}return a.abrupt("return",(0,_tsRes.Ok)());case 12:if(!b){a.next=15;break}return this.handleExternalUpdates(),a.abrupt("return",(0,_tsRes.Ok)());case 15:if(this.updateType!==_types.UpdateType.RealTime||this.eventSource){a.next=19;break}return this.updateType=_types.UpdateType.Idle,this.handleRealTimeUpdates(),a.abrupt("return",(0,_tsRes.Ok)());case 19:return this.updateType===_types.UpdateType.Polling&&this.handlePollingUpdates(),a.abrupt("return",(0,_tsRes.Ok)());case 21:case"end":return a.stop();}},a,this)}));return a}()},{key:"cleanupHandlers",value:function cleanupHandlers(){this.eventSource&&this.eventSource.close(),this.updateConfigurationIntervalId&&clearInterval(this.updateConfigurationIntervalId)}},{key:"handleExternalUpdates",value:function handleExternalUpdates(){this.cleanupHandlers(),this.configurationData=this.externalClientConfiguration}},{key:"handleRealTimeUpdates",value:function handleRealTimeUpdates(){var a=this;this.cleanupHandlers(),this.eventSource=new _eventSource.ExternalEventSource(this.settings.siteCode,this.externalEventSource);var b=function updateEventCallback(b){a.updateClientConfiguration(b).then(function(b){b.ok&&a.configurationUpdateCallback&&a.configurationUpdateCallback()})};this.eventSource.open(b)}},{key:"handlePollingUpdates",value:function handlePollingUpdates(){this.cleanupHandlers();try{this.updateConfigurationIntervalId=setInterval(this.updateClientConfiguration.bind(this),this.settings.updateInterval)}catch(a){throw this.updateConfigurationIntervalId&&clearInterval(this.updateConfigurationIntervalId),a}}},{key:"onConfigurationUpdate",value:function onConfigurationUpdate(a){this.configurationUpdateCallback=a}},{key:"featureFlags",get:function get(){return this.configurationData.featureFlags}},{key:"configuration",get:function get(){return this.configurationData.configuration}},{key:"segments",get:function get(){var a=new Map;return this.featureFlags.forEach(function(b){b.rules.forEach(function(b){b.segment&&!a.has(b.segment.id)&&a.set(b.segment.id,b.segment)})}),a}},{key:"ruleMap",get:function get(){if(this.mappedRules.size)return this.mappedRules;var a,b=new Map,c=_createForOfIteratorHelper(this.featureFlags);try{for(c.s();!(a=c.n()).done;){var d,e=a.value,f=_createForOfIteratorHelper(e.rules);try{var g=function _loop(){var a=d.value,c=a.id,f=a.experimentId,g=a.variationByExposition,h=new Map;g.forEach(function(a){var b=a.variationKey,c=a.variationId;"number"==typeof c&&h.set(b,c)}),b.set(c,{featureId:e.id,experimentId:f,variations:h})};for(f.s();!(d=f.n()).done;)g()}catch(a){f.e(a)}finally{f.f()}}}catch(a){c.e(a)}finally{c.f()}return this.mappedRules=b,b}},{key:"isConsentRequired",get:function get(){return this.configuration.consentType===_types.ConsentType.Required}},{key:"hasAnyTargetedDeliveryRule",get:function get(){return this.featureFlags.some(function(a){return a.environmentEnabled&&a.rules.some(function(a){return a.type===_types.RuleType.TARGETED_DELIVERY})})}},{key:"checkIntegrity",value:function checkIntegrity(a){if(!a)return!1;var b=Object.keys(a);if(!b.length)return!1;var c=Object.keys(_constants.DEFAULT_CONFIGURATION_DATA);return b.sort().join()===c.sort().join()}},{key:"checkShouldUpdate",value:function checkShouldUpdate(){var a=!!(0<arguments.length&&void 0!==arguments[0])&&arguments[0],b=this.configurationData,c=b.featureFlags,d=b.configuration,e=this.settings.updateInterval;if(a)return this.updateType=_types.UpdateType.Idle,!1;if(this.updateType=d.realTimeUpdate?_types.UpdateType.RealTime:_types.UpdateType.Polling,!c.length)return!0;var f=this.lastUpdate.getTime(),g=Date.now()-e;return f<g}},{key:"readStorageData",value:function readStorageData(){var a=this.storage.read();if(a.ok){var b=a.data,c=b.data,d=b.lastUpdate,e=this.checkIntegrity(c);e?(this.configurationData=c,this.lastUpdate=new Date(Date.parse(d))):(this.storage.write({data:_constants.DEFAULT_CONFIGURATION_DATA,lastUpdate:this.lastUpdate.toString()}),this.configurationData=_constants.DEFAULT_CONFIGURATION_DATA)}}},{key:"updateClientConfiguration",value:function(){function a(a){return b.apply(this,arguments)}var b=_asyncToGenerator(_regeneratorRuntime().mark(function b(a){var c,d,e,f,g,h,i,j,k;return _regeneratorRuntime().wrap(function l(b){for(;1;)switch(b.prev=b.next){case 0:return b.next=2,this.requester.getClientConfiguration(a);case 2:if(c=b.sent,c.ok){b.next=8;break}if(d=this.configurationData.featureFlags,!d.length){b.next=7;break}return b.abrupt("return",(0,_tsRes.Ok)(!0));case 7:return b.abrupt("return",c);case 8:if(_utilities.Utilities.sendOfflineTracking({storage:this.offlineTrackingStorage,requester:this.requester}),e=c.data,f=e.configuration,g=e.customData,this.configurationData=c.data,null!==g&&void 0!==g&&g.length&&(this.dataManager.customDataIndexes=g),this.dataManager.clearTrees(),this.mappedRules.clear(),h=this.updateStorageData(),h.ok){b.next=17;break}return b.abrupt("return",h);case 17:if(i=f.realTimeUpdate?_types.UpdateType.RealTime:_types.UpdateType.Polling,j=i!==this.updateType,!j){b.next=23;break}return this.updateType=i,b.next=23,this.initialize();case 23:return k=this.isConsentRequired&&!this.hasAnyTargetedDeliveryRule,this.visitorCodeManager.setConsentRequired(k),b.abrupt("return",(0,_tsRes.Ok)(j));case 26:case"end":return b.stop();}},b,this)}));return a}()},{key:"updateStorageData",value:function updateStorageData(){this.lastUpdate=new Date;var a={data:this.configurationData,lastUpdate:this.lastUpdate.toString()};return this.storage.write(a)}}]),a}();exports.ClientConfiguration=ClientConfiguration;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientConfiguration=void 0;var _tsRes=require("ts-res"),_constants=require("./constants"),_types=require("./types"),_utilities=require("../utilities");function _defineProperty(a,b,c){return b=_toPropertyKey(b),b in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==typeof b?b:b+""}function _toPrimitive(a,b){if("object"!=typeof a||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=typeof d)return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}class ClientConfiguration{constructor(a){let{settings:b,storage:c,requester:d,dataManager:e,externalClientConfiguration:f,offlineTrackingStorage:g,eventSource:h,externalVisitorCodeManager:i}=a;_defineProperty(this,"configurationUpdateCallback",void 0),_defineProperty(this,"updateConfigurationIntervalId",null),_defineProperty(this,"updateType",_types.UpdateType.Idle),_defineProperty(this,"configurationData",_constants.DEFAULT_CONFIGURATION_DATA),_defineProperty(this,"settings",void 0),_defineProperty(this,"lastUpdate",void 0),_defineProperty(this,"storage",void 0),_defineProperty(this,"offlineTrackingStorage",void 0),_defineProperty(this,"requester",void 0),_defineProperty(this,"eventSource",void 0),_defineProperty(this,"externalClientConfiguration",void 0),_defineProperty(this,"mappedRules",new Map),_defineProperty(this,"dataManager",void 0),_defineProperty(this,"visitorCodeManager",void 0),this.requester=d,this.settings=b,this.lastUpdate=new Date,this.storage=c,this.dataManager=e,this.externalClientConfiguration=f,this.offlineTrackingStorage=g,this.visitorCodeManager=i,this.eventSource=h}async initialize(){this.readStorageData();const a=!!this.externalClientConfiguration,b=this.checkShouldUpdate(a);if(b){const a=await this.updateClientConfiguration();if(!a.ok)return a;const b=a.data;if(b)return(0,_tsRes.Ok)()}return a?(this.handleExternalUpdates(),(0,_tsRes.Ok)()):this.updateType!==_types.UpdateType.RealTime||this.eventSource.isOpen?(this.updateType===_types.UpdateType.Polling&&this.handlePollingUpdates(),(0,_tsRes.Ok)()):(this.updateType=_types.UpdateType.Idle,this.handleRealTimeUpdates(),(0,_tsRes.Ok)())}cleanupHandlers(){this.eventSource.isOpen&&this.eventSource.close(),this.updateConfigurationIntervalId&&clearInterval(this.updateConfigurationIntervalId)}handleExternalUpdates(){this.cleanupHandlers(),this.configurationData=this.externalClientConfiguration}handleRealTimeUpdates(){this.cleanupHandlers();const a=a=>{this.updateClientConfiguration(a).then(a=>{a.ok&&this.configurationUpdateCallback&&this.configurationUpdateCallback()})};this.eventSource.open(a)}handlePollingUpdates(){this.cleanupHandlers();try{this.updateConfigurationIntervalId=setInterval(this.updateClientConfiguration.bind(this),this.settings.updateInterval)}catch(a){throw this.updateConfigurationIntervalId&&clearInterval(this.updateConfigurationIntervalId),a}}onConfigurationUpdate(a){this.configurationUpdateCallback=a}get featureFlags(){return this.configurationData.featureFlags}get configuration(){return this.configurationData.configuration}get segments(){const a=new Map;return this.featureFlags.forEach(b=>{b.rules.forEach(b=>{b.segment&&!a.has(b.segment.id)&&a.set(b.segment.id,b.segment)})}),a}get ruleMap(){if(this.mappedRules.size)return this.mappedRules;const a=new Map;for(const b of this.featureFlags)for(const c of b.rules){const{id:d,experimentId:e,variationByExposition:f}=c,g=new Map;f.forEach(a=>{let{variationKey:b,variationId:c}=a;"number"==typeof c&&g.set(b,c)}),a.set(d,{featureId:b.id,experimentId:e,variations:g})}return this.mappedRules=a,a}get isConsentRequired(){return this.configuration.consentType===_types.ConsentType.Required}get hasAnyTargetedDeliveryRule(){return this.featureFlags.some(a=>a.environmentEnabled&&a.rules.some(a=>a.type===_types.RuleType.TARGETED_DELIVERY))}checkIntegrity(a){if(!a)return!1;const b=Object.keys(a);if(!b.length)return!1;const c=Object.keys(_constants.DEFAULT_CONFIGURATION_DATA);return b.sort().join()===c.sort().join()}checkShouldUpdate(){let a=!!(0<arguments.length&&void 0!==arguments[0])&&arguments[0];const{featureFlags:b,configuration:c}=this.configurationData,{updateInterval:d}=this.settings;if(a)return this.updateType=_types.UpdateType.Idle,!1;if(this.updateType=c.realTimeUpdate?_types.UpdateType.RealTime:_types.UpdateType.Polling,!b.length)return!0;const e=this.lastUpdate.getTime(),f=Date.now()-d;return e<f}readStorageData(){const a=this.storage.read();if(a.ok){const{data:b,lastUpdate:c}=a.data,d=this.checkIntegrity(b);d?(this.configurationData=b,this.lastUpdate=new Date(Date.parse(c))):(this.storage.write({data:_constants.DEFAULT_CONFIGURATION_DATA,lastUpdate:this.lastUpdate.toString()}),this.configurationData=_constants.DEFAULT_CONFIGURATION_DATA)}}async updateClientConfiguration(a){const b=await this.requester.getClientConfiguration(a);if(!b.ok){const{featureFlags:a}=this.configurationData;return a.length?(0,_tsRes.Ok)(!0):b}_utilities.Utilities.sendOfflineTracking({storage:this.offlineTrackingStorage,requester:this.requester});const{configuration:c,customData:d}=b.data;this.configurationData=b.data,null!==d&&void 0!==d&&d.length&&(this.dataManager.customDataIndexes=d),this.dataManager.clearTrees(),this.mappedRules.clear();const e=this.updateStorageData();if(!e.ok)return e;const f=c.realTimeUpdate?_types.UpdateType.RealTime:_types.UpdateType.Polling,g=f!==this.updateType;g&&(this.updateType=f,await this.initialize());const h=this.isConsentRequired&&!this.hasAnyTargetedDeliveryRule;return this.visitorCodeManager.consentRequired=h,(0,_tsRes.Ok)(g)}updateStorageData(){this.lastUpdate=new Date;const a={data:this.configurationData,lastUpdate:this.lastUpdate.toString()};return this.storage.write(a)}}exports.ClientConfiguration=ClientConfiguration;
|
|
2
2
|
//# sourceMappingURL=clientConfiguration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientConfiguration.js","names":["ClientConfiguration","a","b","settings","storage","requester","dataManager","externalClientConfiguration","offlineTrackingStorage","externalEventSource","externalVisitorCodeManager","_classCallCheck","_defineProperty","UpdateType","Idle","DEFAULT_CONFIGURATION_DATA","Map","lastUpdate","Date","visitorCodeManager","_createClass","key","value","apply","arguments","_asyncToGenerator","_regeneratorRuntime","mark","c","d","e","wrap","f","prev","next","readStorageData","isExternalConfiguration","shouldUpdate","checkShouldUpdate","updateClientConfiguration","updateResult","sent","ok","abrupt","isUpdateTypeToggled","data","Ok","handleExternalUpdates","updateType","RealTime","eventSource","handleRealTimeUpdates","Polling","handlePollingUpdates","stop","cleanupHandlers","close","updateConfigurationIntervalId","clearInterval","configurationData","ExternalEventSource","siteCode","updateEventCallback","timestamp","then","configurationUpdateCallback","open","setInterval","bind","updateInterval","err","onConfigurationUpdate","callback","get","featureFlags","configuration","segments","forEach","flag","rules","rule","segment","has","id","set","mappedRules","size","_createForOfIteratorHelper","s","n","done","featureFlag","g","_loop","experimentId","variationByExposition","variationMap","variationKey","variationId","featureId","variations","consentType","ConsentType","Required","some","environmentEnabled","type","RuleType","TARGETED_DELIVERY","checkIntegrity","fields","Object","keys","length","requiredFields","sort","join","skipChecks","realTimeUpdate","lastUpdateTime","getTime","updateWindowEdge","now","result","read","isStorageValid","parse","write","toString","h","i","j","k","l","getClientConfiguration","clientConfigurationResult","Utilities","sendOfflineTracking","customData","customDataIndexes","clearTrees","clear","updateStorageData","toggleUpdateType","initialize","consentRequired","isConsentRequired","hasAnyTargetedDeliveryRule","setConsentRequired","exports"],"sources":["../../src/clientConfiguration/clientConfiguration.ts"],"sourcesContent":["import { Ok, Result } from 'ts-res';\nimport { KameleoonError } from 'src/kameleoonError/kameleoonError';\nimport { ClientSettingsType } from 'src/clientSettings/types';\nimport { DataManager } from 'src/kameleoonData';\nimport { Requester } from 'src/requester';\nimport { SegmentType } from 'src/targeting';\nimport { IExternalStorage, ClientDataType } from 'src/storage';\nimport {\n ExternalEventSource,\n IEventSource,\n IExternalEventSourceConstructor,\n} from 'src/eventSource';\nimport { DEFAULT_CONFIGURATION_DATA } from './constants';\nimport {\n ClientConfigurationParametersType,\n ConfigurationDataType,\n ConfigurationType,\n ConsentType,\n FeatureFlagType,\n MappedRuleType,\n RuleType,\n UpdateType,\n} from './types';\nimport { Utilities } from 'src/utilities';\nimport { OfflineTracking } from 'src/storage/types';\nimport { VisitorCodeManager } from 'src/visitorCodeManager';\n\ninterface IClientConfiguration {\n initialize: (useCache?: boolean) => Promise<Result<void, KameleoonError>>;\n onConfigurationUpdate: (callback: () => void) => void;\n readonly featureFlags: FeatureFlagType[];\n readonly configuration: ConfigurationType;\n readonly segments: Map<string, SegmentType>;\n readonly ruleMap: Map<number, MappedRuleType>;\n}\n\nexport class ClientConfiguration implements IClientConfiguration {\n private configurationUpdateCallback?: () => void;\n private updateConfigurationIntervalId: NodeJS.Timer | null = null;\n private updateType: UpdateType = UpdateType.Idle;\n private configurationData: ConfigurationDataType = DEFAULT_CONFIGURATION_DATA;\n private settings: ClientSettingsType;\n private lastUpdate: Date;\n private storage: IExternalStorage<ClientDataType>;\n private offlineTrackingStorage: IExternalStorage<OfflineTracking>;\n private requester: Requester;\n private eventSource?: IEventSource;\n private externalEventSource: IExternalEventSourceConstructor;\n private externalClientConfiguration?: ConfigurationDataType;\n private mappedRules: Map<number, MappedRuleType> = new Map();\n private dataManager: DataManager;\n private visitorCodeManager: VisitorCodeManager;\n\n constructor({\n settings,\n storage,\n requester,\n dataManager,\n externalClientConfiguration,\n offlineTrackingStorage,\n externalEventSource,\n externalVisitorCodeManager,\n }: ClientConfigurationParametersType) {\n this.requester = requester;\n this.settings = settings;\n this.lastUpdate = new Date();\n this.storage = storage;\n this.dataManager = dataManager;\n this.externalClientConfiguration = externalClientConfiguration;\n this.offlineTrackingStorage = offlineTrackingStorage;\n this.externalEventSource = externalEventSource;\n this.visitorCodeManager = externalVisitorCodeManager;\n }\n\n public async initialize(): Promise<Result<void, KameleoonError>> {\n this.readStorageData();\n\n const isExternalConfiguration = Boolean(this.externalClientConfiguration);\n const shouldUpdate = this.checkShouldUpdate(isExternalConfiguration);\n\n if (shouldUpdate) {\n const updateResult = await this.updateClientConfiguration();\n\n if (!updateResult.ok) {\n return updateResult;\n }\n\n // --- Note ---\n // If update type is being toggled `initialize` will be called again\n // so we don't need to continue execution here\n const isUpdateTypeToggled = updateResult.data;\n\n if (isUpdateTypeToggled) {\n return Ok();\n }\n }\n\n if (isExternalConfiguration) {\n this.handleExternalUpdates();\n\n return Ok();\n }\n\n if (this.updateType === UpdateType.RealTime && !this.eventSource) {\n this.updateType = UpdateType.Idle;\n this.handleRealTimeUpdates();\n\n return Ok();\n }\n\n if (this.updateType === UpdateType.Polling) {\n this.handlePollingUpdates();\n }\n\n return Ok();\n }\n\n private cleanupHandlers(): void {\n if (this.eventSource) {\n this.eventSource.close();\n }\n\n if (this.updateConfigurationIntervalId) {\n clearInterval(this.updateConfigurationIntervalId);\n }\n }\n\n private handleExternalUpdates(): void {\n this.cleanupHandlers();\n\n this.configurationData = this.externalClientConfiguration!;\n }\n\n private handleRealTimeUpdates(): void {\n this.cleanupHandlers();\n\n this.eventSource = new ExternalEventSource(\n this.settings.siteCode,\n this.externalEventSource,\n );\n\n const updateEventCallback = (timestamp: number) => {\n this.updateClientConfiguration(timestamp).then((updateResult) => {\n if (updateResult.ok && this.configurationUpdateCallback) {\n this.configurationUpdateCallback();\n }\n });\n };\n\n this.eventSource.open(updateEventCallback);\n }\n\n private handlePollingUpdates(): void {\n // --- Note ---\n // If `initialize` is called again the interval will be cleared\n // so theoretically we will constantly defer config update\n // but `this.lastUpdate` with `checkShouldUpdate` will prevent that\n this.cleanupHandlers();\n\n // --- Note ---\n // Error Handling is for `setInterval` emergency cleanup\n try {\n this.updateConfigurationIntervalId = setInterval(\n this.updateClientConfiguration.bind(this),\n this.settings.updateInterval,\n );\n } catch (err) {\n if (this.updateConfigurationIntervalId) {\n clearInterval(this.updateConfigurationIntervalId);\n }\n\n throw err;\n }\n }\n\n public onConfigurationUpdate(callback: () => void): void {\n this.configurationUpdateCallback = callback;\n }\n\n get featureFlags(): FeatureFlagType[] {\n return this.configurationData.featureFlags;\n }\n\n get configuration(): ConfigurationType {\n return this.configurationData.configuration;\n }\n\n get segments(): Map<string, SegmentType> {\n const segments = new Map();\n\n this.featureFlags.forEach((flag) => {\n flag.rules.forEach((rule) => {\n if (rule.segment && !segments.has(rule.segment.id)) {\n segments.set(rule.segment.id, rule.segment);\n }\n });\n });\n\n return segments;\n }\n\n get ruleMap(): Map<number, MappedRuleType> {\n if (this.mappedRules.size) {\n return this.mappedRules;\n }\n\n const mappedRules = new Map<number, MappedRuleType>();\n\n for (const featureFlag of this.featureFlags) {\n for (const rule of featureFlag.rules) {\n const { id, experimentId, variationByExposition } = rule;\n const variationMap = new Map<string, number>();\n\n variationByExposition.forEach(({ variationKey, variationId }) => {\n if (typeof variationId === 'number') {\n variationMap.set(variationKey, variationId);\n }\n });\n\n mappedRules.set(id, {\n featureId: featureFlag.id,\n experimentId,\n variations: variationMap,\n });\n }\n }\n\n this.mappedRules = mappedRules;\n\n return mappedRules;\n }\n\n get isConsentRequired(): boolean {\n return this.configuration.consentType === ConsentType.Required;\n }\n\n get hasAnyTargetedDeliveryRule(): boolean {\n return this.featureFlags.some(\n (featureFlag) =>\n featureFlag.environmentEnabled &&\n featureFlag.rules.some(\n (rule) => rule.type === RuleType.TARGETED_DELIVERY,\n ),\n );\n }\n\n // --- Note ---\n // Integrity check covers most of the migration scenarios\n // however in the future it will be changed to a dedicate migration\n // block that can handle all versions migrations\n private checkIntegrity(data: ConfigurationDataType | undefined): boolean {\n if (!data) {\n return false;\n }\n\n const fields = Object.keys(data);\n\n if (!fields.length) {\n return false;\n }\n\n const requiredFields = Object.keys(DEFAULT_CONFIGURATION_DATA);\n\n return fields.sort().join() === requiredFields.sort().join();\n }\n\n private checkShouldUpdate(skipChecks = false): boolean {\n const { featureFlags, configuration } = this.configurationData;\n const { updateInterval } = this.settings;\n\n // --- Note ---\n // Following `updateType` logic is done for client side\n // edge cases where we have previous campaigns on storage already, but we still want\n // to initialize SSE/Polling after page reload\n if (skipChecks) {\n this.updateType = UpdateType.Idle;\n\n return false;\n }\n\n this.updateType = configuration.realTimeUpdate\n ? UpdateType.RealTime\n : UpdateType.Polling;\n\n if (!featureFlags.length) {\n return true;\n }\n\n const lastUpdateTime = this.lastUpdate.getTime();\n const updateWindowEdge = Date.now() - updateInterval;\n\n return lastUpdateTime < updateWindowEdge;\n }\n\n private readStorageData(): void {\n const result = this.storage.read();\n\n if (result.ok) {\n const { data, lastUpdate } = result.data;\n\n const isStorageValid = this.checkIntegrity(data);\n\n // --- Note ---\n // Cleaning up storage if it's not valid for migration purposes\n if (!isStorageValid) {\n this.storage.write({\n data: DEFAULT_CONFIGURATION_DATA,\n lastUpdate: this.lastUpdate.toString(),\n });\n\n this.configurationData = DEFAULT_CONFIGURATION_DATA;\n } else {\n this.configurationData = data;\n this.lastUpdate = new Date(Date.parse(lastUpdate));\n }\n }\n }\n\n /**\n * Updates client configuration\n *\n * @param timeStamp - timestamp for real-time configuration update\n *\n * @returns `true` if current update type should be toggled (SSE/Polling)\n */\n private async updateClientConfiguration(\n timestamp?: number,\n ): Promise<Result<boolean, KameleoonError>> {\n const clientConfigurationResult =\n await this.requester.getClientConfiguration(timestamp);\n\n if (!clientConfigurationResult.ok) {\n const { featureFlags } = this.configurationData;\n\n if (featureFlags.length) {\n // TODO: the case of silent fail should be logged when logging is implemented\n return Ok(true);\n }\n\n return clientConfigurationResult;\n }\n\n Utilities.sendOfflineTracking({\n storage: this.offlineTrackingStorage,\n requester: this.requester,\n });\n\n const { configuration, customData } = clientConfigurationResult.data;\n\n this.configurationData = clientConfigurationResult.data;\n\n if (customData?.length) {\n this.dataManager.customDataIndexes = customData;\n }\n\n this.dataManager.clearTrees();\n this.mappedRules.clear();\n\n const result = this.updateStorageData();\n\n if (!result.ok) {\n return result;\n }\n\n const updateType = configuration.realTimeUpdate\n ? UpdateType.RealTime\n : UpdateType.Polling;\n\n const toggleUpdateType = updateType !== this.updateType;\n\n if (toggleUpdateType) {\n this.updateType = updateType;\n await this.initialize();\n }\n\n // --- Note ---\n // Regarding GDPR policy we should set visitorCode if legal consent isn't required\n // or we have at least one Targeted Delivery rule in configuration\n const consentRequired =\n this.isConsentRequired && !this.hasAnyTargetedDeliveryRule;\n this.visitorCodeManager.setConsentRequired(consentRequired);\n\n return Ok(toggleUpdateType);\n }\n\n private updateStorageData(): Result<void, KameleoonError> {\n this.lastUpdate = new Date();\n\n const data: ClientDataType = {\n data: this.configurationData,\n lastUpdate: this.lastUpdate.toString(),\n };\n\n return this.storage.write(data);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clientConfiguration.js","names":["ClientConfiguration","constructor","a","settings","storage","requester","dataManager","externalClientConfiguration","offlineTrackingStorage","eventSource","externalVisitorCodeManager","_defineProperty","UpdateType","Idle","DEFAULT_CONFIGURATION_DATA","Map","lastUpdate","Date","visitorCodeManager","initialize","readStorageData","isExternalConfiguration","shouldUpdate","checkShouldUpdate","updateResult","updateClientConfiguration","ok","isUpdateTypeToggled","data","Ok","handleExternalUpdates","updateType","RealTime","isOpen","Polling","handlePollingUpdates","handleRealTimeUpdates","cleanupHandlers","close","updateConfigurationIntervalId","clearInterval","configurationData","updateEventCallback","timestamp","then","configurationUpdateCallback","open","setInterval","bind","updateInterval","err","onConfigurationUpdate","callback","featureFlags","configuration","segments","forEach","flag","rules","rule","segment","has","id","set","ruleMap","mappedRules","size","featureFlag","experimentId","variationByExposition","variationMap","variationKey","variationId","featureId","variations","isConsentRequired","consentType","ConsentType","Required","hasAnyTargetedDeliveryRule","some","environmentEnabled","type","RuleType","TARGETED_DELIVERY","checkIntegrity","fields","Object","keys","length","requiredFields","sort","join","skipChecks","arguments","realTimeUpdate","lastUpdateTime","getTime","updateWindowEdge","now","result","read","isStorageValid","parse","write","toString","clientConfigurationResult","getClientConfiguration","Utilities","sendOfflineTracking","customData","customDataIndexes","clearTrees","clear","updateStorageData","toggleUpdateType","consentRequired","exports"],"sources":["../../src/clientConfiguration/clientConfiguration.ts"],"sourcesContent":["import { Ok, Result } from 'ts-res';\nimport { KameleoonError } from 'src/kameleoonError/kameleoonError';\nimport { ClientSettingsType } from 'src/clientSettings/types';\nimport { DataManager } from 'src/kameleoonData';\nimport { Requester } from 'src/requester';\nimport { SegmentType } from 'src/targeting';\nimport { ClientDataType } from 'src/storage';\nimport { IEventSource } from 'src/eventSource';\nimport { DEFAULT_CONFIGURATION_DATA } from './constants';\nimport {\n ClientConfigurationParametersType,\n ConfigurationDataType,\n ConfigurationType,\n ConsentType,\n FeatureFlagType,\n MappedRuleType,\n RuleType,\n UpdateType,\n} from './types';\nimport { Utilities } from 'src/utilities';\nimport { IStorage, OfflineTracking } from 'src/storage/types';\nimport { IVisitorCodeManager } from 'src/visitorCodeManager';\n\ninterface IClientConfiguration {\n initialize: (useCache?: boolean) => Promise<Result<void, KameleoonError>>;\n onConfigurationUpdate: (callback: () => void) => void;\n readonly featureFlags: FeatureFlagType[];\n readonly configuration: ConfigurationType;\n readonly segments: Map<string, SegmentType>;\n readonly ruleMap: Map<number, MappedRuleType>;\n}\n\nexport class ClientConfiguration implements IClientConfiguration {\n private configurationUpdateCallback?: () => void;\n private updateConfigurationIntervalId: NodeJS.Timer | null = null;\n private updateType: UpdateType = UpdateType.Idle;\n private configurationData: ConfigurationDataType = DEFAULT_CONFIGURATION_DATA;\n private settings: ClientSettingsType;\n private lastUpdate: Date;\n private storage: IStorage<ClientDataType>;\n private offlineTrackingStorage: IStorage<OfflineTracking>;\n private requester: Requester;\n private eventSource: IEventSource;\n private externalClientConfiguration?: ConfigurationDataType;\n private mappedRules: Map<number, MappedRuleType> = new Map();\n private dataManager: DataManager;\n private visitorCodeManager: IVisitorCodeManager;\n\n constructor({\n settings,\n storage,\n requester,\n dataManager,\n externalClientConfiguration,\n offlineTrackingStorage,\n eventSource,\n externalVisitorCodeManager,\n }: ClientConfigurationParametersType) {\n this.requester = requester;\n this.settings = settings;\n this.lastUpdate = new Date();\n this.storage = storage;\n this.dataManager = dataManager;\n this.externalClientConfiguration = externalClientConfiguration;\n this.offlineTrackingStorage = offlineTrackingStorage;\n this.visitorCodeManager = externalVisitorCodeManager;\n this.eventSource = eventSource;\n }\n\n public async initialize(): Promise<Result<void, KameleoonError>> {\n this.readStorageData();\n\n const isExternalConfiguration = Boolean(this.externalClientConfiguration);\n const shouldUpdate = this.checkShouldUpdate(isExternalConfiguration);\n\n if (shouldUpdate) {\n const updateResult = await this.updateClientConfiguration();\n\n if (!updateResult.ok) {\n return updateResult;\n }\n\n // --- Note ---\n // If update type is being toggled `initialize` will be called again\n // so we don't need to continue execution here\n const isUpdateTypeToggled = updateResult.data;\n\n if (isUpdateTypeToggled) {\n return Ok();\n }\n }\n\n if (isExternalConfiguration) {\n this.handleExternalUpdates();\n\n return Ok();\n }\n\n if (this.updateType === UpdateType.RealTime && !this.eventSource.isOpen) {\n this.updateType = UpdateType.Idle;\n this.handleRealTimeUpdates();\n\n return Ok();\n }\n\n if (this.updateType === UpdateType.Polling) {\n this.handlePollingUpdates();\n }\n\n return Ok();\n }\n\n private cleanupHandlers(): void {\n if (this.eventSource.isOpen) {\n this.eventSource.close();\n }\n\n if (this.updateConfigurationIntervalId) {\n clearInterval(this.updateConfigurationIntervalId);\n }\n }\n\n private handleExternalUpdates(): void {\n this.cleanupHandlers();\n\n this.configurationData = this.externalClientConfiguration!;\n }\n\n private handleRealTimeUpdates(): void {\n this.cleanupHandlers();\n\n const updateEventCallback = (timestamp: number) => {\n this.updateClientConfiguration(timestamp).then((updateResult) => {\n if (updateResult.ok && this.configurationUpdateCallback) {\n this.configurationUpdateCallback();\n }\n });\n };\n\n this.eventSource.open(updateEventCallback);\n }\n\n private handlePollingUpdates(): void {\n // --- Note ---\n // If `initialize` is called again the interval will be cleared\n // so theoretically we will constantly defer config update\n // but `this.lastUpdate` with `checkShouldUpdate` will prevent that\n this.cleanupHandlers();\n\n // --- Note ---\n // Error Handling is for `setInterval` emergency cleanup\n try {\n this.updateConfigurationIntervalId = setInterval(\n this.updateClientConfiguration.bind(this),\n this.settings.updateInterval,\n );\n } catch (err) {\n if (this.updateConfigurationIntervalId) {\n clearInterval(this.updateConfigurationIntervalId);\n }\n\n throw err;\n }\n }\n\n public onConfigurationUpdate(callback: () => void): void {\n this.configurationUpdateCallback = callback;\n }\n\n get featureFlags(): FeatureFlagType[] {\n return this.configurationData.featureFlags;\n }\n\n get configuration(): ConfigurationType {\n return this.configurationData.configuration;\n }\n\n get segments(): Map<string, SegmentType> {\n const segments = new Map();\n\n this.featureFlags.forEach((flag) => {\n flag.rules.forEach((rule) => {\n if (rule.segment && !segments.has(rule.segment.id)) {\n segments.set(rule.segment.id, rule.segment);\n }\n });\n });\n\n return segments;\n }\n\n get ruleMap(): Map<number, MappedRuleType> {\n if (this.mappedRules.size) {\n return this.mappedRules;\n }\n\n const mappedRules = new Map<number, MappedRuleType>();\n\n for (const featureFlag of this.featureFlags) {\n for (const rule of featureFlag.rules) {\n const { id, experimentId, variationByExposition } = rule;\n const variationMap = new Map<string, number>();\n\n variationByExposition.forEach(({ variationKey, variationId }) => {\n if (typeof variationId === 'number') {\n variationMap.set(variationKey, variationId);\n }\n });\n\n mappedRules.set(id, {\n featureId: featureFlag.id,\n experimentId,\n variations: variationMap,\n });\n }\n }\n\n this.mappedRules = mappedRules;\n\n return mappedRules;\n }\n\n get isConsentRequired(): boolean {\n return this.configuration.consentType === ConsentType.Required;\n }\n\n get hasAnyTargetedDeliveryRule(): boolean {\n return this.featureFlags.some(\n (featureFlag) =>\n featureFlag.environmentEnabled &&\n featureFlag.rules.some(\n (rule) => rule.type === RuleType.TARGETED_DELIVERY,\n ),\n );\n }\n\n // --- Note ---\n // Integrity check covers most of the migration scenarios\n // however in the future it will be changed to a dedicate migration\n // block that can handle all versions migrations\n private checkIntegrity(data: ConfigurationDataType | undefined): boolean {\n if (!data) {\n return false;\n }\n\n const fields = Object.keys(data);\n\n if (!fields.length) {\n return false;\n }\n\n const requiredFields = Object.keys(DEFAULT_CONFIGURATION_DATA);\n\n return fields.sort().join() === requiredFields.sort().join();\n }\n\n private checkShouldUpdate(skipChecks = false): boolean {\n const { featureFlags, configuration } = this.configurationData;\n const { updateInterval } = this.settings;\n\n // --- Note ---\n // Following `updateType` logic is done for client side\n // edge cases where we have previous campaigns on storage already, but we still want\n // to initialize SSE/Polling after page reload\n if (skipChecks) {\n this.updateType = UpdateType.Idle;\n\n return false;\n }\n\n this.updateType = configuration.realTimeUpdate\n ? UpdateType.RealTime\n : UpdateType.Polling;\n\n if (!featureFlags.length) {\n return true;\n }\n\n const lastUpdateTime = this.lastUpdate.getTime();\n const updateWindowEdge = Date.now() - updateInterval;\n\n return lastUpdateTime < updateWindowEdge;\n }\n\n private readStorageData(): void {\n const result = this.storage.read();\n\n if (result.ok) {\n const { data, lastUpdate } = result.data;\n\n const isStorageValid = this.checkIntegrity(data);\n\n // --- Note ---\n // Cleaning up storage if it's not valid for migration purposes\n if (!isStorageValid) {\n this.storage.write({\n data: DEFAULT_CONFIGURATION_DATA,\n lastUpdate: this.lastUpdate.toString(),\n });\n\n this.configurationData = DEFAULT_CONFIGURATION_DATA;\n } else {\n this.configurationData = data;\n this.lastUpdate = new Date(Date.parse(lastUpdate));\n }\n }\n }\n\n /**\n * Updates client configuration\n *\n * @param timeStamp - timestamp for real-time configuration update\n *\n * @returns `true` if current update type should be toggled (SSE/Polling)\n */\n private async updateClientConfiguration(\n timestamp?: number,\n ): Promise<Result<boolean, KameleoonError>> {\n const clientConfigurationResult =\n await this.requester.getClientConfiguration(timestamp);\n\n if (!clientConfigurationResult.ok) {\n const { featureFlags } = this.configurationData;\n\n if (featureFlags.length) {\n // TODO: the case of silent fail should be logged when logging is implemented\n return Ok(true);\n }\n\n return clientConfigurationResult;\n }\n\n Utilities.sendOfflineTracking({\n storage: this.offlineTrackingStorage,\n requester: this.requester,\n });\n\n const { configuration, customData } = clientConfigurationResult.data;\n\n this.configurationData = clientConfigurationResult.data;\n\n if (customData?.length) {\n this.dataManager.customDataIndexes = customData;\n }\n\n this.dataManager.clearTrees();\n this.mappedRules.clear();\n\n const result = this.updateStorageData();\n\n if (!result.ok) {\n return result;\n }\n\n const updateType = configuration.realTimeUpdate\n ? UpdateType.RealTime\n : UpdateType.Polling;\n\n const toggleUpdateType = updateType !== this.updateType;\n\n if (toggleUpdateType) {\n this.updateType = updateType;\n await this.initialize();\n }\n\n // --- Note ---\n // Regarding GDPR policy we should set visitorCode if legal consent isn't required\n // or we have at least one Targeted Delivery rule in configuration\n const consentRequired =\n this.isConsentRequired && !this.hasAnyTargetedDeliveryRule;\n this.visitorCodeManager.consentRequired = consentRequired;\n\n return Ok(toggleUpdateType);\n }\n\n private updateStorageData(): Result<void, KameleoonError> {\n this.lastUpdate = new Date();\n\n const data: ClientDataType = {\n data: this.configurationData,\n lastUpdate: this.lastUpdate.toString(),\n };\n\n return this.storage.write(data);\n }\n}\n"],"mappings":"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"}
|