@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
@@ -1,7 +1,6 @@
1
- import { MaybeThenable, IMetadata, ISplitFiltersValidation, ISplit } from '../dtos/types';
2
- import { ILogger } from '../logger/types';
3
- import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs } from '../sync/submitters/types';
4
- import { SplitIO, ImpressionDTO, SDKMode } from '../types';
1
+ import { MaybeThenable, ISplit } from '../dtos/types';
2
+ import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload } from '../sync/submitters/types';
3
+ import { SplitIO, ImpressionDTO, ISettings } from '../types';
5
4
 
6
5
  /**
7
6
  * Interface of a pluggable storage wrapper.
@@ -285,19 +284,29 @@ export interface ISegmentsCacheAsync extends ISegmentsCacheBase {
285
284
  /** Recorder storages (impressions, events and telemetry) */
286
285
 
287
286
  export interface IImpressionsCacheBase {
288
- // Consumer API method, used by impressions tracker, in standalone and consumer modes, to push impressions into the storage.
287
+ // Used by impressions tracker, in DEBUG and OPTIMIZED impression modes, to push impressions into the storage.
289
288
  track(data: ImpressionDTO[]): MaybeThenable<void>
290
289
  }
291
290
 
292
291
  export interface IEventsCacheBase {
293
- // Consumer API method, used by events tracker, in standalone and consumer modes, to push events into the storage.
292
+ // Used by events tracker to push events into the storage.
294
293
  track(data: SplitIO.EventData, size?: number): MaybeThenable<boolean>
295
294
  }
296
295
 
297
- /** Impressions and events cache for standalone mode (sync) */
296
+ export interface IImpressionCountsCacheBase {
297
+ // Used by impressions tracker, in OPTIMIZED and NONE impression modes, to count impressions.
298
+ track(featureName: string, timeFrame: number, amount: number): void
299
+ }
300
+
301
+ export interface IUniqueKeysCacheBase {
302
+ // Used by impressions tracker, in NONE impression mode, to track unique keys.
303
+ track(key: string, value: string): void
304
+ }
298
305
 
