@splitsoftware/splitio-commons 1.8.3 → 1.8.4-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +17 -0
  2. package/cjs/sync/polling/updaters/splitChangesUpdater.js +4 -2
  3. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +6 -2
  4. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +16 -7
  5. package/cjs/sync/streaming/pushManager.js +18 -3
  6. package/cjs/trackers/telemetryTracker.js +5 -1
  7. package/esm/storages/inMemory/TelemetryCacheInMemory.js +17 -0
  8. package/esm/sync/polling/updaters/splitChangesUpdater.js +4 -2
  9. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +6 -2
  10. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +13 -4
  11. package/esm/sync/streaming/pushManager.js +19 -4
  12. package/esm/trackers/telemetryTracker.js +5 -1
  13. package/package.json +1 -1
  14. package/src/storages/inMemory/TelemetryCacheInMemory.ts +21 -1
  15. package/src/storages/types.ts +2 -1
  16. package/src/sync/polling/types.ts +2 -1
  17. package/src/sync/polling/updaters/splitChangesUpdater.ts +6 -4
  18. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +6 -2
  19. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +15 -6
  20. package/src/sync/streaming/pushManager.ts +18 -4
  21. package/src/sync/submitters/types.ts +8 -0
  22. package/src/trackers/telemetryTracker.ts +6 -1
  23. package/src/trackers/types.ts +5 -1
  24. package/types/sdkClient/types.d.ts +18 -0
  25. package/types/storages/inMemory/CountsCacheInMemory.d.ts +20 -0
  26. package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +20 -0
  27. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +7 -1
  28. package/types/storages/inRedis/CountsCacheInRedis.d.ts +9 -0
  29. package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +9 -0
  30. package/types/storages/metadataBuilder.d.ts +3 -0
  31. package/types/storages/types.d.ts +2 -1
  32. package/types/sync/offline/LocalhostFromFile.d.ts +2 -0
  33. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -0
  34. package/types/sync/polling/types.d.ts +5 -1
  35. package/types/sync/polling/updaters/splitChangesUpdater.d.ts +4 -1
  36. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -1
  37. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +2 -1
  38. package/types/sync/submitters/eventsSyncTask.d.ts +8 -0
  39. package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +5 -0
  40. package/types/sync/submitters/impressionCountsSyncTask.d.ts +13 -0
  41. package/types/sync/submitters/impressionsSyncTask.d.ts +14 -0
  42. package/types/sync/submitters/metricsSyncTask.d.ts +12 -0
  43. package/types/sync/submitters/submitterSyncTask.d.ts +10 -0
  44. package/types/sync/submitters/types.d.ts +6 -0
  45. package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +5 -0
  46. package/types/sync/syncTaskComposite.d.ts +5 -0
  47. package/types/trackers/filter/bloomFilter.d.ts +10 -0
  48. package/types/trackers/filter/dictionaryFilter.d.ts +8 -0
  49. package/types/trackers/filter/types.d.ts +5 -0
  50. package/types/trackers/types.d.ts +5 -1
  51. package/types/utils/timeTracker/index.d.ts +70 -0
  52. package/types/utils/inputValidation/sdkKey.d.ts +0 -7
  53. /package/types/storages/inMemory/{UniqueKeysCacheInMemory.d.ts → uniqueKeysCacheInMemory.d.ts} +0 -0
  54. /package/types/storages/inMemory/{UniqueKeysCacheInMemoryCS.d.ts → uniqueKeysCacheInMemoryCS.d.ts} +0 -0
  55. /package/types/storages/inRedis/{UniqueKeysCacheInRedis.d.ts → uniqueKeysCacheInRedis.d.ts} +0 -0
@@ -14,7 +14,7 @@ import { getMatching } from '../../utils/key';
14
14
  import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
15
  import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 } from '../../logger/constants';
16
16
  import { KeyList, UpdateStrategy } from './SSEHandler/types';
