@splitsoftware/splitio-commons 1.6.2-rc.11 → 1.6.2-rc.13

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.
Files changed (58) hide show
  1. package/cjs/listeners/browser.js +9 -11
  2. package/cjs/sdkFactory/index.js +7 -24
  3. package/cjs/storages/inLocalStorage/index.js +14 -10
  4. package/cjs/storages/inMemory/InMemoryStorage.js +10 -7
  5. package/cjs/storages/inMemory/InMemoryStorageCS.js +10 -7
  6. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +57 -34
  7. package/cjs/storages/inRedis/index.js +4 -2
  8. package/cjs/storages/pluggable/index.js +15 -11
  9. package/cjs/sync/submitters/submitterManager.js +1 -1
  10. package/cjs/sync/submitters/telemetrySubmitter.js +4 -40
  11. package/cjs/trackers/impressionObserver/utils.js +1 -17
  12. package/cjs/trackers/uniqueKeysTracker.js +1 -1
  13. package/cjs/utils/settingsValidation/index.js +7 -1
  14. package/esm/listeners/browser.js +9 -11
  15. package/esm/sdkFactory/index.js +7 -24
  16. package/esm/storages/inLocalStorage/index.js +15 -11
  17. package/esm/storages/inMemory/InMemoryStorage.js +10 -7
  18. package/esm/storages/inMemory/InMemoryStorageCS.js +10 -7
  19. package/esm/storages/inMemory/TelemetryCacheInMemory.js +58 -35
  20. package/esm/storages/inRedis/index.js +4 -2
  21. package/esm/storages/pluggable/index.js +15 -11
  22. package/esm/sync/submitters/submitterManager.js +1 -1
  23. package/esm/sync/submitters/telemetrySubmitter.js +4 -39
  24. package/esm/trackers/impressionObserver/utils.js +1 -15
  25. package/esm/trackers/uniqueKeysTracker.js +1 -1
  26. package/esm/utils/settingsValidation/index.js +7 -1
  27. package/package.json +2 -1
  28. package/src/listeners/browser.ts +9 -13
  29. package/src/sdkClient/sdkClient.ts +1 -1
  30. package/src/sdkFactory/index.ts +7 -29
  31. package/src/sdkFactory/types.ts +2 -2
  32. package/src/storages/inLocalStorage/index.ts +16 -11
  33. package/src/storages/inMemory/InMemoryStorage.ts +11 -7
  34. package/src/storages/inMemory/InMemoryStorageCS.ts +11 -7
  35. package/src/storages/inMemory/TelemetryCacheInMemory.ts +66 -33
  36. package/src/storages/inRedis/TelemetryCacheInRedis.ts +1 -1
  37. package/src/storages/inRedis/index.ts +4 -1
  38. package/src/storages/pluggable/TelemetryCachePluggable.ts +1 -1
  39. package/src/storages/pluggable/index.ts +12 -8
  40. package/src/storages/types.ts +41 -60
  41. package/src/sync/submitters/submitter.ts +2 -2
  42. package/src/sync/submitters/submitterManager.ts +1 -1
  43. package/src/sync/submitters/telemetrySubmitter.ts +5 -41
  44. package/src/sync/submitters/types.ts +5 -5
  45. package/src/trackers/impressionObserver/utils.ts +1 -16
  46. package/src/trackers/strategy/strategyNone.ts +9 -9
  47. package/src/trackers/strategy/strategyOptimized.ts +9 -9
  48. package/src/trackers/uniqueKeysTracker.ts +6 -6
  49. package/src/utils/settingsValidation/index.ts +5 -1
  50. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +19 -8
  51. package/types/storages/types.d.ts +31 -41
  52. package/types/sync/submitters/submitter.d.ts +2 -2
  53. package/types/sync/submitters/telemetrySubmitter.d.ts +2 -10
  54. package/types/sync/submitters/types.d.ts +6 -6
  55. package/types/trackers/impressionObserver/utils.d.ts +0 -8
  56. package/types/trackers/strategy/strategyNone.d.ts +2 -2
  57. package/types/trackers/strategy/strategyOptimized.d.ts +2 -2
  58. package/types/trackers/uniqueKeysTracker.d.ts +1 -1
@@ -7,7 +7,6 @@ var constants_1 = require("../utils/constants");
7
7
  var objectAssign_1 = require("../utils/lang/objectAssign");
8
8
  var constants_2 = require("../logger/constants");
9
9
  var consent_1 = require("../consent");
10
- var telemetrySubmitter_1 = require("../sync/submitters/telemetrySubmitter");
11
10
  var VISIBILITYCHANGE_EVENT = 'visibilitychange';
12
11
  var PAGEHIDE_EVENT = 'pagehide';
13
12
  var UNLOAD_EVENT = 'unload';
