@kameleoon/javascript-sdk-core 4.4.6 → 4.4.7
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
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 4.4.7 (2024-08-30)
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed the issue - some feature experiment conditions could resolve to incorrect values on interval configuration update
|
|
8
|
+
|
|
3
9
|
## 4.4.6 (2024-08-15)
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
6
12
|
|
|
7
|
-
-
|
|
13
|
+
- Fixed the issue with mapping identifier Custom Data not being set correctly after browser tab reload
|
|
8
14
|
|
|
9
15
|
## 4.4.5 (2024-08-08)
|
|
10
16
|
|
|
@@ -1,2 +1,2 @@
|
|
|
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"),_eventManager=require("../eventManager"),_urlProvider=require("../requester/urlProvider");function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return 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||!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{updateInterval:b,storage:c,requester:d,dataManager:e,externalClientConfiguration:f,offlineTrackingStorage:g,eventSource:h,externalVisitorCodeManager:i,eventManager:j}=a;_defineProperty(this,"updateConfigurationIntervalId",null),_defineProperty(this,"updateType",_types.UpdateType.Idle),_defineProperty(this,"configurationData",_constants.DEFAULT_CONFIGURATION_DATA),_defineProperty(this,"featureFlagsData",new Map),_defineProperty(this,"isTargetedDeliveryRule",null),_defineProperty(this,"segmentsData",null),_defineProperty(this,"updateInterval",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",null),_defineProperty(this,"dataManager",void 0),_defineProperty(this,"visitorCodeManager",void 0),_defineProperty(this,"eventManager",void 0),this.requester=d,this.updateInterval=b,this.lastUpdate=new Date,this.storage=c,this.dataManager=e,this.eventManager=j,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();const{customData:a,configuration:b,featureFlags:c}=this.externalClientConfiguration;this.configurationData={customData:a,configuration:b};for(const a of c)this.featureFlagsData.set(a.featureKey,a)}handleRealTimeUpdates(){this.cleanupHandlers();const a=a=>{this.updateClientConfiguration(a).then(b=>{b.ok&&this.eventManager.fireEvent(_eventManager.EventType.ConfigurationUpdate,{timestamp:a})})};this.eventSource.open(a)}handlePollingUpdates(){this.cleanupHandlers();try{this.updateConfigurationIntervalId=setInterval(this.updateClientConfiguration.bind(this),this.updateInterval)}catch(a){throw this.updateConfigurationIntervalId&&clearInterval(this.updateConfigurationIntervalId),a}}get featureFlags(){return this.featureFlagsData}get configuration(){return this.configurationData.configuration}get segments(){if(this.segmentsData)return this.segmentsData;const a=new Map;return this.featureFlagsData.forEach(b=>{b.rules.forEach(b=>{b.segment&&!a.has(b.segment.id)&&a.set(b.segment.id,b.segment)})}),this.segmentsData=a,a}get ruleMap(){if(this.mappedRules)return this.mappedRules;const
|
|
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"),_eventManager=require("../eventManager"),_urlProvider=require("../requester/urlProvider");function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return 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||!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{updateInterval:b,storage:c,requester:d,dataManager:e,externalClientConfiguration:f,offlineTrackingStorage:g,eventSource:h,externalVisitorCodeManager:i,eventManager:j}=a;_defineProperty(this,"updateConfigurationIntervalId",null),_defineProperty(this,"updateType",_types.UpdateType.Idle),_defineProperty(this,"configurationData",_constants.DEFAULT_CONFIGURATION_DATA),_defineProperty(this,"featureFlagsData",new Map),_defineProperty(this,"isTargetedDeliveryRule",null),_defineProperty(this,"segmentsData",null),_defineProperty(this,"updateInterval",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",null),_defineProperty(this,"dataManager",void 0),_defineProperty(this,"visitorCodeManager",void 0),_defineProperty(this,"eventManager",void 0),this.requester=d,this.updateInterval=b,this.lastUpdate=new Date,this.storage=c,this.dataManager=e,this.eventManager=j,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();const{customData:a,configuration:b,featureFlags:c}=this.externalClientConfiguration;this.configurationData={customData:a,configuration:b};for(const a of c)this.featureFlagsData.set(a.featureKey,a)}handleRealTimeUpdates(){this.cleanupHandlers();const a=a=>{this.updateClientConfiguration(a).then(b=>{b.ok&&this.eventManager.fireEvent(_eventManager.EventType.ConfigurationUpdate,{timestamp:a})})};this.eventSource.open(a)}handlePollingUpdates(){this.cleanupHandlers();try{this.updateConfigurationIntervalId=setInterval(this.updateClientConfiguration.bind(this),this.updateInterval)}catch(a){throw this.updateConfigurationIntervalId&&clearInterval(this.updateConfigurationIntervalId),a}}get featureFlags(){return this.featureFlagsData}get configuration(){return this.configurationData.configuration}get segments(){if(this.segmentsData)return this.segmentsData;const a=new Map;return this.featureFlagsData.forEach(b=>{b.rules.forEach(b=>{b.segment&&!a.has(b.segment.id)&&a.set(b.segment.id,b.segment)})}),this.segmentsData=a,a}get ruleMap(){var a;if(null!==(a=this.mappedRules)&&void 0!==a&&a.size)return this.mappedRules;const b=new Map;for(const a of this.featureFlags.values())for(const c of a.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)}),b.set(d,{featureId:a.id,experimentId:e,variations:g})}return this.mappedRules=b,b}get isConsentRequired(){return this.configuration.consentType===_types.ConsentType.Required}get hasAnyTargetedDeliveryRule(){if(null!==this.isTargetedDeliveryRule)return this.isTargetedDeliveryRule;for(const a of this.featureFlags.values())if(a.environmentEnabled&&a.rules.some(a=>a.type===_types.RuleType.TARGETED_DELIVERY))return!0;return!1}checkIntegrity(a){if(!a)return!1;const b=Object.keys(a);if(!b.length)return!1;const c=Object.keys(_constants.DEFAULT_CLIENT_CONFIGURATION);return b.sort().join()===c.sort().join()}checkShouldUpdate(){let a=!!(0<arguments.length&&void 0!==arguments[0])&&arguments[0];const{configuration:b}=this.configurationData;if(a)return this.updateType=_types.UpdateType.Idle,!1;if(this.updateType=b.realTimeUpdate?_types.UpdateType.RealTime:_types.UpdateType.Polling,!this.featureFlags.size)return!0;const c=this.lastUpdate.getTime(),d=Date.now()-this.updateInterval;return c<d}readStorageData(){const a=this.storage.read();if(a.ok){const{data:b,lastUpdate:c}=a.data,d=this.checkIntegrity(b);if(!d){_urlProvider.UrlProvider.setDataApiDomain(_constants.DEFAULT_CONFIGURATION_DATA.configuration.dataApiDomain);const a=_objectSpread(_objectSpread({},_constants.DEFAULT_CONFIGURATION_DATA),{},{featureFlags:[]});this.storage.write({data:a,lastUpdate:this.lastUpdate.toString()}),this.configurationData=_constants.DEFAULT_CONFIGURATION_DATA}else{_urlProvider.UrlProvider.setDataApiDomain(b.configuration.dataApiDomain);const{featureFlags:a,customData:d}=b;null!==d&&void 0!==d&&d.length&&(this.dataManager.customDataIndexes=d);for(const b of a)this.featureFlagsData.set(b.featureKey,b);this.configurationData=b,this.lastUpdate=new Date(Date.parse(c))}}}async updateClientConfiguration(a){var b;const c=await this.requester.getClientConfiguration(a);if(!c.ok)return this.featureFlags.size?(0,_tsRes.Ok)(!0):c;_utilities.Utilities.sendOfflineTracking({storage:this.offlineTrackingStorage,requester:this.requester});const{configuration:d,customData:e,featureFlags:f}=c.data;this.configurationData={configuration:d,customData:e};for(const b of f)this.featureFlagsData.set(b.featureKey,b);null!==e&&void 0!==e&&e.length&&(this.dataManager.customDataIndexes=e),this.dataManager.clearTrees(),null===(b=this.mappedRules)||void 0===b?void 0:b.clear(),this.isTargetedDeliveryRule=null,this.segmentsData=null;const g=this.updateStorageData();if(!g.ok)return g;const h=d.realTimeUpdate?_types.UpdateType.RealTime:_types.UpdateType.Polling,i=h!==this.updateType;i&&(this.updateType=h,await this.initialize());const j=this.isConsentRequired&&!this.hasAnyTargetedDeliveryRule;return this.visitorCodeManager.consentRequired=j,(0,_tsRes.Ok)(i)}updateStorageData(){this.lastUpdate=new Date;const a=_objectSpread(_objectSpread({},this.configurationData),{},{featureFlags:Array.from(this.featureFlags.values())}),b={data:a,lastUpdate:this.lastUpdate.toString()};return _urlProvider.UrlProvider.setDataApiDomain(this.configurationData.configuration.dataApiDomain),this.storage.write(b)}}exports.ClientConfiguration=ClientConfiguration;
|
|
2
2
|
//# sourceMappingURL=clientConfiguration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientConfiguration.js","names":["ClientConfiguration","constructor","a","updateInterval","storage","requester","dataManager","externalClientConfiguration","offlineTrackingStorage","eventSource","externalVisitorCodeManager","eventManager","_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","customData","configuration","featureFlags","configurationData","featureFlag","featureFlagsData","set","featureKey","updateEventCallback","timestamp","then","fireEvent","EventType","ConfigurationUpdate","open","setInterval","bind","err","segments","segmentsData","forEach","flag","rules","rule","segment","has","id","ruleMap","mappedRules","values","experimentId","variationByExposition","variationMap","variationKey","variationId","featureId","variations","isConsentRequired","consentType","ConsentType","Required","hasAnyTargetedDeliveryRule","isTargetedDeliveryRule","environmentEnabled","some","type","RuleType","TARGETED_DELIVERY","checkIntegrity","fields","Object","keys","length","requiredFields","DEFAULT_CLIENT_CONFIGURATION","sort","join","skipChecks","arguments","realTimeUpdate","size","lastUpdateTime","getTime","updateWindowEdge","now","result","read","isStorageValid","UrlProvider","setDataApiDomain","dataApiDomain","_objectSpread","write","toString","customDataIndexes","parse","b","clientConfigurationResult","getClientConfiguration","Utilities","sendOfflineTracking","clearTrees","clear","updateStorageData","toggleUpdateType","consentRequired","Array","from","exports"],"sources":["../../src/clientConfiguration/clientConfiguration.ts"],"sourcesContent":["import { Ok, Result } from 'ts-res';\nimport { KameleoonError } from 'src/kameleoonError/kameleoonError';\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 {\n DEFAULT_CLIENT_CONFIGURATION,\n DEFAULT_CONFIGURATION_DATA,\n} from './constants';\nimport {\n ClientConfigurationDataType,\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';\nimport { EventManager, EventType } from 'src/eventManager';\nimport { UrlProvider } from 'src/requester/urlProvider';\n\ninterface IClientConfiguration {\n initialize: (useCache?: boolean) => Promise<Result<void, KameleoonError>>;\n readonly featureFlags: Map<string, 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 updateConfigurationIntervalId: NodeJS.Timeout | null = null;\n private updateType: UpdateType = UpdateType.Idle;\n private configurationData: ClientConfigurationDataType =\n DEFAULT_CONFIGURATION_DATA;\n private featureFlagsData: Map<string, FeatureFlagType> = new Map();\n private isTargetedDeliveryRule: boolean | null = null;\n private segmentsData: Map<string, SegmentType> | null = null;\n private updateInterval: number;\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> | null = null;\n private dataManager: DataManager;\n private visitorCodeManager: IVisitorCodeManager;\n private eventManager: EventManager;\n\n constructor({\n updateInterval,\n storage,\n requester,\n dataManager,\n externalClientConfiguration,\n offlineTrackingStorage,\n eventSource,\n externalVisitorCodeManager,\n eventManager,\n }: ClientConfigurationParametersType) {\n this.requester = requester;\n this.updateInterval = updateInterval;\n this.lastUpdate = new Date();\n this.storage = storage;\n this.dataManager = dataManager;\n this.eventManager = eventManager;\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 const { customData, configuration, featureFlags } =\n this.externalClientConfiguration!;\n this.configurationData = { customData, configuration };\n\n for (const featureFlag of featureFlags) {\n this.featureFlagsData.set(featureFlag.featureKey, featureFlag);\n }\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) {\n this.eventManager.fireEvent(EventType.ConfigurationUpdate, {\n timestamp,\n });\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.updateInterval,\n );\n } catch (err) {\n if (this.updateConfigurationIntervalId) {\n clearInterval(this.updateConfigurationIntervalId);\n }\n\n throw err;\n }\n }\n\n get featureFlags(): Map<string, FeatureFlagType> {\n return this.featureFlagsData;\n }\n\n get configuration(): ConfigurationType {\n return this.configurationData.configuration;\n }\n\n get segments(): Map<string, SegmentType> {\n if (this.segmentsData) {\n return this.segmentsData;\n }\n\n const segmentsData = new Map<string, SegmentType>();\n\n this.featureFlagsData.forEach((flag) => {\n flag.rules.forEach((rule) => {\n if (rule.segment && !segmentsData.has(rule.segment.id)) {\n segmentsData.set(rule.segment.id, rule.segment);\n }\n });\n });\n\n this.segmentsData = segmentsData;\n\n return segmentsData;\n }\n\n get ruleMap(): Map<number, MappedRuleType> {\n if (this.mappedRules) {\n return this.mappedRules;\n }\n\n const mappedRules = new Map<number, MappedRuleType>();\n\n for (const featureFlag of this.featureFlags.values()) {\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 if (this.isTargetedDeliveryRule !== null) {\n return this.isTargetedDeliveryRule;\n }\n\n for (const featureFlag of this.featureFlags.values()) {\n if (\n featureFlag.environmentEnabled &&\n featureFlag.rules.some(\n (rule) => rule.type === RuleType.TARGETED_DELIVERY,\n )\n ) {\n return true;\n }\n }\n\n return false;\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_CLIENT_CONFIGURATION);\n\n return fields.sort().join() === requiredFields.sort().join();\n }\n\n private checkShouldUpdate(skipChecks = false): boolean {\n const { configuration } = this.configurationData;\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 (!this.featureFlags.size) {\n return true;\n }\n\n const lastUpdateTime = this.lastUpdate.getTime();\n const updateWindowEdge = Date.now() - this.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 UrlProvider.setDataApiDomain(\n DEFAULT_CONFIGURATION_DATA.configuration.dataApiDomain,\n );\n\n const data = {\n ...DEFAULT_CONFIGURATION_DATA,\n featureFlags: [],\n };\n\n this.storage.write({\n data,\n lastUpdate: this.lastUpdate.toString(),\n });\n\n this.configurationData = DEFAULT_CONFIGURATION_DATA;\n } else {\n UrlProvider.setDataApiDomain(data.configuration.dataApiDomain);\n\n const { featureFlags, customData } = data;\n\n if (customData?.length) {\n this.dataManager.customDataIndexes = customData;\n }\n\n for (const featureFlag of featureFlags) {\n this.featureFlagsData.set(featureFlag.featureKey, featureFlag);\n }\n\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 if (this.featureFlags.size) {\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, featureFlags } =\n clientConfigurationResult.data;\n\n this.configurationData = { configuration, customData };\n\n for (const featureFlag of featureFlags) {\n this.featureFlagsData.set(featureFlag.featureKey, featureFlag);\n }\n\n if (customData?.length) {\n this.dataManager.customDataIndexes = customData;\n }\n\n this.dataManager.clearTrees();\n this.mappedRules?.clear();\n this.isTargetedDeliveryRule = null;\n this.segmentsData = null;\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 configurationData = {\n ...this.configurationData,\n featureFlags: Array.from(this.featureFlags.values()),\n };\n\n const data: ClientDataType = {\n data: configurationData,\n lastUpdate: this.lastUpdate.toString(),\n };\n\n UrlProvider.setDataApiDomain(\n this.configurationData.configuration.dataApiDomain,\n );\n\n return this.storage.write(data);\n }\n}\n"],"mappings":"k6CAoCO,KAAM,CAAAA,mBAAoD,CAoB/DC,WAAWA,CAAAC,CAAA,CAU2B,IAV1B,CACVC,cAAc,CAAdA,CAAc,CACdC,OAAO,CAAPA,CAAO,CACPC,SAAS,CAATA,CAAS,CACTC,WAAW,CAAXA,CAAW,CACXC,2BAA2B,CAA3BA,CAA2B,CAC3BC,sBAAsB,CAAtBA,CAAsB,CACtBC,WAAW,CAAXA,CAAW,CACXC,0BAA0B,CAA1BA,CAA0B,CAC1BC,YAAY,CAAZA,CACiC,CAAC,CAAAT,CAAA,CAAAU,eAAA,sCA7B2B,IAAI,EAAAA,eAAA,mBAClCC,iBAAU,CAACC,IAAI,EAAAF,eAAA,0BAE9CG,qCAA0B,EAAAH,eAAA,yBAC6B,GAAI,CAAAI,GAAK,EAAAJ,eAAA,+BACjB,IAAI,EAAAA,eAAA,qBACG,IAAI,EAAAA,eAAA,+BAAAA,eAAA,2BAAAA,eAAA,wBAAAA,eAAA,uCAAAA,eAAA,0BAAAA,eAAA,4BAAAA,eAAA,4CAAAA,eAAA,oBAQF,IAAI,EAAAA,eAAA,4BAAAA,eAAA,mCAAAA,eAAA,6BAgB5D,IAAI,CAACP,SAAS,CAAGA,CAAS,CAC1B,IAAI,CAACF,cAAc,CAAGA,CAAc,CACpC,IAAI,CAACc,UAAU,CAAG,GAAI,CAAAC,IAAM,CAC5B,IAAI,CAACd,OAAO,CAAGA,CAAO,CACtB,IAAI,CAACE,WAAW,CAAGA,CAAW,CAC9B,IAAI,CAACK,YAAY,CAAGA,CAAY,CAChC,IAAI,CAACJ,2BAA2B,CAAGA,CAA2B,CAC9D,IAAI,CAACC,sBAAsB,CAAGA,CAAsB,CACpD,IAAI,CAACW,kBAAkB,CAAGT,CAA0B,CACpD,IAAI,CAACD,WAAW,CAAGA,CACrB,CAEA,KAAa,CAAAW,UAAUA,CAAA,CAA0C,CAC/D,IAAI,CAACC,eAAe,CAAC,CAAC,MAEhB,CAAAC,CAAuB,GAAW,IAAI,CAACf,2BAA4B,CACnEgB,CAAY,CAAG,IAAI,CAACC,iBAAiB,CAACF,CAAuB,CAAC,CAEpE,GAAIC,CAAY,CAAE,CAChB,KAAM,CAAAE,CAAY,CAAG,KAAM,KAAI,CAACC,yBAAyB,CAAC,CAAC,CAE3D,GAAI,CAACD,CAAY,CAACE,EAAE,CAClB,MAAO,CAAAF,CAAY,CAMrB,KAAM,CAAAG,CAAmB,CAAGH,CAAY,CAACI,IAAI,CAE7C,GAAID,CAAmB,CACrB,MAAO,GAAAE,SAAE,EAAC,CAEd,CAAC,MAEG,CAAAR,CAAuB,EACzB,IAAI,CAACS,qBAAqB,CAAC,CAAC,CAErB,GAAAD,SAAE,EAAC,CAAC,EAGT,IAAI,CAACE,UAAU,GAAKnB,iBAAU,CAACoB,QAAQ,EAAK,IAAI,CAACxB,WAAW,CAACyB,MAAM,EAOnE,IAAI,CAACF,UAAU,GAAKnB,iBAAU,CAACsB,OAAO,EACxC,IAAI,CAACC,oBAAoB,CAAC,CAAC,CAGtB,GAAAN,SAAE,EAAC,CAAC,GAVT,IAAI,CAACE,UAAU,CAAGnB,iBAAU,CAACC,IAAI,CACjC,IAAI,CAACuB,qBAAqB,CAAC,CAAC,CAErB,GAAAP,SAAE,EAAC,CAAC,CAQf,CAEQQ,eAAeA,CAAA,CAAS,CAC1B,IAAI,CAAC7B,WAAW,CAACyB,MAAM,EACzB,IAAI,CAACzB,WAAW,CAAC8B,KAAK,CAAC,CAAC,CAGtB,IAAI,CAACC,6BAA6B,EACpCC,aAAa,CAAC,IAAI,CAACD,6BAA6B,CAEpD,CAEQT,qBAAqBA,CAAA,CAAS,CACpC,IAAI,CAACO,eAAe,CAAC,CAAC,CAEtB,KAAM,CAAEI,UAAU,CAAVA,CAAU,CAAEC,aAAa,CAAbA,CAAa,CAAEC,YAAY,CAAZA,CAAa,CAAC,CAC/C,IAAI,CAACrC,2BAA4B,CACnC,IAAI,CAACsC,iBAAiB,CAAG,CAAEH,UAAU,CAAVA,CAAU,CAAEC,aAAa,CAAbA,CAAc,CAAC,CAEtD,IAAK,KAAM,CAAAG,CAAW,GAAI,CAAAF,CAAY,CACpC,IAAI,CAACG,gBAAgB,CAACC,GAAG,CAACF,CAAW,CAACG,UAAU,CAAEH,CAAW,CAEjE,CAEQT,qBAAqBA,CAAA,CAAS,CACpC,IAAI,CAACC,eAAe,CAAC,CAAC,CAEtB,KAAM,CAAAY,CAAmB,CAAIC,CAAiB,EAAK,CACjD,IAAI,CAACzB,yBAAyB,CAACyB,CAAS,CAAC,CAACC,IAAI,CAAE3B,CAAY,EAAK,CAC3DA,CAAY,CAACE,EAAE,EACjB,IAAI,CAAChB,YAAY,CAAC0C,SAAS,CAACC,uBAAS,CAACC,mBAAmB,CAAE,CACzDJ,SAAS,CAATA,CACF,CAAC,CAEL,CAAC,CACH,CAAC,CAED,IAAI,CAAC1C,WAAW,CAAC+C,IAAI,CAACN,CAAmB,CAC3C,CAEQd,oBAAoBA,CAAA,CAAS,CAKnC,IAAI,CAACE,eAAe,CAAC,CAAC,CAItB,GAAI,CACF,IAAI,CAACE,6BAA6B,CAAGiB,WAAW,CAC9C,IAAI,CAAC/B,yBAAyB,CAACgC,IAAI,CAAC,IAAI,CAAC,CACzC,IAAI,CAACvD,cACP,CACF,CAAE,MAAOwD,CAAG,CAAE,CAKZ,KAJI,KAAI,CAACnB,6BAA6B,EACpCC,aAAa,CAAC,IAAI,CAACD,6BAA6B,CAAC,CAG7CmB,CACR,CACF,CAEA,GAAI,CAAAf,YAAYA,CAAA,CAAiC,CAC/C,MAAO,KAAI,CAACG,gBACd,CAEA,GAAI,CAAAJ,aAAaA,CAAA,CAAsB,CACrC,MAAO,KAAI,CAACE,iBAAiB,CAACF,aAChC,CAEA,GAAI,CAAAiB,QAAQA,CAAA,CAA6B,CACvC,GAAI,IAAI,CAACC,YAAY,CACnB,MAAO,KAAI,CAACA,YAAY,CAG1B,KAAM,CAAAA,CAAY,CAAG,GAAI,CAAA7C,GAA0B,CAYnD,MAVA,KAAI,CAAC+B,gBAAgB,CAACe,OAAO,CAAEC,CAAI,EAAK,CACtCA,CAAI,CAACC,KAAK,CAACF,OAAO,CAAEG,CAAI,EAAK,CACvBA,CAAI,CAACC,OAAO,EAAI,CAACL,CAAY,CAACM,GAAG,CAACF,CAAI,CAACC,OAAO,CAACE,EAAE,CAAC,EACpDP,CAAY,CAACb,GAAG,CAACiB,CAAI,CAACC,OAAO,CAACE,EAAE,CAAEH,CAAI,CAACC,OAAO,CAElD,CAAC,CACH,CAAC,CAAC,CAEF,IAAI,CAACL,YAAY,CAAGA,CAAY,CAEzBA,CACT,CAEA,GAAI,CAAAQ,OAAOA,CAAA,CAAgC,CACzC,GAAI,IAAI,CAACC,WAAW,CAClB,MAAO,KAAI,CAACA,WAAW,CAGzB,KAAM,CAAAA,CAAW,CAAG,GAAI,CAAAtD,GAA6B,CAErD,IAAK,KAAM,CAAA8B,CAAW,GAAI,KAAI,CAACF,YAAY,CAAC2B,MAAM,CAAC,CAAC,CAClD,IAAK,KAAM,CAAAN,CAAI,GAAI,CAAAnB,CAAW,CAACkB,KAAK,CAAE,MAC9B,CAAEI,EAAE,CAAFA,CAAE,CAAEI,YAAY,CAAZA,CAAY,CAAEC,qBAAqB,CAArBA,CAAsB,CAAC,CAAGR,CAAI,CAClDS,CAAY,CAAG,GAAI,CAAA1D,GAAqB,CAE9CyD,CAAqB,CAACX,OAAO,CAAC5D,CAAA,EAAmC,IAAlC,CAAEyE,YAAY,CAAZA,CAAY,CAAEC,WAAW,CAAXA,CAAY,CAAC,CAAA1E,CAAA,CAC/B,QAAQ,EAA/B,MAAO,CAAA0E,CAAwB,EACjCF,CAAY,CAAC1B,GAAG,CAAC2B,CAAY,CAAEC,CAAW,CAE9C,CAAC,CAAC,CAEFN,CAAW,CAACtB,GAAG,CAACoB,CAAE,CAAE,CAClBS,SAAS,CAAE/B,CAAW,CAACsB,EAAE,CACzBI,YAAY,CAAZA,CAAY,CACZM,UAAU,CAAEJ,CACd,CAAC,CACH,CAKF,MAFA,KAAI,CAACJ,WAAW,CAAGA,CAAW,CAEvBA,CACT,CAEA,GAAI,CAAAS,iBAAiBA,CAAA,CAAY,CAC/B,MAAO,KAAI,CAACpC,aAAa,CAACqC,WAAW,GAAKC,kBAAW,CAACC,QACxD,CAEA,GAAI,CAAAC,0BAA0BA,CAAA,CAAY,CACxC,GAAoC,IAAI,GAApC,IAAI,CAACC,sBAA+B,CACtC,MAAO,KAAI,CAACA,sBAAsB,CAGpC,IAAK,KAAM,CAAAtC,CAAW,GAAI,KAAI,CAACF,YAAY,CAAC2B,MAAM,CAAC,CAAC,CAClD,GACEzB,CAAW,CAACuC,kBAAkB,EAC9BvC,CAAW,CAACkB,KAAK,CAACsB,IAAI,CACnBrB,CAAI,EAAKA,CAAI,CAACsB,IAAI,GAAKC,eAAQ,CAACC,iBACnC,CAAC,CAED,SAIJ,QACF,CAMQC,cAAcA,CAAC7D,CAAuC,CAAW,CACvE,GAAI,CAACA,CAAI,CACP,SAGF,KAAM,CAAA8D,CAAM,CAAGC,MAAM,CAACC,IAAI,CAAChE,CAAI,CAAC,CAEhC,GAAI,CAAC8D,CAAM,CAACG,MAAM,CAChB,SAGF,KAAM,CAAAC,CAAc,CAAGH,MAAM,CAACC,IAAI,CAACG,uCAA4B,CAAC,CAEhE,MAAO,CAAAL,CAAM,CAACM,IAAI,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC,GAAKH,CAAc,CAACE,IAAI,CAAC,CAAC,CAACC,IAAI,CAAC,CAC7D,CAEQ1E,iBAAiBA,CAAA,CAA8B,IAA7B,CAAA2E,CAAU,MAAAC,SAAA,CAAAN,MAAA,WAAAM,SAAA,MAAAA,SAAA,IAClC,KAAM,CAAEzD,aAAa,CAAbA,CAAc,CAAC,CAAG,IAAI,CAACE,iBAAiB,CAMhD,GAAIsD,CAAU,CAGZ,MAFA,KAAI,CAACnE,UAAU,CAAGnB,iBAAU,CAACC,IAAI,IASnC,GAJA,IAAI,CAACkB,UAAU,CAAGW,CAAa,CAAC0D,cAAc,CAC1CxF,iBAAU,CAACoB,QAAQ,CACnBpB,iBAAU,CAACsB,OAAO,CAElB,CAAC,IAAI,CAACS,YAAY,CAAC0D,IAAI,CACzB,SACD,KAEK,CAAAC,CAAc,CAAG,IAAI,CAACtF,UAAU,CAACuF,OAAO,CAAC,CAAC,CAC1CC,CAAgB,CAAGvF,IAAI,CAACwF,GAAG,CAAC,CAAC,CAAG,IAAI,CAACvG,cAAc,CAEzD,MAAO,CAAAoG,CAAc,CAAGE,CAC1B,CAEQpF,eAAeA,CAAA,CAAS,CAC9B,KAAM,CAAAsF,CAAM,CAAG,IAAI,CAACvG,OAAO,CAACwG,IAAI,CAAC,CAAC,CAElC,GAAID,CAAM,CAAChF,EAAE,CAAE,MACP,CAAEE,IAAI,CAAJA,CAAI,CAAEZ,UAAU,CAAVA,CAAW,CAAC,CAAG0F,CAAM,CAAC9E,IAAI,CAElCgF,CAAc,CAAG,IAAI,CAACnB,cAAc,CAAC7D,CAAI,CAAC,CAIhD,GAAI,CAACgF,CAAc,CAAE,CACnBC,wBAAW,CAACC,gBAAgB,CAC1BhG,qCAA0B,CAAC4B,aAAa,CAACqE,aAC3C,CAAC,CAED,KAAM,CAAAnF,CAAI,CAAAoF,aAAA,CAAAA,aAAA,IACLlG,qCAA0B,MAC7B6B,YAAY,CAAE,EAAE,EACjB,CAED,IAAI,CAACxC,OAAO,CAAC8G,KAAK,CAAC,CACjBrF,IAAI,CAAJA,CAAI,CACJZ,UAAU,CAAE,IAAI,CAACA,UAAU,CAACkG,QAAQ,CAAC,CACvC,CAAC,CAAC,CAEF,IAAI,CAACtE,iBAAiB,CAAG9B,qCAC3B,CAAC,IAAM,CACL+F,wBAAW,CAACC,gBAAgB,CAAClF,CAAI,CAACc,aAAa,CAACqE,aAAa,CAAC,CAE9D,KAAM,CAAEpE,YAAY,CAAZA,CAAY,CAAEF,UAAU,CAAVA,CAAW,CAAC,CAAGb,CAAI,CAAC,OAEtCa,CAAU,WAAVA,CAAU,EAAVA,CAAU,CAAEoD,MAAM,GACpB,IAAI,CAACxF,WAAW,CAAC8G,iBAAiB,CAAG1E,CAAU,EAGjD,IAAK,KAAM,CAAAI,CAAW,GAAI,CAAAF,CAAY,CACpC,IAAI,CAACG,gBAAgB,CAACC,GAAG,CAACF,CAAW,CAACG,UAAU,CAAEH,CAAW,CAAC,CAGhE,IAAI,CAACD,iBAAiB,CAAGhB,CAAI,CAC7B,IAAI,CAACZ,UAAU,CAAG,GAAI,CAAAC,IAAI,CAACA,IAAI,CAACmG,KAAK,CAACpG,CAAU,CAAC,CACnD,CACF,CACF,CASA,KAAc,CAAAS,yBAAyBA,CACrCyB,CAAkB,CACwB,KAAAmE,CAAA,CAC1C,KAAM,CAAAC,CAAyB,CAC7B,KAAM,KAAI,CAAClH,SAAS,CAACmH,sBAAsB,CAACrE,CAAS,CAAC,CAExD,GAAI,CAACoE,CAAyB,CAAC5F,EAAE,OAC3B,KAAI,CAACiB,YAAY,CAAC0D,IAAI,CAEjB,GAAAxE,SAAE,IAAK,CAAC,CAGVyF,CAAyB,CAGlCE,oBAAS,CAACC,mBAAmB,CAAC,CAC5BtH,OAAO,CAAE,IAAI,CAACI,sBAAsB,CACpCH,SAAS,CAAE,IAAI,CAACA,SAClB,CAAC,CAAC,CAEF,KAAM,CAAEsC,aAAa,CAAbA,CAAa,CAAED,UAAU,CAAVA,CAAU,CAAEE,YAAY,CAAZA,CAAa,CAAC,CAC/C2E,CAAyB,CAAC1F,IAAI,CAEhC,IAAI,CAACgB,iBAAiB,CAAG,CAAEF,aAAa,CAAbA,CAAa,CAAED,UAAU,CAAVA,CAAW,CAAC,CAEtD,IAAK,KAAM,CAAAI,CAAW,GAAI,CAAAF,CAAY,CACpC,IAAI,CAACG,gBAAgB,CAACC,GAAG,CAACF,CAAW,CAACG,UAAU,CAAEH,CAAW,CAAC,CAC/D,OAEGJ,CAAU,WAAVA,CAAU,EAAVA,CAAU,CAAEoD,MAAM,GACpB,IAAI,CAACxF,WAAW,CAAC8G,iBAAiB,CAAG1E,CAAU,EAGjD,IAAI,CAACpC,WAAW,CAACqH,UAAU,CAAC,CAAC,SAAAL,CAAA,CAC7B,IAAI,CAAChD,WAAW,YAAAgD,CAAA,QAAhBA,CAAA,CAAkBM,KAAK,CAAC,CAAC,CACzB,IAAI,CAACxC,sBAAsB,CAAG,IAAI,CAClC,IAAI,CAACvB,YAAY,CAAG,IAAI,CAExB,KAAM,CAAA8C,CAAM,CAAG,IAAI,CAACkB,iBAAiB,CAAC,CAAC,CAEvC,GAAI,CAAClB,CAAM,CAAChF,EAAE,CACZ,MAAO,CAAAgF,CAAM,CACd,KAEK,CAAA3E,CAAU,CAAGW,CAAa,CAAC0D,cAAc,CAC3CxF,iBAAU,CAACoB,QAAQ,CACnBpB,iBAAU,CAACsB,OAAO,CAEhB2F,CAAgB,CAAG9F,CAAU,GAAK,IAAI,CAACA,UAAU,CAEnD8F,CAAgB,GAClB,IAAI,CAAC9F,UAAU,CAAGA,CAAU,CAC5B,KAAM,KAAI,CAACZ,UAAU,CAAC,CAAC,EAMzB,KAAM,CAAA2G,CAAe,CACnB,IAAI,CAAChD,iBAAiB,EAAI,CAAC,IAAI,CAACI,0BAA0B,CAG5D,MAFA,KAAI,CAAChE,kBAAkB,CAAC4G,eAAe,CAAGA,CAAe,CAElD,GAAAjG,SAAE,EAACgG,CAAgB,CAC5B,CAEQD,iBAAiBA,CAAA,CAAiC,CACxD,IAAI,CAAC5G,UAAU,CAAG,GAAI,CAAAC,IAAM,MAEtB,CAAA2B,CAAiB,CAAAoE,aAAA,CAAAA,aAAA,IAClB,IAAI,CAACpE,iBAAiB,MACzBD,YAAY,CAAEoF,KAAK,CAACC,IAAI,CAAC,IAAI,CAACrF,YAAY,CAAC2B,MAAM,CAAC,CAAC,CAAC,EACrD,CAEK1C,CAAoB,CAAG,CAC3BA,IAAI,CAAEgB,CAAiB,CACvB5B,UAAU,CAAE,IAAI,CAACA,UAAU,CAACkG,QAAQ,CAAC,CACvC,CAAC,CAMD,MAJA,CAAAL,wBAAW,CAACC,gBAAgB,CAC1B,IAAI,CAAClE,iBAAiB,CAACF,aAAa,CAACqE,aACvC,CAAC,CAEM,IAAI,CAAC5G,OAAO,CAAC8G,KAAK,CAACrF,CAAI,CAChC,CACF,CAACqG,OAAA,CAAAlI,mBAAA,CAAAA,mBAAA"}
|
|
1
|
+
{"version":3,"file":"clientConfiguration.js","names":["ClientConfiguration","constructor","a","updateInterval","storage","requester","dataManager","externalClientConfiguration","offlineTrackingStorage","eventSource","externalVisitorCodeManager","eventManager","_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","customData","configuration","featureFlags","configurationData","featureFlag","featureFlagsData","set","featureKey","updateEventCallback","timestamp","then","fireEvent","EventType","ConfigurationUpdate","open","setInterval","bind","err","segments","segmentsData","forEach","flag","rules","rule","segment","has","id","ruleMap","mappedRules","size","values","experimentId","variationByExposition","variationMap","variationKey","variationId","featureId","variations","isConsentRequired","consentType","ConsentType","Required","hasAnyTargetedDeliveryRule","isTargetedDeliveryRule","environmentEnabled","some","type","RuleType","TARGETED_DELIVERY","checkIntegrity","fields","Object","keys","length","requiredFields","DEFAULT_CLIENT_CONFIGURATION","sort","join","skipChecks","arguments","realTimeUpdate","lastUpdateTime","getTime","updateWindowEdge","now","result","read","isStorageValid","UrlProvider","setDataApiDomain","dataApiDomain","_objectSpread","write","toString","customDataIndexes","parse","b","clientConfigurationResult","getClientConfiguration","Utilities","sendOfflineTracking","clearTrees","clear","updateStorageData","toggleUpdateType","consentRequired","Array","from","exports"],"sources":["../../src/clientConfiguration/clientConfiguration.ts"],"sourcesContent":["import { Ok, Result } from 'ts-res';\nimport { KameleoonError } from 'src/kameleoonError/kameleoonError';\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 {\n DEFAULT_CLIENT_CONFIGURATION,\n DEFAULT_CONFIGURATION_DATA,\n} from './constants';\nimport {\n ClientConfigurationDataType,\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';\nimport { EventManager, EventType } from 'src/eventManager';\nimport { UrlProvider } from 'src/requester/urlProvider';\n\ninterface IClientConfiguration {\n initialize: (useCache?: boolean) => Promise<Result<void, KameleoonError>>;\n readonly featureFlags: Map<string, 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 updateConfigurationIntervalId: NodeJS.Timeout | null = null;\n private updateType: UpdateType = UpdateType.Idle;\n private configurationData: ClientConfigurationDataType =\n DEFAULT_CONFIGURATION_DATA;\n private featureFlagsData: Map<string, FeatureFlagType> = new Map();\n private isTargetedDeliveryRule: boolean | null = null;\n private segmentsData: Map<string, SegmentType> | null = null;\n private updateInterval: number;\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> | null = null;\n private dataManager: DataManager;\n private visitorCodeManager: IVisitorCodeManager;\n private eventManager: EventManager;\n\n constructor({\n updateInterval,\n storage,\n requester,\n dataManager,\n externalClientConfiguration,\n offlineTrackingStorage,\n eventSource,\n externalVisitorCodeManager,\n eventManager,\n }: ClientConfigurationParametersType) {\n this.requester = requester;\n this.updateInterval = updateInterval;\n this.lastUpdate = new Date();\n this.storage = storage;\n this.dataManager = dataManager;\n this.eventManager = eventManager;\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 const { customData, configuration, featureFlags } =\n this.externalClientConfiguration!;\n this.configurationData = { customData, configuration };\n\n for (const featureFlag of featureFlags) {\n this.featureFlagsData.set(featureFlag.featureKey, featureFlag);\n }\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) {\n this.eventManager.fireEvent(EventType.ConfigurationUpdate, {\n timestamp,\n });\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.updateInterval,\n );\n } catch (err) {\n if (this.updateConfigurationIntervalId) {\n clearInterval(this.updateConfigurationIntervalId);\n }\n\n throw err;\n }\n }\n\n get featureFlags(): Map<string, FeatureFlagType> {\n return this.featureFlagsData;\n }\n\n get configuration(): ConfigurationType {\n return this.configurationData.configuration;\n }\n\n get segments(): Map<string, SegmentType> {\n if (this.segmentsData) {\n return this.segmentsData;\n }\n\n const segmentsData = new Map<string, SegmentType>();\n\n this.featureFlagsData.forEach((flag) => {\n flag.rules.forEach((rule) => {\n if (rule.segment && !segmentsData.has(rule.segment.id)) {\n segmentsData.set(rule.segment.id, rule.segment);\n }\n });\n });\n\n this.segmentsData = segmentsData;\n\n return segmentsData;\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.values()) {\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 if (this.isTargetedDeliveryRule !== null) {\n return this.isTargetedDeliveryRule;\n }\n\n for (const featureFlag of this.featureFlags.values()) {\n if (\n featureFlag.environmentEnabled &&\n featureFlag.rules.some(\n (rule) => rule.type === RuleType.TARGETED_DELIVERY,\n )\n ) {\n return true;\n }\n }\n\n return false;\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_CLIENT_CONFIGURATION);\n\n return fields.sort().join() === requiredFields.sort().join();\n }\n\n private checkShouldUpdate(skipChecks = false): boolean {\n const { configuration } = this.configurationData;\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 (!this.featureFlags.size) {\n return true;\n }\n\n const lastUpdateTime = this.lastUpdate.getTime();\n const updateWindowEdge = Date.now() - this.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 UrlProvider.setDataApiDomain(\n DEFAULT_CONFIGURATION_DATA.configuration.dataApiDomain,\n );\n\n const data = {\n ...DEFAULT_CONFIGURATION_DATA,\n featureFlags: [],\n };\n\n this.storage.write({\n data,\n lastUpdate: this.lastUpdate.toString(),\n });\n\n this.configurationData = DEFAULT_CONFIGURATION_DATA;\n } else {\n UrlProvider.setDataApiDomain(data.configuration.dataApiDomain);\n\n const { featureFlags, customData } = data;\n\n if (customData?.length) {\n this.dataManager.customDataIndexes = customData;\n }\n\n for (const featureFlag of featureFlags) {\n this.featureFlagsData.set(featureFlag.featureKey, featureFlag);\n }\n\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 if (this.featureFlags.size) {\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, featureFlags } =\n clientConfigurationResult.data;\n\n this.configurationData = { configuration, customData };\n\n for (const featureFlag of featureFlags) {\n this.featureFlagsData.set(featureFlag.featureKey, featureFlag);\n }\n\n if (customData?.length) {\n this.dataManager.customDataIndexes = customData;\n }\n\n this.dataManager.clearTrees();\n this.mappedRules?.clear();\n this.isTargetedDeliveryRule = null;\n this.segmentsData = null;\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 configurationData = {\n ...this.configurationData,\n featureFlags: Array.from(this.featureFlags.values()),\n };\n\n const data: ClientDataType = {\n data: configurationData,\n lastUpdate: this.lastUpdate.toString(),\n };\n\n UrlProvider.setDataApiDomain(\n this.configurationData.configuration.dataApiDomain,\n );\n\n return this.storage.write(data);\n }\n}\n"],"mappings":"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"}
|