299
- // Producer API methods for sync recorder storages, used by submitters in standalone mode to pop data and post it to Split BE.
300
- export interface IRecorderCacheProducerSync<T> {
306
+ /** Impressions and events cache for standalone and partial consumer modes (sync methods) */
307
+
308
+ // API methods for sync recorder storages, used by submitters in standalone mode to pop data and post it to Split BE.
309
+ export interface IRecorderCacheSync<T> {
301
310
  // @TODO names are inconsistent with spec
302
311
  /* Checks if cache is empty. Returns true if the cache was just created or cleared */
303
312
  isEmpty(): boolean
@@ -307,23 +316,29 @@ export interface IRecorderCacheProducerSync<T> {
307
316
  pop(toMerge?: T): T
308
317
  }
309
318
 
310
-
311
- export interface IImpressionsCacheSync extends IImpressionsCacheBase, IRecorderCacheProducerSync<ImpressionDTO[]> {
319
+ export interface IImpressionsCacheSync extends IImpressionsCacheBase, IRecorderCacheSync<ImpressionDTO[]> {
312
320
  track(data: ImpressionDTO[]): void
313
321
  /* Registers callback for full queue */
314
322
  setOnFullQueueCb(cb: () => void): void
315
323
  }
316
324
 
317
- export interface IEventsCacheSync extends IEventsCacheBase, IRecorderCacheProducerSync<SplitIO.EventData[]> {
325
+ export interface IEventsCacheSync extends IEventsCacheBase, IRecorderCacheSync<SplitIO.EventData[]> {
318
326
  track(data: SplitIO.EventData, size?: number): boolean
319
327
  /* Registers callback for full queue */
320
328
  setOnFullQueueCb(cb: () => void): void
321
329
  }
322
330
 
323
- /** Impressions and events cache for consumer and producer mode (async) */
331
+ /* Named `ImpressionsCounter` in spec */
332
+ export interface IImpressionCountsCacheSync extends IImpressionCountsCacheBase, IRecorderCacheSync<Record<string, number>> { }
324
333
 
325
- // Producer API methods for async recorder storages, used by submitters in producer mode to pop data and post it to Split BE.
326
- export interface IRecorderCacheProducerAsync<T> {
334
+ export interface IUniqueKeysCacheSync extends IUniqueKeysCacheBase, IRecorderCacheSync<UniqueKeysPayloadSs | UniqueKeysPayloadCs> {
335
+ setOnFullQueueCb(cb: () => void): void,
336
+ }
337
+
338
+ /** Impressions and events cache for consumer and producer modes (async methods) */
339
+
340
+ // API methods for async recorder storages, used by submitters in producer mode (synchronizer) to pop data and post it to Split BE.
341
+ export interface IRecorderCacheAsync<T> {
327
342
  /* returns the number of stored items */
328
343
  count(): Promise<number>
329
344
  /* removes the given number of items from the store. If not provided, it deletes all items */
@@ -332,43 +347,18 @@ export interface IRecorderCacheProducerAsync<T> {
332
347
  popNWithMetadata(count: number): Promise<T>
333
348
  }
334
349
 
335
- export interface IImpressionsCacheAsync extends IImpressionsCacheBase, IRecorderCacheProducerAsync<StoredImpressionWithMetadata[]> {
350
+ export interface IImpressionsCacheAsync extends IImpressionsCacheBase, IRecorderCacheAsync<StoredImpressionWithMetadata[]> {
336
351
  // Consumer API method, used by impressions tracker (in standalone and consumer modes) to push data into.
337
352
  // The result promise can reject.
338
353
  track(data: ImpressionDTO[]): Promise<void>
339
354
  }
340
355
 
341
- export interface IEventsCacheAsync extends IEventsCacheBase, IRecorderCacheProducerAsync<StoredEventWithMetadata[]> {
356
+ export interface IEventsCacheAsync extends IEventsCacheBase, IRecorderCacheAsync<StoredEventWithMetadata[]> {
342
357
  // Consumer API method, used by events tracker (in standalone and consumer modes) to push data into.
343
358
  // The result promise cannot reject.
344
359
  track(data: SplitIO.EventData, size?: number): Promise<boolean>
345
360
  }
346
361
 
347
- /**
348
- * Impression counts cache for impressions dedup in standalone and producer mode.
349
- * Only in memory. Named `ImpressionsCounter` in spec.
350
- */
351
- export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<Record<string, number>> {
352
- // Used by impressions tracker
353
- track(featureName: string, timeFrame: number, amount: number): void
354
-
355
- // Used by impressions count submitter in standalone and producer mode
356
- isEmpty(): boolean // check if cache is empty. Return true if the cache was just created or cleared.
357
- pop(toMerge?: Record<string, number>): Record<string, number> // pop cache data
358
- }
359
-
360
- export interface IUniqueKeysCacheBase {
361
- // Used by unique Keys tracker
362
- track(key: string, value: string): void
363
-
364
- // Used by unique keys submitter in standalone and producer mode
365
- isEmpty(): boolean // check if cache is empty. Return true if the cache was just created or cleared.
366
- pop(): UniqueKeysPayloadSs | UniqueKeysPayloadCs // pop cache data
367
- /* Registers callback for full queue */
368
- setOnFullQueueCb(cb: () => void): void,
369
- clear(): void
370
- }
371
-
372
362
  /**
373
363
  * Telemetry storage interface for standalone and partial consumer modes.
374
364
  * Methods are sync because data is stored in memory.
@@ -428,7 +418,7 @@ export interface ITelemetryEvaluationProducerSync {
428
418
 
429
419
  export interface ITelemetryStorageProducerSync extends ITelemetryInitProducerSync, ITelemetryRuntimeProducerSync, ITelemetryEvaluationProducerSync { }
430
420
 
431
- export interface ITelemetryCacheSync extends ITelemetryStorageConsumerSync, ITelemetryStorageProducerSync { }
421
+ export interface ITelemetryCacheSync extends ITelemetryStorageConsumerSync, ITelemetryStorageProducerSync, IRecorderCacheSync<TelemetryUsageStatsPayload> { }
432
422
 
433
423
  /**
434
424
  * Telemetry storage interface for consumer mode.
@@ -458,7 +448,7 @@ export interface IStorageBase<
458
448
  TSplitsCache extends ISplitsCacheBase,
459
449
  TSegmentsCache extends ISegmentsCacheBase,
460
450
  TImpressionsCache extends IImpressionsCacheBase,
461
- TImpressionsCountCache extends IImpressionCountsCacheSync,
451
+ TImpressionsCountCache extends IImpressionCountsCacheBase,
462
452
  TEventsCache extends IEventsCacheBase,
463
453
  TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync,
464
454
  TUniqueKeysCache extends IUniqueKeysCacheBase
@@ -481,14 +471,14 @@ export interface IStorageSync extends IStorageBase<
481
471
  IImpressionCountsCacheSync,
482
472
  IEventsCacheSync,
483
473
  ITelemetryCacheSync,
484
- IUniqueKeysCacheBase
474
+ IUniqueKeysCacheSync
485
475
  > { }
486
476
 
487
477
  export interface IStorageAsync extends IStorageBase<
488
478
  ISplitsCacheAsync,
489
479
  ISegmentsCacheAsync,
490
480
  IImpressionsCacheAsync | IImpressionsCacheSync,
491
- IImpressionCountsCacheSync,
481
+ IImpressionCountsCacheBase,
492
482
  IEventsCacheAsync | IEventsCacheSync,
493
483
  ITelemetryCacheAsync | ITelemetryCacheSync,
494
484
  IUniqueKeysCacheBase
@@ -499,21 +489,12 @@ export interface IStorageAsync extends IStorageBase<
499
489
  export type DataLoader = (storage: IStorageSync, matchingKey: string) => void
500
490
 
501
491
  export interface IStorageFactoryParams {
502
- log: ILogger,
503
- impressionsQueueSize?: number,
504
- eventsQueueSize?: number,
505
- optimize?: boolean /* whether create the `impressionCounts` cache (OPTIMIZED impression mode) or not (DEBUG impression mode) */,
506
- mode: SDKMode,
507
- impressionsMode?: string,
508
- // ATM, only used by InLocalStorage
509
- matchingKey?: string, /* undefined on server-side SDKs */
510
- splitFiltersValidation?: ISplitFiltersValidation,
511
-
512
- // This callback is invoked when the storage is ready to be used. Error-first callback style: if an error is passed,
513
- // it means that the storge fail to connect and shouldn't be used.
514
- // It is meant for emitting SDK_READY event in consumer mode, and for synchronizer to wait before using the storage.
492
+ settings: ISettings,
493
+ /**
494
+ * Error-first callback invoked when the storage is ready to be used. An error means that the storage failed to connect and shouldn't be used.
495
+ * It is meant for emitting SDK_READY event in consumer mode, and waiting before using the storage in the synchronizer.
496
+ */
515
497
  onReadyCb: (error?: any) => void,
516
- metadata: IMetadata,
517
498
  }
518
499
 
519
500
  export type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS' | 'PLUGGABLE';
@@ -1,6 +1,6 @@
1
1
  import { syncTaskFactory } from '../syncTask';
2
2
  import { ISyncTask } from '../types';
3
- import { IRecorderCacheProducerSync } from '../../storages/types';
3
+ import { IRecorderCacheSync } from '../../storages/types';
4
4
  import { ILogger } from '../../logger/types';
5
5
  import { SUBMITTERS_PUSH, SUBMITTERS_PUSH_FAILS, SUBMITTERS_PUSH_RETRY } from '../../logger/constants';
6
6
  import { IResponse } from '../../services/types';
@@ -11,7 +11,7 @@ import { IResponse } from '../../services/types';
11
11
  export function submitterFactory<T>(
12
12
  log: ILogger,
13
13
  postClient: (body: string) => Promise<IResponse>,
14
- sourceCache: IRecorderCacheProducerSync<T>,
14
+ sourceCache: IRecorderCacheSync<T>,
15
15
  postRate: number,
16
16
  dataName: string,
17
17
  fromCacheToPayload?: (cacheData: T) => any,
@@ -16,7 +16,7 @@ export function submitterManagerFactory(params: ISdkFactoryContextSync): ISubmit
16
16
  const impressionCountsSubmitter = impressionCountsSubmitterFactory(params);
17
17
  if (impressionCountsSubmitter) submitters.push(impressionCountsSubmitter);
18
18
  const telemetrySubmitter = telemetrySubmitterFactory(params);
19
- if (params.uniqueKeysTracker) submitters.push(uniqueKeysSubmitterFactory(params));
19
+ if (params.storage.uniqueKeys) submitters.push(uniqueKeysSubmitterFactory(params));
20
20
 
21
21
  return {
22
22
  // `onlyTelemetry` true if SDK is created with userConsent not GRANTED
@@ -1,7 +1,7 @@
1
- import { ISegmentsCacheSync, ISplitsCacheSync, ITelemetryCacheSync } from '../../storages/types';
1
+ import { ITelemetryCacheSync } from '../../storages/types';
2
2
  import { submitterFactory, firstPushWindowDecorator } from './submitter';
3
- import { TelemetryUsageStatsPayload, TelemetryConfigStatsPayload, TelemetryConfigStats } from './types';
4
- import { QUEUED, DEDUPED, DROPPED, CONSUMER_MODE, CONSUMER_ENUM, STANDALONE_MODE, CONSUMER_PARTIAL_MODE, STANDALONE_ENUM, CONSUMER_PARTIAL_ENUM, OPTIMIZED, DEBUG, NONE, DEBUG_ENUM, OPTIMIZED_ENUM, NONE_ENUM, CONSENT_GRANTED, CONSENT_DECLINED, CONSENT_UNKNOWN } from '../../utils/constants';
3
+ import { TelemetryConfigStatsPayload, TelemetryConfigStats } from './types';
4
+ import { CONSUMER_MODE, CONSUMER_ENUM, STANDALONE_MODE, CONSUMER_PARTIAL_MODE, STANDALONE_ENUM, CONSUMER_PARTIAL_ENUM, OPTIMIZED, DEBUG, NONE, DEBUG_ENUM, OPTIMIZED_ENUM, NONE_ENUM, CONSENT_GRANTED, CONSENT_DECLINED, CONSENT_UNKNOWN } from '../../utils/constants';
5
5
  import { SDK_READY, SDK_READY_FROM_CACHE } from '../../readiness/constants';
6
6
  import { ConsentStatus, ISettings, SDKMode } from '../../types';
7
7
  import { base } from '../../utils/settingsValidation';
@@ -9,41 +9,6 @@ import { usedKeysMap } from '../../utils/inputValidation/apiKey';
9
9
  import { timer } from '../../utils/timeTracker/timer';
10
10
  import { ISdkFactoryContextSync } from '../../sdkFactory/types';
11
11
  import { objectAssign } from '../../utils/lang/objectAssign';
12
- import { isStorageSync } from '../../trackers/impressionObserver/utils';
13
-
14
- /**
15
- * Converts data from telemetry cache into /metrics/usage request payload.
16
- */
17
- export function telemetryCacheStatsAdapter(telemetry: ITelemetryCacheSync, splits?: ISplitsCacheSync, segments?: ISegmentsCacheSync) {
18
- return {
19
- isEmpty() { return false; }, // There is always data in telemetry cache
20
- clear() { }, // No-op
21
-
22
- // @TODO consider moving inside telemetry cache for code size reduction
23
- pop(): TelemetryUsageStatsPayload {
24
- return {
25
- lS: telemetry.getLastSynchronization(),
26
- mL: telemetry.popLatencies(),
27
- mE: telemetry.popExceptions(),
28
- hE: telemetry.popHttpErrors(),
29
- hL: telemetry.popHttpLatencies(),
30
- tR: telemetry.popTokenRefreshes(),
31
- aR: telemetry.popAuthRejections(),
32
- iQ: telemetry.getImpressionStats(QUEUED),
33
- iDe: telemetry.getImpressionStats(DEDUPED),
34
- iDr: telemetry.getImpressionStats(DROPPED),
35
- spC: splits && splits.getSplitNames().length,
36
- seC: segments && segments.getRegisteredSegments().length,
37
- skC: segments && segments.getKeysCount(),
38
- sL: telemetry.getSessionLength(),
39
- eQ: telemetry.getEventStats(QUEUED),
40
- eD: telemetry.getEventStats(DROPPED),
41
- sE: telemetry.popStreamingEvents(),
42
- t: telemetry.popTags(),
43
- };
44
- }
45
- };
46
- }
47
12
 
48
13
  const OPERATION_MODE_MAP = {
49
14
  [STANDALONE_MODE]: STANDALONE_ENUM,
@@ -131,7 +96,7 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
131
96
  * Submitter that periodically posts telemetry data
132
97
  */
133
98
  export function telemetrySubmitterFactory(params: ISdkFactoryContextSync) {
134
- const { storage: { splits, segments, telemetry }, platform: { now } } = params;
99
+ const { storage: { telemetry }, platform: { now } } = params;
135
100
  if (!telemetry || !now) return; // No submitter created if telemetry cache is not defined
136
101
 
137
102
  const { settings, settings: { log, scheduler: { telemetryRefreshRate } }, splitApi, readiness, sdkReadinessManager } = params;
@@ -140,8 +105,7 @@ export function telemetrySubmitterFactory(params: ISdkFactoryContextSync) {
140
105
  const submitter = firstPushWindowDecorator(
141
106
  submitterFactory(
142
107
  log, splitApi.postMetricsUsage,
143
- // @TODO cannot provide splits and segments cache if they are async, because `submitterFactory` expects a sync storage source
144
- isStorageSync(params.settings) ? telemetryCacheStatsAdapter(telemetry, splits, segments) : telemetryCacheStatsAdapter(telemetry),
108
+ telemetry,
145
109
  telemetryRefreshRate, 'telemetry stats', undefined, 0, true
146
110
  ),
147
111
  telemetryRefreshRate
@@ -112,9 +112,9 @@ export type SEGMENT = 'se';
112
112
  export type MY_SEGMENT = 'ms';
113
113
  export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
114
114
 
115
- export type LastSync = Record<OperationType, number | undefined>
116
- export type HttpErrors = Record<OperationType, { [statusCode: string]: number }>
117
- export type HttpLatencies = Record<OperationType, Array<number>>
115
+ export type LastSync = Partial<Record<OperationType, number | undefined>>
116
+ export type HttpErrors = Partial<Record<OperationType, { [statusCode: string]: number }>>
117
+ export type HttpLatencies = Partial<Record<OperationType, Array<number>>>
118
118
 
119
119
  export type TREATMENT = 't';
120
120
  export type TREATMENTS = 'ts';
@@ -123,9 +123,9 @@ export type TREATMENTS_WITH_CONFIG = 'tcs';
123
123
  export type TRACK = 'tr';
124
124
  export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK;
125
125
 
126
- export type MethodLatencies = Record<Method, Array<number>>;
126
+ export type MethodLatencies = Partial<Record<Method, Array<number>>>;
127
127
 
128
- export type MethodExceptions = Record<Method, number>;
128
+ export type MethodExceptions = Partial<Record<Method, number>>;
129
129
 
130
130
  export type CONNECTION_ESTABLISHED = 0;
131
131
  export type OCCUPANCY_PRI = 10;
@@ -1,21 +1,6 @@
1
- import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE, OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
1
+ import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE } from '../../utils/constants';
2
2
  import { ISettings } from '../../types';
3
3
 
4
- /**
5
- * Checks if impressions previous time should be added or not.
6
- */
7
- export function shouldAddPt(settings: ISettings) {
8
- return [PRODUCER_MODE, STANDALONE_MODE, CONSUMER_PARTIAL_MODE].indexOf(settings.mode) > -1 ? true : false;
9
- }
10
-
11
- /**
12
- * Checks if it should dedupe impressions or not.
13
- */
14
- export function shouldBeOptimized(settings: ISettings) {
15
- if (!shouldAddPt(settings)) return false;
16
- return settings.sync.impressionsMode === OPTIMIZED ? true : false;
17
- }
18
-
19
4
  /**
20
5
  * Storage is async if mode is consumer or partial consumer
21
6
  */
@@ -1,32 +1,32 @@
1
- import { IImpressionCountsCacheSync } from '../../storages/types';
1
+ import { IImpressionCountsCacheBase } from '../../storages/types';
2
2
  import { ImpressionDTO } from '../../types';
3
3
  import { IStrategy, IUniqueKeysTracker } from '../types';
4
4
 
5
5
  /**
6
6
  * None strategy for impressions tracker.
7
- *
7
+ *
8
8
  * @param impressionsCounter cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
9
- * @param uniqueKeysTracker unique keys tracker in charge of tracking the unique keys per split.
9
+ * @param uniqueKeysTracker unique keys tracker in charge of tracking the unique keys per split.
10
10
  * @returns IStrategyResult
11
11
  */
12
12
  export function strategyNoneFactory(
13
- impressionsCounter: IImpressionCountsCacheSync,
13
+ impressionsCounter: IImpressionCountsCacheBase,
14
14
  uniqueKeysTracker: IUniqueKeysTracker
15
15
  ): IStrategy {
16
-
16
+
17
17
  return {
18
18
  process(impressions: ImpressionDTO[]) {
19
- impressions.forEach((impression) => {
19
+ impressions.forEach((impression) => {
20
20
  const now = Date.now();
21
21
  // Increments impression counter per featureName
22
22
  impressionsCounter.track(impression.feature, now, 1);
23
23
  // Keep track by unique key
24
24
  uniqueKeysTracker.track(impression.keyName, impression.feature);
25
25
  });
26
-
26
+
27
27
  return {
28
- impressionsToStore: [],
29
- impressionsToListener: impressions,
28
+ impressionsToStore: [],
29
+ impressionsToListener: impressions,
30
30
  deduped: 0
31
31
  };
32
32
  }
@@ -1,4 +1,4 @@
1
- import { IImpressionCountsCacheSync } from '../../storages/types';
1
+ import { IImpressionCountsCacheBase } from '../../storages/types';
2
2
  import { ImpressionDTO } from '../../types';
3
3
  import { truncateTimeFrame } from '../../utils/time';
4
4
  import { IImpressionObserver } from '../impressionObserver/types';
@@ -6,35 +6,35 @@ import { IStrategy } from '../types';
6
6
 
7
7
  /**
8
8
  * Optimized strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
9
- *
9
+ *
10
10
  * @param impressionsObserver impression observer. previous time (pt property) is included in impression instances
11
11
  * @param impressionsCounter cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
12
12
  * @returns IStrategyResult
13
13
  */
14
14
  export function strategyOptimizedFactory(
15
15
  impressionsObserver: IImpressionObserver,
16
- impressionsCounter: IImpressionCountsCacheSync,
16
+ impressionsCounter: IImpressionCountsCacheBase,
17
17
  ): IStrategy {
18
-
18
+
19
19
  return {
20
20
  process(impressions: ImpressionDTO[]) {
21
21
  const impressionsToStore: ImpressionDTO[] = [];
22
22
  impressions.forEach((impression) => {
23
23
  impression.pt = impressionsObserver.testAndSet(impression);
24
-
24
+
25
25
  const now = Date.now();
26
-
26
+
27
27
  // Increments impression counter per featureName
28
28
  if (impression.pt) impressionsCounter.track(impression.feature, now, 1);
29
-
29
+
30
30
  // Checks if the impression should be added in queue to be sent
31
31
  if (!impression.pt || impression.pt < truncateTimeFrame(now)) {
32
32
  impressionsToStore.push(impression);
33
33
  }
34
34
  });
35
35
  return {
36
- impressionsToStore: impressionsToStore,
37
- impressionsToListener: impressions,
36
+ impressionsToStore: impressionsToStore,
37
+ impressionsToListener: impressions,
38
38
  deduped: impressions.length - impressionsToStore.length
39
39
  };
40
40
  }
@@ -4,16 +4,16 @@ import { IUniqueKeysCacheBase } from '../storages/types';
4
4
  import { IFilterAdapter, IUniqueKeysTracker } from './types';
5
5
 
6
6
  const noopFilterAdapter = {
7
- add() {return true;},
8
- contains() {return true;},
9
- clear() {}
7
+ add() { return true; },
8
+ contains() { return true; },
9
+ clear() { }
10
10
  };
11
11
 
12
12
  /**
13
13
  * Trackes uniques keys
14
14
  * Unique Keys Tracker will be in charge of checking if the MTK was already sent to the BE in the last period
15
- * or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
16
- *
15
+ * or schedule to be sent; if not it will be added in an internal cache and sent in the next post.
16
+ *
17
17
  * @param log Logger instance
18
18
  * @param uniqueKeysCache cache to save unique keys
19
19
  * @param filterAdapter filter adapter
@@ -42,7 +42,7 @@ export function uniqueKeysTrackerFactory(
42
42
  stop(): void {
43
43
  clearInterval(intervalId);
44
44
  }
45
-
45
+
46
46
  };
47
47
 
48
48
  }
@@ -154,8 +154,8 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
154
154
  if (storage) withDefaults.storage = storage(withDefaults);
155
155
 
156
156
  // Validate key and TT (for client-side)
157
+ const maybeKey = withDefaults.core.key;
157
158
  if (validationParams.acceptKey) {
158
- const maybeKey = withDefaults.core.key;
159
159
  // Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
160
160
  if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
161
161
  withDefaults.core.key = 'localhost_key';
@@ -172,6 +172,10 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
172
172
  withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
173
173
  }
174
174
  }
175
+ } else {
176
+ // On server-side, key is undefined and used to distinguish from client-side
177
+ if (maybeKey !== undefined) log.warn('Provided `key` is ignored in server-side SDK.'); // @ts-ignore
178
+ withDefaults.core.key = undefined;
175
179
  }
176
180
 
177
181
  // Current ip/hostname information
@@ -1,13 +1,21 @@
1
- import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies } from '../../sync/submitters/types';
2
- import { IStorageFactoryParams, ITelemetryCacheSync } from '../types';
1
+ import { ImpressionDataType, EventDataType, StreamingEvent, Method, OperationType, TelemetryUsageStatsPayload } from '../../sync/submitters/types';
2
+ import { ISegmentsCacheSync, ISplitsCacheSync, IStorageFactoryParams, ITelemetryCacheSync } from '../types';
3
3
  export declare const MAX_LATENCY_BUCKET_COUNT = 23;
4
4
  export declare function newBuckets(): number[];
5
5
  /**
6
6
  * Record telemetry if mode is not localhost.
7
7
  * All factory instances track telemetry on server-side, and 0.1% on client-side.
8
8
  */
9
- export declare function shouldRecordTelemetry(params: IStorageFactoryParams): boolean;
9
+ export declare function shouldRecordTelemetry({ settings }: IStorageFactoryParams): boolean;
10
10
  export declare class TelemetryCacheInMemory implements ITelemetryCacheSync {
11
+ private splits?;
12
+ private segments?;
13
+ constructor(splits?: ISplitsCacheSync | undefined, segments?: ISegmentsCacheSync | undefined);
14
+ private e;
15
+ isEmpty(): boolean;
16
+ clear(): void;
17
+ pop(): TelemetryUsageStatsPayload;
18
+ /** Config stats */
11
19
  private timeUntilReady?;
12
20
  getTimeUntilReady(): number | undefined;
13
21
  recordTimeUntilReady(ms: number): void;
@@ -17,6 +25,7 @@ export declare class TelemetryCacheInMemory implements ITelemetryCacheSync {
17
25
  private notReadyUsage;
18
26
  getNonReadyUsage(): number;
19
27
  recordNonReadyUsage(): void;
28
+ /** Usage stats */
20
29
  private impressionStats;
21
30
  getImpressionStats(type: ImpressionDataType): number;
22
31
  recordImpressionStats(type: ImpressionDataType, count: number): void;
@@ -24,13 +33,15 @@ export declare class TelemetryCacheInMemory implements ITelemetryCacheSync {
24
33
  getEventStats(type: EventDataType): number;
25
34
  recordEventStats(type: EventDataType, count: number): void;
26
35
  private lastSync;
27
- getLastSynchronization(): LastSync;
36
+ getLastSynchronization(): Partial<Record<OperationType, number | undefined>>;
28
37
  recordSuccessfulSync(resource: OperationType, timeMs: number): void;
29
38
  private httpErrors;
30
- popHttpErrors(): HttpErrors;
39
+ popHttpErrors(): Partial<Record<OperationType, {
40
+ [statusCode: string]: number;
41
+ }>>;
31
42
  recordHttpError(resource: OperationType, status: number): void;
32
43
  private httpLatencies;
33
- popHttpLatencies(): HttpLatencies;
44
+ popHttpLatencies(): Partial<Record<OperationType, number[]>>;
34
45
  recordHttpLatency(resource: OperationType, latencyMs: number): void;
35
46
  private authRejections;
36
47
  popAuthRejections(): number;
@@ -48,9 +59,9 @@ export declare class TelemetryCacheInMemory implements ITelemetryCacheSync {
48
59
  getSessionLength(): number | undefined;
49
60
  recordSessionLength(ms: number): void;
50
61
  private exceptions;
51
- popExceptions(): MethodExceptions;
62
+ popExceptions(): Partial<Record<Method, number>>;
52
63
  recordException(method: Method): void;
53
64
  private latencies;
54
- popLatencies(): MethodLatencies;
65
+ popLatencies(): Partial<Record<Method, number[]>>;
55
66
  recordLatency(method: Method, latencyMs: number): void;
56
67
  }