@@ -71,25 +70,25 @@ var BrowserSignalListener = /** @class */ (function () {
71
70
  BrowserSignalListener.prototype.flushData = function () {
72
71
  if (!this.syncManager)
73
72
  return; // In consumer mode there is not sync manager and data to flush
73
+ var _a = this.settings.urls, events = _a.events, telemetry = _a.telemetry;
74
74
  // Flush impressions & events data if there is user consent
75
75
  if ((0, consent_1.isConsentGranted)(this.settings)) {
76
- var eventsUrl = this.settings.urls.events;
77
76
  var sim = this.settings.sync.impressionsMode;
78
77
  var extraMetadata = {
79
78
  // sim stands for Sync/Split Impressions Mode
80
79
  sim: sim === constants_1.OPTIMIZED ? constants_1.OPTIMIZED : sim === constants_1.DEBUG ? constants_1.DEBUG : constants_1.NONE
81
80
  };
82
- this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
83
- this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
81
+ this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
82
+ this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
84
83
  if (this.storage.impressionCounts)
85
- this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, impressionCountsSubmitter_1.fromImpressionCountsCollector);
84
+ this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, impressionCountsSubmitter_1.fromImpressionCountsCollector);
85
+ // @ts-ignore
86
+ if (this.storage.uniqueKeys)
87
+ this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs);
86
88
  }
87
89
  // Flush telemetry data
88
- if (this.storage.telemetry) {
89
- var telemetryUrl = this.settings.urls.telemetry;
90
- var telemetryCacheAdapter = (0, telemetrySubmitter_1.telemetryCacheStatsAdapter)(this.storage.telemetry, this.storage.splits, this.storage.segments);
91
- this._flushData(telemetryUrl + '/v1/metrics/usage/beacon', telemetryCacheAdapter, this.serviceApi.postMetricsUsage);
92
- }
90
+ if (this.storage.telemetry)
91
+ this._flushData(telemetry + '/v1/metrics/usage/beacon', this.storage.telemetry, this.serviceApi.postMetricsUsage);
93
92
  };
94
93
  BrowserSignalListener.prototype.flushDataIfHidden = function () {
95
94
  // Precondition: document defined
@@ -103,7 +102,6 @@ var BrowserSignalListener = /** @class */ (function () {
103
102
  if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
104
103
  postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
105
104
  }
106
- cache.clear();
107
105
  }
108
106
  };
109
107
  /**
@@ -5,12 +5,9 @@ var sdkReadinessManager_1 = require("../readiness/sdkReadinessManager");
5
5
  var impressionsTracker_1 = require("../trackers/impressionsTracker");
6
6
  var eventTracker_1 = require("../trackers/eventTracker");
7
7
  var telemetryTracker_1 = require("../trackers/telemetryTracker");
8
- var key_1 = require("../utils/key");
9
- var utils_1 = require("../trackers/impressionObserver/utils");
10
8
  var apiKey_1 = require("../utils/inputValidation/apiKey");
11
9
  var sdkLogger_1 = require("../logger/sdkLogger");
12
10
  var constants_1 = require("../logger/constants");
13
- var metadataBuilder_1 = require("../storages/metadataBuilder");
14
11
  var constants_2 = require("../readiness/constants");
15
12
  var objectAssign_1 = require("../utils/lang/objectAssign");
16
13
  var strategyDebug_1 = require("../trackers/strategy/strategyDebug");
@@ -23,43 +20,29 @@ var constants_3 = require("../utils/constants");
23
20
  */