17
- import { isInBitmap, parseBitmap, parseKeyList } from './parseUtils';
17
+ import { isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
18
18
  import { ISet, _Set } from '../../utils/lang/sets';
19
19
  import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
20
20
  import { IAuthTokenPushEnabled } from './AuthClient/types';
@@ -58,7 +58,7 @@ export function pushManagerFactory(
58
58
  // MySegmentsUpdateWorker (client-side) are initiated in `add` method
59
59
  const segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask as ISegmentsSyncTask, storage.segments);
60
60
  // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
61
- const splitsUpdateWorker = SplitsUpdateWorker(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
61
+ const splitsUpdateWorker = SplitsUpdateWorker(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
62
62
 
63
63
  // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
64
64
  const userKeyHashes: Record<string, string> = {};
@@ -221,7 +221,21 @@ export function pushManagerFactory(
221
221
  /** Functions related to synchronization (Queues and Workers in the spec) */
222
222
 
223
223
  pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
224
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
224
+ pushEmitter.on(SPLIT_UPDATE, (parsedData) => {
225
+ if (parsedData.d && parsedData.c !== undefined) {
226
+ try {
227
+ const payload = parseFFUpdatePayload(parsedData.c, parsedData.d);
228
+ if (payload) {
229
+ splitsUpdateWorker.put(parsedData, payload);
230
+ return;
231
+ }
232
+ } catch (e) {
233
+ // @TODO define a error code for feature flags parsing
234
+ log.debug(e);
235
+ }
236
+ }
237
+ splitsUpdateWorker.put(parsedData);
238
+ });
225
239
 
226
240
  if (userKey) {
227
241
  pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
@@ -330,7 +344,7 @@ export function pushManagerFactory(
330
344
 
331
345
  if (!userKeyHashes[hash]) {
332
346
  userKeyHashes[hash] = userKey;
333
- clients[userKey] = { hash64: hash64(userKey), worker: MySegmentsUpdateWorker(mySegmentsSyncTask) };
347
+ clients[userKey] = { hash64: hash64(userKey), worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker) };
334
348
  connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
335
349
 
336
350
  // Reconnects in case of a new client.
@@ -103,6 +103,7 @@ export type DROPPED = 1;
103
103
  export type DEDUPED = 2;
104
104
  export type ImpressionDataType = QUEUED | DROPPED | DEDUPED
105
105
  export type EventDataType = QUEUED | DROPPED;
106
+ export type UpdatesFromSSEEnum = SPLITS | MY_SEGMENT;
106
107
 
107
108
  export type SPLITS = 'sp';
108
109
  export type IMPRESSIONS = 'im';
@@ -151,6 +152,12 @@ export type TelemetryUsageStats = {
151
152
  mE?: MethodExceptions, // methodExceptions
152
153
  }
153
154
 
155
+ // amount of instant updates that we are doing by avoiding fetching to Split servers
156
+ export type UpdatesFromSSE = {
157
+ sp: number, // splits
158
+ ms?: number, // my segments
159
+ }
160
+
154
161
  // 'metrics/usage' JSON request body
155
162
  export type TelemetryUsageStatsPayload = TelemetryUsageStats & {
156
163
  lS: LastSync, // lastSynchronization
@@ -169,6 +176,7 @@ export type TelemetryUsageStatsPayload = TelemetryUsageStats & {
169
176
  eD: number, // eventsDropped
170
177
  sE: Array<StreamingEvent>, // streamingEvents
171
178
  t?: Array<string>, // tags
179
+ ufs?: UpdatesFromSSE, //UpdatesFromSSE
172
180
  }
173
181
 
174
182
  /**
@@ -3,6 +3,7 @@ import { EXCEPTION, SDK_NOT_READY } from '../utils/labels';
3
3
  import { ITelemetryTracker } from './types';
4
4
  import { timer } from '../utils/timeTracker/timer';
5
5
  import { TOKEN_REFRESH, AUTH_REJECTION } from '../utils/constants';
6
+ import { UpdatesFromSSEEnum } from '../sync/submitters/types';
6
7
 
7
8
  export function telemetryTrackerFactory(
8
9
  telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync,
@@ -52,6 +53,9 @@ export function telemetryTrackerFactory(
52
53
  addTag(tag: string) {
53
54
  // @ts-ignore
54
55
  if (telemetryCache.addTag) telemetryCache.addTag(tag);
56
+ },
57
+ trackUpdatesFromSSE(type: UpdatesFromSSEEnum) {
58
+ (telemetryCache as ITelemetryCacheSync).recordUpdatesFromSSE(type);
55
59
  }
56
60
  };
57
61
 
@@ -62,7 +66,8 @@ export function telemetryTrackerFactory(
62
66
  trackHttp: noopTrack,
63
67
  sessionLength() { },
64
68
  streamingEvent() { },
65
- addTag() { }
69
+ addTag() { },
70
+ trackUpdatesFromSSE() { },
66
71
  };
67
72
  }
68
73
  }
@@ -1,5 +1,5 @@
1
1
  import { SplitIO, ImpressionDTO } from '../types';
2
- import { StreamingEventType, Method, OperationType } from '../sync/submitters/types';
2
+ import { StreamingEventType, Method, OperationType, UpdatesFromSSEEnum } from '../sync/submitters/types';
3
3
  import { IEventsCacheBase } from '../storages/types';
4
4
  import { NetworkError } from '../services/types';
5
5
 
@@ -45,6 +45,10 @@ export interface ITelemetryTracker {
45
45
  * Records tag
46
46
  */
47
47
  addTag(tag: string): void
48
+ /**
49
+ * Records updates from sse
50
+ */
51
+ trackUpdatesFromSSE(type: UpdatesFromSSEEnum): void;
48
52
  }
49
53
 
50
54
  export interface IFilterAdapter {
@@ -0,0 +1,18 @@
1
+ import { ISignalListener } from '../listeners/types';
2
+ import { ISdkReadinessManager } from '../readiness/types';
3
+ import { IStorageAsync, IStorageSync } from '../storages/types';
4
+ import { ISyncManager } from '../sync/types';
5
+ import { IEventTracker, IImpressionsTracker } from '../trackers/types';
6
+ import { ISettings } from '../types';
7
+ export interface IClientFactoryParams {
8
+ storage: IStorageSync | IStorageAsync;
9
+ sdkReadinessManager: ISdkReadinessManager;
10
+ settings: ISettings;
11
+ impressionsTracker: IImpressionsTracker;
12
+ eventTracker: IEventTracker;
13
+ }
14
+ export interface ISdkClientFactoryParams extends IClientFactoryParams {
15
+ signalListener?: ISignalListener;
16
+ syncManager?: ISyncManager;
17
+ sharedClient?: boolean;
18
+ }
@@ -0,0 +1,20 @@
1
+ import { ICountsCacheSync } from '../types';
2
+ export declare class CountsCacheInMemory implements ICountsCacheSync {
3
+ private counters;
4
+ /**
5
+ * Add counts.
6
+ */
7
+ track(metricName: string): boolean;
8
+ /**
9
+ * Clear the collector
10
+ */
11
+ clear(): void;
12
+ /**
13
+ * Get the collected data, used as payload for posting.
14
+ */
15
+ state(): Record<string, number>;
16
+ /**
17
+ * Check if the cache is empty.
18
+ */
19
+ isEmpty(): boolean;
20
+ }
@@ -0,0 +1,20 @@
1
+ import { ILatenciesCacheSync } from '../types';
2
+ export declare class LatenciesCacheInMemory implements ILatenciesCacheSync {
3
+ private counters;
4
+ /**
5
+ * Add latencies.
6
+ */
7
+ track(metricName: string, latency: number): boolean;
8
+ /**
9
+ * Clear the collector
10
+ */
11
+ clear(): void;
12
+ /**
13
+ * Get the collected data, used as payload for posting.
14
+ */
15
+ state(): Record<string, number[]>;
16
+ /**
17
+ * Check if the cache is empty.
18
+ */
19
+ isEmpty(): boolean;
20
+ }
@@ -1,4 +1,4 @@
1
- import { ImpressionDataType, EventDataType, StreamingEvent, Method, OperationType, TelemetryUsageStatsPayload } from '../../sync/submitters/types';
1
+ import { ImpressionDataType, EventDataType, StreamingEvent, Method, OperationType, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../../sync/submitters/types';
2
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[];
@@ -64,4 +64,10 @@ export declare class TelemetryCacheInMemory implements ITelemetryCacheSync {
64
64
  private latencies;
65
65
  popLatencies(): Partial<Record<Method, number[]>>;
66
66
  recordLatency(method: Method, latencyMs: number): void;
67
+ private updatesFromSSE;
68
+ popUpdatesFromSSE(): {
69
+ sp: number;
70
+ ms: number;
71
+ };
72
+ recordUpdatesFromSSE(type: UpdatesFromSSEEnum): void;
67
73
  }
@@ -0,0 +1,9 @@
1
+ import { ICountsCacheAsync } from '../types';
2
+ import { KeyBuilderSS } from '../KeyBuilderSS';
3
+ import { Redis } from 'ioredis';
4
+ export declare class CountsCacheInRedis implements ICountsCacheAsync {
5
+ private readonly redis;
6
+ private readonly keys;
7
+ constructor(keys: KeyBuilderSS, redis: Redis);
8
+ track(metricName: string): Promise<boolean>;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { ILatenciesCacheAsync } from '../types';
2
+ import { KeyBuilderSS } from '../KeyBuilderSS';
3
+ import { Redis } from 'ioredis';
4
+ export declare class LatenciesCacheInRedis implements ILatenciesCacheAsync {
5
+ private readonly redis;
6
+ private readonly keys;
7
+ constructor(keys: KeyBuilderSS, redis: Redis);
8
+ track(metricName: string, latency: number): Promise<boolean>;
9
+ }
@@ -0,0 +1,3 @@
1
+ import { IMetadata } from '../dtos/types';
2
+ import { ISettings } from '../types';
3
+ export declare function metadataBuilder(settings: Pick<ISettings, 'version' | 'runtime'>): IMetadata;
@@ -1,5 +1,5 @@
1
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';
2
+ import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
3
3
  import { SplitIO, ImpressionDTO, ISettings } from '../types';
4
4
  /**
5
5
  * Interface of a pluggable storage wrapper.
@@ -343,6 +343,7 @@ export interface ITelemetryRuntimeProducerSync {
343
343
  recordTokenRefreshes(): void;
344
344
  recordStreamingEvents(streamingEvent: StreamingEvent): void;
345
345
  recordSessionLength(ms: number): void;
346
+ recordUpdatesFromSSE(type: UpdatesFromSSEEnum): void;
346
347
  }
347
348
  export interface ITelemetryEvaluationProducerSync {
348
349
  recordLatency(method: Method, latencyMs: number): void;
@@ -0,0 +1,2 @@
1
+ import { SplitIO } from '../../types';
2
+ export declare function LocalhostFromFile(): SplitIO.LocalhostFactory;
@@ -0,0 +1,2 @@
1
+ import { ISplitsParser } from './types';
2
+ export declare function splitsParserFromFileFactory(): ISplitsParser;
@@ -1,7 +1,11 @@
1
+ import { ISplit } from '../../dtos/types';
1
2
  import { IReadinessManager } from '../../readiness/types';
2
3
  import { IStorageSync } from '../../storages/types';
3
4
  import { ITask, ISyncTask } from '../types';
4
- export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number], boolean> {
5
+ export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: {
6
+ payload: ISplit;
7
+ changeNumber: number;
8
+ }], boolean> {
5
9
  }
6
10
  export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number], boolean> {
7
11
  }
@@ -4,7 +4,10 @@ import { ISplitChangesFetcher } from '../fetchers/types';
4
4
  import { ISplit } from '../../../dtos/types';
5
5
  import { ISplitsEventEmitter } from '../../../readiness/types';
6
6
  import { ILogger } from '../../../logger/types';
7
- declare type ISplitChangesUpdater = (noCache?: boolean, till?: number) => Promise<boolean>;
7
+ declare type ISplitChangesUpdater = (noCache?: boolean, till?: number, splitUpdateNotification?: {
8
+ payload: ISplit;
9
+ changeNumber: number;
10
+ }) => Promise<boolean>;
8
11
  /**
9
12
  * Collect segments from a raw split definition.
10
13
  * Exported for testing purposes.
@@ -1,6 +1,7 @@
1
1
  import { IMySegmentsSyncTask } from '../../polling/types';
2
2
  import { IUpdateWorker } from './types';
3
+ import { ITelemetryTracker } from '../../../trackers/types';
3
4
  /**
4
5
  * MySegmentsUpdateWorker factory
5
6
  */
6
- export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask): IUpdateWorker;
7
+ export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker): IUpdateWorker;
@@ -1,12 +1,13 @@
1
1
  import { ILogger } from '../../../logger/types';
2
2
  import { ISplitsEventEmitter } from '../../../readiness/types';
3
3
  import { ISplitsCacheSync } from '../../../storages/types';
4
+ import { ITelemetryTracker } from '../../../trackers/types';
4
5
  import { ISegmentsSyncTask, ISplitsSyncTask } from '../../polling/types';
5
6
  import { ISplitKillData } from '../SSEHandler/types';
6
7
  import { IUpdateWorker } from './types';
7
8
  /**
8
9
  * SplitsUpdateWorker factory
9
10
  */
10
- export declare function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker & {
11
+ export declare function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker & {
11
12
  killSplit(event: ISplitKillData): void;
12
13
  };
@@ -0,0 +1,8 @@
1
+ import { IEventsCacheSync } from '../../storages/types';
2
+ import { IPostEventsBulk } from '../../services/types';
3
+ import { ISyncTask, ITimeTracker } from '../types';
4
+ import { ILogger } from '../../logger/types';
5
+ /**
6
+ * Sync task that periodically posts tracked events
7
+ */
8
+ export declare function eventsSyncTaskFactory(log: ILogger, postEventsBulk: IPostEventsBulk, eventsCache: IEventsCacheSync, eventsPushRate: number, eventsFirstPushWindow: number, latencyTracker?: ITimeTracker): ISyncTask;
@@ -0,0 +1,5 @@
1
+ import { ISdkFactoryContextSync } from '../../sdkFactory/types';
2
+ /**
3
+ * Submitter that periodically posts impression counts
4
+ */
5
+ export declare function impressionCountsSubmitterInRedisFactory(params: ISdkFactoryContextSync): import("../types").ISyncTask<[], void>;
@@ -0,0 +1,13 @@
1
+ import { ISyncTask, ITimeTracker } from '../types';
2
+ import { IPostTestImpressionsCount } from '../../services/types';
3
+ import { IImpressionCountsCacheSync } from '../../storages/types';
4
+ import { ImpressionCountsPayload } from './types';
5
+ import { ILogger } from '../../logger/types';
6
+ /**
7
+ * Converts `impressionCounts` data from cache into request payload.
8
+ */
9
+ export declare function fromImpressionCountsCollector(impressionsCount: Record<string, number>): ImpressionCountsPayload;
10
+ /**
11
+ * Sync task that periodically posts impression counts
12
+ */
13
+ export declare function impressionCountsSyncTaskFactory(log: ILogger, postTestImpressionsCount: IPostTestImpressionsCount, impressionCountsCache: IImpressionCountsCacheSync, latencyTracker?: ITimeTracker): ISyncTask;
@@ -0,0 +1,14 @@
1
+ import { ISyncTask, ITimeTracker } from '../types';
2
+ import { IPostTestImpressionsBulk } from '../../services/types';
3
+ import { IImpressionsCacheSync } from '../../storages/types';
4
+ import { ImpressionDTO } from '../../types';
5
+ import { ImpressionsPayload } from './types';
6
+ import { ILogger } from '../../logger/types';
7
+ /**
8
+ * Converts `impressions` data from cache into request payload.
9
+ */
10
+ export declare function fromImpressionsCollector(sendLabels: boolean, data: ImpressionDTO[]): ImpressionsPayload;
11
+ /**
12
+ * Sync task that periodically posts impressions data
13
+ */
14
+ export declare function impressionsSyncTaskFactory(log: ILogger, postTestImpressionsBulk: IPostTestImpressionsBulk, impressionsCache: IImpressionsCacheSync, impressionsRefreshRate: number, sendLabels?: boolean, latencyTracker?: ITimeTracker): ISyncTask;
@@ -0,0 +1,12 @@
1
+ import { ICountsCacheSync, ILatenciesCacheSync } from '../../storages/types';
2
+ import { IPostMetricsCounters, IPostMetricsTimes } from '../../services/types';
3
+ import { ISyncTask, ITimeTracker } from '../types';
4
+ import { ILogger } from '../../logger/types';
5
+ /**
6
+ * Sync task that periodically posts telemetry counts
7
+ */
8
+ export declare function countsSyncTaskFactory(log: ILogger, postMetricsCounters: IPostMetricsCounters, countsCache: ICountsCacheSync, metricsRefreshRate: number, latencyTracker?: ITimeTracker): ISyncTask;
9
+ /**
10
+ * Sync task that periodically posts telemetry latencies
11
+ */
12
+ export declare function latenciesSyncTaskFactory(log: ILogger, postMetricsLatencies: IPostMetricsTimes, latenciesCache: ILatenciesCacheSync, metricsRefreshRate: number, latencyTracker?: ITimeTracker): ISyncTask;
@@ -0,0 +1,10 @@
1
+ import { ISyncTask, ITimeTracker } from '../types';
2
+ import { IRecorderCacheProducerSync } from '../../storages/types';
3
+ import { ILogger } from '../../logger/types';
4
+ import { IResponse } from '../../services/types';
5
+ /**
6
+ * Base function to create submitter sync tasks, such as ImpressionsSyncTask and EventsSyncTask
7
+ */
8
+ export declare function submitterSyncTaskFactory<TState extends {
9
+ length?: number;
10
+ }>(log: ILogger, postClient: (body: string) => Promise<IResponse>, sourceCache: IRecorderCacheProducerSync<TState>, postRate: number, dataName: string, latencyTracker?: ITimeTracker, fromCacheToPayload?: (cacheData: TState) => any, maxRetries?: number, debugLogs?: boolean): ISyncTask<[], void>;
@@ -90,6 +90,7 @@ export declare type DROPPED = 1;
90
90
  export declare type DEDUPED = 2;
91
91
  export declare type ImpressionDataType = QUEUED | DROPPED | DEDUPED;
92
92
  export declare type EventDataType = QUEUED | DROPPED;
93
+ export declare type UpdatesFromSSEEnum = SPLITS | MY_SEGMENT;
93
94
  export declare type SPLITS = 'sp';
94
95
  export declare type IMPRESSIONS = 'im';
95
96
  export declare type IMPRESSIONS_COUNT = 'ic';
@@ -130,6 +131,10 @@ export declare type TelemetryUsageStats = {
130
131
  mL?: MethodLatencies;
131
132
  mE?: MethodExceptions;
132
133
  };
134
+ export declare type UpdatesFromSSE = {
135
+ sp: number;
136
+ ms?: number;
137
+ };
133
138
  export declare type TelemetryUsageStatsPayload = TelemetryUsageStats & {
134
139
  lS: LastSync;
135
140
  hE: HttpErrors;
@@ -147,6 +152,7 @@ export declare type TelemetryUsageStatsPayload = TelemetryUsageStats & {
147
152
  eD: number;
148
153
  sE: Array<StreamingEvent>;
149
154
  t?: Array<string>;
155
+ ufs?: UpdatesFromSSE;
150
156
  };
151
157
  /**
152
158
  * Telemetry config stats
@@ -0,0 +1,5 @@
1
+ import { ISdkFactoryContextSync } from '../../sdkFactory/types';
2
+ /**
3
+ * Submitter that periodically posts impression counts
4
+ */
5
+ export declare function uniqueKeysSubmitterInRedisFactory(params: ISdkFactoryContextSync): import("../types").ISyncTask<[], void>;
@@ -0,0 +1,5 @@
1
+ import { ISyncTask } from './types';
2
+ /**
3
+ * Composite Sync Task: group of sync tasks that are treated as a single one.
4
+ */
5
+ export declare function syncTaskComposite(syncTasks: ISyncTask[]): ISyncTask;
@@ -0,0 +1,10 @@
1
+ import { IFilter } from './types';
2
+ export declare class BloomFilterImp implements IFilter {
3
+ private spectedInsertions;
4
+ private errorRate;
5
+ private filter;
6
+ constructor(spectedInsertions: number, errorRate: number);
7
+ add(data: string): boolean;
8
+ contains(data: string): boolean;
9
+ clear(): void;
10
+ }
@@ -0,0 +1,8 @@
1
+ import { IFilter } from './types';
2
+ export declare class DictionaryFilter implements IFilter {
3
+ private filter;
4
+ constructor();
5
+ add(data: string): boolean;
6
+ contains(data: string): boolean;
7
+ clear(): void;
8
+ }
@@ -0,0 +1,5 @@
1
+ export interface IFilter {
2
+ add(data: string): boolean;
3
+ contains(data: string): boolean;
4
+ clear(): void;
5
+ }
@@ -1,5 +1,5 @@
1
1
  import { SplitIO, ImpressionDTO } from '../types';
2
- import { StreamingEventType, Method, OperationType } from '../sync/submitters/types';
2
+ import { StreamingEventType, Method, OperationType, UpdatesFromSSEEnum } from '../sync/submitters/types';
3
3
  import { IEventsCacheBase } from '../storages/types';
4
4
  import { NetworkError } from '../services/types';
5
5
  /** Events tracker */
@@ -37,6 +37,10 @@ export interface ITelemetryTracker {
37
37
  * Records tag
38
38
  */
39
39
  addTag(tag: string): void;
40
+ /**
41
+ * Records updates from sse
42
+ */
43
+ trackUpdatesFromSSE(type: UpdatesFromSSEEnum): void;
40
44
  }
41
45
  export interface IFilterAdapter {
42
46
  add(key: string, featureName: string): boolean;
@@ -0,0 +1,70 @@
1
+ import { ILogger } from '../../logger/types';
2
+ import { IResponse } from '../../services/types';
3
+ interface MetricsCollector {
4
+ countException(): void;
5
+ count(status: number): void;
6
+ latency(ms: number): void;
7
+ ready(ms: number): void;
8
+ getTreatment(ms: number): void;
9
+ getTreatments(ms: number): void;
10
+ getTreatmentWithConfig(ms: number): void;
11
+ getTreatmentsWithConfig(ms: number): void;
12
+ [method: string]: (ms: number) => void;
13
+ }
14
+ export declare const TrackerAPI: {
15
+ /**
16
+ * "Private" method, used to attach count/countException and stop callbacks to a promise.
17
+ *
18
+ * @param {ILogger} log - Logger.
19
+ * @param {Promise} promise - The promise we want to attach the callbacks.
20
+ * @param {string} task - The name of the task.
21
+ * @param {number | string} modifier - (optional) The modifier for the task, if any.
22
+ */
23
+ __attachToPromise(log: ILogger, promise: Promise<IResponse>, task: string, collector: false | MetricsCollector, modifier?: string | number | undefined): Promise<IResponse>;
24
+ /**
25
+ * Starts tracking the time for a given task. All tasks tracked are considered "unique" because
26
+ * there may be multiple SDK instances tracking a "generic" task, making any task non-generic.
27
+ *
28
+ * @param {ILogger} log - Logger.
29
+ * @param {string} task - The task we are starting.
30
+ * @param {Object} collectors - The collectors map.
31
+ * @param {Promise} promise - (optional) The promise we are tracking.
32
+ * @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
33
+ */
34
+ start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector> | undefined, promise?: Promise<IResponse> | undefined, now?: (() => number) | undefined): Promise<IResponse> | (() => number);
35
+ /**
36
+ * Setup the collector for a task that reports metrics.
37
+ *
38
+ * @param {string} task - The task name
39
+ * @param {number | string} taskUniqueId - The unique identifier for this task
40
+ * @param {Object} collectors - The collectors map.
41
+ */
42
+ setCollectorForTask(task: string, taskUniqueId: number | string, collectors: Record<string, MetricsCollector>): void;
43
+ /**
44
+ * Stops the tracking of a given task.
45
+ *
46
+ * @param {ILogger} log - Logger.
47
+ * @param {string} task - The task we are starting.
48
+ * @param {number | string} modifier - (optional) The modifier for that specific task.
49
+ */
50
+ stop(log: ILogger, task: string, modifier?: string | number | undefined): number | undefined;
51
+ /**
52
+ * The constants shortcut for the task names.
53
+ */
54
+ TaskNames: {
55
+ SDK_READY: string;
56
+ SDK_GET_TREATMENT: string;
57
+ SDK_GET_TREATMENTS: string;
58
+ SDK_GET_TREATMENT_WITH_CONFIG: string;
59
+ SDK_GET_TREATMENTS_WITH_CONFIG: string;
60
+ SPLITS_READY: string;
61
+ SEGMENTS_READY: string;
62
+ METRICS_PUSH: string;
63
+ IMPRESSIONS_PUSH: string;
64
+ EVENTS_PUSH: string;
65
+ MY_SEGMENTS_FETCH: string;
66
+ SEGMENTS_FETCH: string;
67
+ SPLITS_FETCH: string;
68
+ };
69
+ };
70
+ export {};
@@ -1,7 +0,0 @@
1
- import { ILogger } from '../../logger/types';
2
- /** validates the given SDK key */
3
- export declare function validateApiKey(log: ILogger, maybeSdkKey: any): string | false;
4
- export declare const usedKeysMap: Record<string, number>;
5
- /** validates the given SDK key and also warns if it is in use */
6
- export declare function validateAndTrackApiKey(log: ILogger, maybeSdkKey: any): string | false;
7
- export declare function releaseApiKey(sdkKey: string): void;