24
21
  function sdkFactory(params) {
25
22
  var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, filterAdapterFactory = params.filterAdapterFactory;
26
- var log = settings.log;
23
+ var log = settings.log, impressionsMode = settings.sync.impressionsMode;
27
24
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid API Key, etc.
28
25
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
29
26
  // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
30
27
  (0, apiKey_1.validateAndTrackApiKey)(log, settings.core.authorizationKey);
31
28
  var sdkReadinessManager = (0, sdkReadinessManager_1.sdkReadinessManagerFactory)(log, platform.EventEmitter, settings.startup.readyTimeout);
32
29
  var readiness = sdkReadinessManager.readinessManager;
33
- // @TODO consider passing the settings object, so that each storage access only what it needs
34
- var storageFactoryParams = {
35
- impressionsQueueSize: settings.scheduler.impressionsQueueSize,
36
- eventsQueueSize: settings.scheduler.eventsQueueSize,
37
- optimize: (0, utils_1.shouldBeOptimized)(settings),
38
- // ATM, only used by InLocalStorage
39
- matchingKey: (0, key_1.getMatching)(settings.core.key),
40
- splitFiltersValidation: settings.sync.__splitFiltersValidation,
41
- // ATM, only used by PluggableStorage
42
- mode: settings.mode,
43
- impressionsMode: settings.sync.impressionsMode,
44
- // Callback used to emit SDK_READY in consumer mode, where `syncManagerFactory` is undefined,
45
- // or partial consumer mode, where it only has submitters, and therefore it doesn't emit readiness events.
30
+ var storage = storageFactory({
31
+ settings: settings,
46
32
  onReadyCb: function (error) {
47
33
  if (error)
48
34
  return; // Don't emit SDK_READY if storage failed to connect. Error message is logged by wrapperAdapter
49
35
  readiness.splits.emit(constants_2.SDK_SPLITS_ARRIVED);
50
36
  readiness.segments.emit(constants_2.SDK_SEGMENTS_ARRIVED);
51
37
  },
52
- metadata: (0, metadataBuilder_1.metadataBuilder)(settings),
53
- log: log
54
- };
55
- var storage = storageFactory(storageFactoryParams);
38
+ });
56
39
  // @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
57
40
  var telemetryTracker = (0, telemetryTracker_1.telemetryTrackerFactory)(storage.telemetry, platform.now);
58
41
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
59
42
  var observer = impressionsObserverFactory();
60
- var uniqueKeysTracker = storageFactoryParams.impressionsMode === constants_3.NONE ? (0, uniqueKeysTracker_1.uniqueKeysTrackerFactory)(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
43
+ var uniqueKeysTracker = impressionsMode === constants_3.NONE ? (0, uniqueKeysTracker_1.uniqueKeysTrackerFactory)(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
61
44
  var strategy;
62
- switch (storageFactoryParams.impressionsMode) {
45
+ switch (impressionsMode) {
63
46
  case constants_3.OPTIMIZED:
64
47
  strategy = (0, strategyOptimized_1.strategyOptimizedFactory)(observer, storage.impressionCounts);
65
48
  break;
@@ -94,7 +77,7 @@ function sdkFactory(params) {
94
77
  return managerInstance;
95
78
  },
96
79
  // Logger wrapper API
97
- Logger: (0, sdkLogger_1.createLoggerAPI)(settings.log),
80
+ Logger: (0, sdkLogger_1.createLoggerAPI)(log),
98
81
  settings: settings,
99
82
  }, extraProps && extraProps(ctx));
100
83
  }
@@ -17,6 +17,7 @@ var constants_1 = require("./constants");
17
17
  var constants_2 = require("../../utils/constants");
18
18
  var TelemetryCacheInMemory_1 = require("../inMemory/TelemetryCacheInMemory");
19
19
  var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS");
20
+ var key_1 = require("../../utils/key");
20
21
  /**
21
22
  * InLocal storage factory for standalone client-side SplitFactory
22
23
  */
@@ -26,20 +27,23 @@ function InLocalStorage(options) {
26
27
  function InLocalStorageCSFactory(params) {
27
28
  // Fallback to InMemoryStorage if LocalStorage API is not available
28
29
  if (!(0, isLocalStorageAvailable_1.isLocalStorageAvailable)()) {
29
- params.log.warn(constants_1.LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
30
+ params.settings.log.warn(constants_1.LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
30
31
  return (0, InMemoryStorageCS_1.InMemoryStorageCSFactory)(params);
31
32
  }
32
- var log = params.log;
33
- var keys = new KeyBuilderCS_1.KeyBuilderCS(prefix, params.matchingKey);
33
+ var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__splitFiltersValidation;
34
+ var matchingKey = (0, key_1.getMatching)(settings.core.key);
35
+ var keys = new KeyBuilderCS_1.KeyBuilderCS(prefix, matchingKey);
34
36
  var expirationTimestamp = Date.now() - browser_1.DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
37
+ var splits = new SplitsCacheInLocal_1.SplitsCacheInLocal(log, keys, expirationTimestamp, __splitFiltersValidation);
38
+ var segments = new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys);
35
39
  return {
36
- splits: new SplitsCacheInLocal_1.SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
37
- segments: new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys),
38
- impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
39
- impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
40
- events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
41
- telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory() : undefined,
42
- uniqueKeys: params.impressionsMode === constants_2.NONE ? new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() : undefined,
40
+ splits: splits,
41
+ segments: segments,
42
+ impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
43
+ impressionCounts: impressionsMode !== constants_2.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
44
+ events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
45
+ telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
46
+ uniqueKeys: impressionsMode === constants_2.NONE ? new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() : undefined,
43
47
  destroy: function () {
44
48
  var _a;
45
49
  this.splits = new SplitsCacheInMemory_1.SplitsCacheInMemory();
@@ -15,14 +15,17 @@ var UniqueKeysCacheInMemory_1 = require("./UniqueKeysCacheInMemory");
15
15
  * @param params parameters required by EventsCacheSync
16
16
  */
17
17
  function InMemoryStorageFactory(params) {
18
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
19
+ var splits = new SplitsCacheInMemory_1.SplitsCacheInMemory();
20
+ var segments = new SegmentsCacheInMemory_1.SegmentsCacheInMemory();
18
21
  return {
19
- splits: new SplitsCacheInMemory_1.SplitsCacheInMemory(),
20
- segments: new SegmentsCacheInMemory_1.SegmentsCacheInMemory(),
21
- impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
22
- impressionCounts: params.impressionsMode !== constants_1.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
23
- events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
24
- telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory() : undefined,
25
- uniqueKeys: params.impressionsMode === constants_1.NONE ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : undefined,
22
+ splits: splits,
23
+ segments: segments,
24
+ impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
25
+ impressionCounts: impressionsMode !== constants_1.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
26
+ events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
27
+ telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
28
+ uniqueKeys: impressionsMode === constants_1.NONE ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : undefined,
26
29
  // When using MEMORY we should clean all the caches to leave them empty
27
30
  destroy: function () {
28
31
  var _a;
@@ -15,14 +15,17 @@ var UniqueKeysCacheInMemoryCS_1 = require("./UniqueKeysCacheInMemoryCS");
15
15
  * @param params parameters required by EventsCacheSync
16
16
  */
17
17
  function InMemoryStorageCSFactory(params) {
18
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
19
+ var splits = new SplitsCacheInMemory_1.SplitsCacheInMemory();
20
+ var segments = new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory();
18
21
  return {
19
- splits: new SplitsCacheInMemory_1.SplitsCacheInMemory(),
20
- segments: new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory(),
21
- impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
22
- impressionCounts: params.impressionsMode !== constants_1.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
23
- events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
24
- telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory() : undefined,
25
- uniqueKeys: params.impressionsMode === constants_1.NONE ? new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() : undefined,
22
+ splits: splits,
23
+ segments: segments,
24
+ impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
25
+ impressionCounts: impressionsMode !== constants_1.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
26
+ events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
27
+ telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
28
+ uniqueKeys: impressionsMode === constants_1.NONE ? new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() : undefined,
26
29
  // When using MEMORY we should clean all the caches to leave them empty
27
30
  destroy: function () {
28
31
  var _a;
@@ -17,30 +17,56 @@ var ACCEPTANCE_RANGE = 0.001;
17
17
  * Record telemetry if mode is not localhost.
18
18
  * All factory instances track telemetry on server-side, and 0.1% on client-side.
19
19
  */
20
- function shouldRecordTelemetry(params) {
21
- return params.mode !== constants_1.LOCALHOST_MODE && (params.matchingKey === undefined || Math.random() <= ACCEPTANCE_RANGE);
20
+ function shouldRecordTelemetry(_a) {
21
+ var settings = _a.settings;
22
+ return settings.mode !== constants_1.LOCALHOST_MODE && (settings.core.key === undefined || Math.random() <= ACCEPTANCE_RANGE);
22
23
  }
23
24
  exports.shouldRecordTelemetry = shouldRecordTelemetry;
24
25
  var TelemetryCacheInMemory = /** @class */ (function () {
25
- function TelemetryCacheInMemory() {
26
+ function TelemetryCacheInMemory(splits, segments) {
27
+ this.splits = splits;
28
+ this.segments = segments;
29
+ // isEmpty flag
30
+ this.e = true;
26
31
  this.notReadyUsage = 0;
32
+ /** Usage stats */
27
33
  this.impressionStats = [0, 0, 0];
28
34
  this.eventStats = [0, 0];
29
- // @ts-expect-error
30
35
  this.lastSync = {};
31
- // @ts-expect-error
32
36
  this.httpErrors = {};
33
- // @ts-expect-error
34
37
  this.httpLatencies = {};
35
38
  this.authRejections = 0;
36
39
  this.tokenRefreshes = 0;
37
40
  this.streamingEvents = [];
38
41
  this.tags = [];
39
- // @ts-expect-error
40
42
  this.exceptions = {};
41
- // @ts-expect-error
42
43
  this.latencies = {};
43
44
  }
45
+ TelemetryCacheInMemory.prototype.isEmpty = function () { return this.e; };
46
+ TelemetryCacheInMemory.prototype.clear = function () { };
47
+ TelemetryCacheInMemory.prototype.pop = function () {
48
+ this.e = true;
49
+ return {
50
+ lS: this.getLastSynchronization(),
51
+ mL: this.popLatencies(),
52
+ mE: this.popExceptions(),
53
+ hE: this.popHttpErrors(),
54
+ hL: this.popHttpLatencies(),
55
+ tR: this.popTokenRefreshes(),
56
+ aR: this.popAuthRejections(),
57
+ iQ: this.getImpressionStats(constants_1.QUEUED),
58
+ iDe: this.getImpressionStats(constants_1.DEDUPED),
59
+ iDr: this.getImpressionStats(constants_1.DROPPED),
60
+ spC: this.splits && this.splits.getSplitNames().length,
61
+ seC: this.segments && this.segments.getRegisteredSegments().length,
62
+ skC: this.segments && this.segments.getKeysCount(),
63
+ sL: this.getSessionLength(),
64
+ eQ: this.getEventStats(constants_1.QUEUED),
65
+ eD: this.getEventStats(constants_1.DROPPED),
66
+ sE: this.popStreamingEvents(),
67
+ t: this.popTags(),
68
+ };
69
+ };
44
70
  TelemetryCacheInMemory.prototype.getTimeUntilReady = function () {
45
71
  return this.timeUntilReady;
46
72
  };
@@ -64,44 +90,41 @@ var TelemetryCacheInMemory = /** @class */ (function () {
64
90
  };
65
91
  TelemetryCacheInMemory.prototype.recordImpressionStats = function (type, count) {
66
92
  this.impressionStats[type] += count;
93
+ this.e = false;
67
94
  };
68
95
  TelemetryCacheInMemory.prototype.getEventStats = function (type) {
69
96
  return this.eventStats[type];
70
97
  };
71
98
  TelemetryCacheInMemory.prototype.recordEventStats = function (type, count) {
72
99
  this.eventStats[type] += count;
100
+ this.e = false;
73
101
  };
74
102
  TelemetryCacheInMemory.prototype.getLastSynchronization = function () {
75
103
  return this.lastSync;
76
104
  };
77
105
  TelemetryCacheInMemory.prototype.recordSuccessfulSync = function (resource, timeMs) {
78
106
  this.lastSync[resource] = timeMs;
107
+ this.e = false;
79
108
  };
80
109
  TelemetryCacheInMemory.prototype.popHttpErrors = function () {
81
- var result = this.httpErrors; // @ts-expect-error
110
+ var result = this.httpErrors;
82
111
  this.httpErrors = {};
83
112
  return result;
84
113
  };
85
114
  TelemetryCacheInMemory.prototype.recordHttpError = function (resource, status) {
86
- if (!this.httpErrors[resource])
87
- this.httpErrors[resource] = {};
88
- if (!this.httpErrors[resource][status]) {
89
- this.httpErrors[resource][status] = 1;
90
- }
91
- else {
92
- this.httpErrors[resource][status]++;
93
- }
115
+ var statusErrors = (this.httpErrors[resource] = this.httpErrors[resource] || {});
116
+ statusErrors[status] = (statusErrors[status] || 0) + 1;
117
+ this.e = false;
94
118
  };
95
119
  TelemetryCacheInMemory.prototype.popHttpLatencies = function () {
96
- var result = this.httpLatencies; // @ts-expect-error
120
+ var result = this.httpLatencies;
97
121
  this.httpLatencies = {};
98
122
  return result;
99
123
  };
100
124
  TelemetryCacheInMemory.prototype.recordHttpLatency = function (resource, latencyMs) {
101
- if (!this.httpLatencies[resource]) {
102
- this.httpLatencies[resource] = newBuckets();
103
- }
104
- this.httpLatencies[resource][(0, findLatencyIndex_1.findLatencyIndex)(latencyMs)]++;
125
+ var latencyBuckets = (this.httpLatencies[resource] = this.httpLatencies[resource] || newBuckets());
126
+ latencyBuckets[(0, findLatencyIndex_1.findLatencyIndex)(latencyMs)]++;
127
+ this.e = false;
105
128
  };
106
129
  TelemetryCacheInMemory.prototype.popAuthRejections = function () {
107
130
  var result = this.authRejections;
@@ -110,6 +133,7 @@ var TelemetryCacheInMemory = /** @class */ (function () {
110
133
  };
111
134
  TelemetryCacheInMemory.prototype.recordAuthRejections = function () {
112
135
  this.authRejections++;
136
+ this.e = false;
113
137
  };
114
138
  TelemetryCacheInMemory.prototype.popTokenRefreshes = function () {
115
139
  var result = this.tokenRefreshes;
@@ -118,6 +142,7 @@ var TelemetryCacheInMemory = /** @class */ (function () {
118
142
  };
119
143
  TelemetryCacheInMemory.prototype.recordTokenRefreshes = function () {
120
144
  this.tokenRefreshes++;
145
+ this.e = false;
121
146
  };
122
147
  TelemetryCacheInMemory.prototype.popStreamingEvents = function () {
123
148
  return this.streamingEvents.splice(0);
@@ -126,6 +151,7 @@ var TelemetryCacheInMemory = /** @class */ (function () {
126
151
  if (this.streamingEvents.length < MAX_STREAMING_EVENTS) {
127
152
  this.streamingEvents.push(streamingEvent);
128
153
  }
154
+ this.e = false;
129
155
  };
130
156
  TelemetryCacheInMemory.prototype.popTags = function () {
131
157
  return this.tags.splice(0);
@@ -134,36 +160,33 @@ var TelemetryCacheInMemory = /** @class */ (function () {
134
160
  if (this.tags.length < MAX_TAGS) {
135
161
  this.tags.push(tag);
136
162
  }
163
+ this.e = false;
137
164
  };
138
165
  TelemetryCacheInMemory.prototype.getSessionLength = function () {
139
166
  return this.sessionLength;
140
167
  };
141
168
  TelemetryCacheInMemory.prototype.recordSessionLength = function (ms) {
142
169
  this.sessionLength = ms;
170
+ this.e = false;
143
171
  };
144
172
  TelemetryCacheInMemory.prototype.popExceptions = function () {
145
- var result = this.exceptions; // @ts-expect-error
173
+ var result = this.exceptions;
146
174
  this.exceptions = {};
147
175
  return result;
148
176
  };
149
177
  TelemetryCacheInMemory.prototype.recordException = function (method) {
150
- if (!this.exceptions[method]) {
151
- this.exceptions[method] = 1;
152
- }
153
- else {
154
- this.exceptions[method]++;
155
- }
178
+ this.exceptions[method] = (this.exceptions[method] || 0) + 1;
179
+ this.e = false;
156
180
  };
157
181
  TelemetryCacheInMemory.prototype.popLatencies = function () {
158
- var result = this.latencies; // @ts-expect-error
182
+ var result = this.latencies;
159
183
  this.latencies = {};
160
184
  return result;
161
185
  };
162
186
  TelemetryCacheInMemory.prototype.recordLatency = function (method, latencyMs) {
163
- if (!this.latencies[method]) {
164
- this.latencies[method] = newBuckets();
165
- }
166
- this.latencies[method][(0, findLatencyIndex_1.findLatencyIndex)(latencyMs)]++;
187
+ var latencyBuckets = (this.latencies[method] = this.latencies[method] || newBuckets());
188
+ latencyBuckets[(0, findLatencyIndex_1.findLatencyIndex)(latencyMs)]++;
189
+ this.e = false;
167
190
  };
168
191
  return TelemetryCacheInMemory;
169
192
  }());
@@ -12,6 +12,7 @@ var constants_1 = require("../../utils/constants");
12
12
  var TelemetryCacheInRedis_1 = require("./TelemetryCacheInRedis");
13
13
  var UniqueKeysCacheInRedis_1 = require("./UniqueKeysCacheInRedis");
14
14
  var ImpressionCountsCacheInRedis_1 = require("./ImpressionCountsCacheInRedis");
15
+ var metadataBuilder_1 = require("../metadataBuilder");
15
16
  /**
16
17
  * InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.
17
18
  * @see {@link https://www.npmjs.com/package/ioredis}
@@ -19,8 +20,9 @@ var ImpressionCountsCacheInRedis_1 = require("./ImpressionCountsCacheInRedis");
19
20
  function InRedisStorage(options) {
20
21
  if (options === void 0) { options = {}; }
21
22
  var prefix = (0, KeyBuilder_1.validatePrefix)(options.prefix);
22
- function InRedisStorageFactory(_a) {
23
- var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb, impressionsMode = _a.impressionsMode;
23
+ function InRedisStorageFactory(params) {
24
+ var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, impressionsMode = _a.sync.impressionsMode;
25
+ var metadata = (0, metadataBuilder_1.metadataBuilder)(settings);
24
26
  var keys = new KeyBuilderSS_1.KeyBuilderSS(prefix, metadata);
25
27
  var redisClient = new RedisAdapter_1.RedisAdapter(log, options.options || {});
26
28
  var telemetry = new TelemetryCacheInRedis_1.TelemetryCacheInRedis(log, keys, redisClient);
@@ -20,6 +20,7 @@ var ImpressionCountsCachePluggable_1 = require("./ImpressionCountsCachePluggable
20
20
  var UniqueKeysCachePluggable_1 = require("./UniqueKeysCachePluggable");
21
21
  var UniqueKeysCacheInMemory_1 = require("../inMemory/UniqueKeysCacheInMemory");
22
22
  var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS");
23
+ var metadataBuilder_1 = require("../metadataBuilder");
23
24
  var NO_VALID_WRAPPER = 'Expecting pluggable storage `wrapper` in options, but no valid wrapper instance was provided.';
24
25
  var NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
25
26
  /**
@@ -52,7 +53,8 @@ function PluggableStorage(options) {
52
53
  validatePluggableStorageOptions(options);
53
54
  var prefix = (0, KeyBuilder_1.validatePrefix)(options.prefix);
54
55
  function PluggableStorageFactory(params) {
55
- var log = params.log, metadata = params.metadata, onReadyCb = params.onReadyCb, mode = params.mode, eventsQueueSize = params.eventsQueueSize, impressionsQueueSize = params.impressionsQueueSize, impressionsMode = params.impressionsMode, matchingKey = params.matchingKey;
56
+ var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, mode = _a.mode, impressionsMode = _a.sync.impressionsMode, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
57
+ var metadata = (0, metadataBuilder_1.metadataBuilder)(settings);
56
58
  var keys = new KeyBuilderSS_1.KeyBuilderSS(prefix, metadata);
57
59
  var wrapper = (0, wrapperAdapter_1.wrapperAdapter)(log, options.wrapper);
58
60
  var isSyncronizer = mode === undefined; // If mode is not defined, the synchronizer is running
@@ -69,19 +71,21 @@ function PluggableStorage(options) {
69
71
  undefined;
70
72
  var uniqueKeysCache = impressionsMode === constants_1.NONE || isSyncronizer ?
71
73
  isPartialConsumer ?
72
- matchingKey === undefined ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() :
74
+ settings.core.key === undefined ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() :
73
75
  new UniqueKeysCachePluggable_1.UniqueKeysCachePluggable(log, keys.buildUniqueKeysKey(), wrapper) :
74
76
  undefined;
75
77
  // Connects to wrapper and emits SDK_READY event on main client
76
78
  var connectPromise = wrapper.connect().then(function () {
77
79
  onReadyCb();
78
- // Start periodic flush of async storages
79
- if (impressionCountsCache && impressionCountsCache.start)
80
- impressionCountsCache.start();
81
- if (uniqueKeysCache && uniqueKeysCache.start)
82
- uniqueKeysCache.start();
83
- if (telemetry && telemetry.recordConfig && !isSyncronizer)
84
- telemetry.recordConfig();
80
+ // Start periodic flush of async storages if not running synchronizer (producer mode)
81
+ if (!isSyncronizer) {
82
+ if (impressionCountsCache && impressionCountsCache.start)
83
+ impressionCountsCache.start();
84
+ if (uniqueKeysCache && uniqueKeysCache.start)
85
+ uniqueKeysCache.start();
86
+ if (telemetry && telemetry.recordConfig)
87
+ telemetry.recordConfig();
88
+ }
85
89
  }).catch(function (e) {
86
90
  e = e || new Error('Error connecting wrapper');
87
91
  onReadyCb(e);
@@ -95,9 +99,9 @@ function PluggableStorage(options) {
95
99
  events: isPartialConsumer ? promisifyEventsTrack(new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize)) : new EventsCachePluggable_1.EventsCachePluggable(log, keys.buildEventsKey(), wrapper, metadata),
96
100
  telemetry: telemetry,
97
101
  uniqueKeys: uniqueKeysCache,
98
- // Disconnect the underlying storage
102
+ // Stop periodic flush and disconnect the underlying storage
99
103
  destroy: function () {
100
- return Promise.all([
104
+ return Promise.all(isSyncronizer ? [] : [
101
105
  impressionCountsCache && impressionCountsCache.stop && impressionCountsCache.stop(),
102
106
  uniqueKeysCache && uniqueKeysCache.stop && uniqueKeysCache.stop(),
103
107
  ]).then(function () { return wrapper.disconnect(); });
@@ -15,7 +15,7 @@ function submitterManagerFactory(params) {
15
15
  if (impressionCountsSubmitter)
16
16
  submitters.push(impressionCountsSubmitter);
17
17
  var telemetrySubmitter = (0, telemetrySubmitter_1.telemetrySubmitterFactory)(params);
18
- if (params.uniqueKeysTracker)
18
+ if (params.storage.uniqueKeys)
19
19
  submitters.push((0, uniqueKeysSubmitter_1.uniqueKeysSubmitterFactory)(params));
20
20
  return {
21
21
  // `onlyTelemetry` true if SDK is created with userConsent not GRANTED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a, _b, _c;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.telemetrySubmitterFactory = exports.telemetryCacheConfigAdapter = exports.getTelemetryConfigStats = exports.telemetryCacheStatsAdapter = void 0;
4
+ exports.telemetrySubmitterFactory = exports.telemetryCacheConfigAdapter = exports.getTelemetryConfigStats = void 0;
5
5
  var submitter_1 = require("./submitter");
6
6
  var constants_1 = require("../../utils/constants");
7
7
  var constants_2 = require("../../readiness/constants");
@@ -9,40 +9,6 @@ var settingsValidation_1 = require("../../utils/settingsValidation");
9
9
  var apiKey_1 = require("../../utils/inputValidation/apiKey");
10
10
  var timer_1 = require("../../utils/timeTracker/timer");
11
11
  var objectAssign_1 = require("../../utils/lang/objectAssign");
12
- var utils_1 = require("../../trackers/impressionObserver/utils");
13
- /**
14
- * Converts data from telemetry cache into /metrics/usage request payload.
15
- */
16
- function telemetryCacheStatsAdapter(telemetry, splits, segments) {
17
- return {
18
- isEmpty: function () { return false; },
19
- clear: function () { },
20
- // @TODO consider moving inside telemetry cache for code size reduction
21
- pop: function () {
22
- return {
23
- lS: telemetry.getLastSynchronization(),
24
- mL: telemetry.popLatencies(),
25
- mE: telemetry.popExceptions(),
26
- hE: telemetry.popHttpErrors(),
27
- hL: telemetry.popHttpLatencies(),
28
- tR: telemetry.popTokenRefreshes(),
29
- aR: telemetry.popAuthRejections(),
30
- iQ: telemetry.getImpressionStats(constants_1.QUEUED),
31
- iDe: telemetry.getImpressionStats(constants_1.DEDUPED),
32
- iDr: telemetry.getImpressionStats(constants_1.DROPPED),
33
- spC: splits && splits.getSplitNames().length,
34
- seC: segments && segments.getRegisteredSegments().length,
35
- skC: segments && segments.getKeysCount(),
36
- sL: telemetry.getSessionLength(),
37
- eQ: telemetry.getEventStats(constants_1.QUEUED),
38
- eD: telemetry.getEventStats(constants_1.DROPPED),
39
- sE: telemetry.popStreamingEvents(),
40
- t: telemetry.popTags(),
41
- };
42
- }
43
- };
44
- }
45
- exports.telemetryCacheStatsAdapter = telemetryCacheStatsAdapter;
46
12
  var OPERATION_MODE_MAP = (_a = {},
47
13
  _a[constants_1.STANDALONE_MODE] = constants_1.STANDALONE_ENUM,
48
14
  _a[constants_1.CONSUMER_MODE] = constants_1.CONSUMER_ENUM,
@@ -122,14 +88,12 @@ exports.telemetryCacheConfigAdapter = telemetryCacheConfigAdapter;
122
88
  * Submitter that periodically posts telemetry data
123
89
  */
124
90
  function telemetrySubmitterFactory(params) {
125
- var _a = params.storage, splits = _a.splits, segments = _a.segments, telemetry = _a.telemetry, now = params.platform.now;
91
+ var telemetry = params.storage.telemetry, now = params.platform.now;
126
92
  if (!telemetry || !now)
127
93
  return; // No submitter created if telemetry cache is not defined
128
- var settings = params.settings, _b = params.settings, log = _b.log, telemetryRefreshRate = _b.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness, sdkReadinessManager = params.sdkReadinessManager;
94
+ var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness, sdkReadinessManager = params.sdkReadinessManager;
129
95
  var startTime = (0, timer_1.timer)(now);
130
- var submitter = (0, submitter_1.firstPushWindowDecorator)((0, submitter_1.submitterFactory)(log, splitApi.postMetricsUsage,
131
- // @TODO cannot provide splits and segments cache if they are async, because `submitterFactory` expects a sync storage source
132
- (0, utils_1.isStorageSync)(params.settings) ? telemetryCacheStatsAdapter(telemetry, splits, segments) : telemetryCacheStatsAdapter(telemetry), telemetryRefreshRate, 'telemetry stats', undefined, 0, true), telemetryRefreshRate);
96
+ var submitter = (0, submitter_1.firstPushWindowDecorator)((0, submitter_1.submitterFactory)(log, splitApi.postMetricsUsage, telemetry, telemetryRefreshRate, 'telemetry stats', undefined, 0, true), telemetryRefreshRate);
133
97
  readiness.gate.once(constants_2.SDK_READY_FROM_CACHE, function () {
134
98
  telemetry.recordTimeUntilReadyFromCache(startTime());
135
99
  });
@@ -1,23 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isStorageSync = exports.shouldBeOptimized = exports.shouldAddPt = void 0;
3
+ exports.isStorageSync = void 0;
4
4
  var constants_1 = require("../../utils/constants");
5
- /**
6
- * Checks if impressions previous time should be added or not.
7
- */
8
- function shouldAddPt(settings) {
9
- return [constants_1.PRODUCER_MODE, constants_1.STANDALONE_MODE, constants_1.CONSUMER_PARTIAL_MODE].indexOf(settings.mode) > -1 ? true : false;
10
- }
11
- exports.shouldAddPt = shouldAddPt;
12
- /**
13
- * Checks if it should dedupe impressions or not.
14
- */
15
- function shouldBeOptimized(settings) {
16
- if (!shouldAddPt(settings))
17
- return false;
18
- return settings.sync.impressionsMode === constants_1.OPTIMIZED ? true : false;
19
- }
20
- exports.shouldBeOptimized = shouldBeOptimized;
21
5
  /**
22
6
  * Storage is async if mode is consumer or partial consumer
23
7
  */
@@ -10,7 +10,7 @@ var noopFilterAdapter = {
10
10
  /**
11
11
  * Trackes uniques keys
12
12
  * Unique Keys Tracker will be in charge of checking if the MTK was already sent to the BE in the last period
13
- * or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
13
+ * or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
14
14
  *
15
15
  * @param log Logger instance
16
16
  * @param uniqueKeysCache cache to save unique keys
@@ -132,8 +132,8 @@ function settingsValidation(config, validationParams) {
132
132
  if (storage)
133
133
  withDefaults.storage = storage(withDefaults);
134
134
  // Validate key and TT (for client-side)
135
+ var maybeKey = withDefaults.core.key;
135
136
  if (validationParams.acceptKey) {
136
- var maybeKey = withDefaults.core.key;
137
137
  // Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
138
138
  if (withDefaults.mode === constants_1.LOCALHOST_MODE && maybeKey === undefined) {
139
139
  withDefaults.core.key = 'localhost_key';
@@ -151,6 +151,12 @@ function settingsValidation(config, validationParams) {
151
151
  }
152
152
  }
153
153
  }
154
+ else {
155
+ // On server-side, key is undefined and used to distinguish from client-side
156
+ if (maybeKey !== undefined)
157
+ log.warn('Provided `key` is ignored in server-side SDK.'); // @ts-ignore
158
+ withDefaults.core.key = undefined;
159
+ }
154
160
  // Current ip/hostname information
155
161
  // @ts-ignore, modify readonly prop
156
162
  withDefaults.runtime = runtime(withDefaults);