@splitsoftware/splitio-commons 1.6.2-rc.12 → 1.6.2-rc.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/listeners/browser.js +9 -11
- package/cjs/sdkFactory/index.js +7 -24
- package/cjs/storages/KeyBuilderSS.js +4 -43
- package/cjs/storages/inLocalStorage/index.js +14 -10
- package/cjs/storages/inMemory/InMemoryStorage.js +10 -7
- package/cjs/storages/inMemory/InMemoryStorageCS.js +10 -7
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +57 -34
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +3 -3
- package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +4 -4
- package/cjs/storages/inRedis/index.js +4 -2
- package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +3 -3
- package/cjs/storages/pluggable/ImpressionsCachePluggable.js +2 -19
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +4 -4
- package/cjs/storages/pluggable/inMemoryWrapper.js +8 -6
- package/cjs/storages/pluggable/index.js +4 -2
- package/cjs/storages/utils.js +73 -0
- package/cjs/sync/submitters/submitterManager.js +1 -1
- package/cjs/sync/submitters/telemetrySubmitter.js +4 -40
- package/cjs/trackers/impressionObserver/utils.js +1 -17
- package/cjs/trackers/uniqueKeysTracker.js +1 -1
- package/cjs/utils/settingsValidation/index.js +7 -1
- package/esm/listeners/browser.js +9 -11
- package/esm/sdkFactory/index.js +7 -24
- package/esm/storages/KeyBuilderSS.js +1 -37
- package/esm/storages/inLocalStorage/index.js +15 -11
- package/esm/storages/inMemory/InMemoryStorage.js +10 -7
- package/esm/storages/inMemory/InMemoryStorageCS.js +10 -7
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +58 -35
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +3 -3
- package/esm/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +1 -1
- package/esm/storages/inRedis/index.js +4 -2
- package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +3 -3
- package/esm/storages/pluggable/ImpressionsCachePluggable.js +2 -19
- package/esm/storages/pluggable/TelemetryCachePluggable.js +1 -1
- package/esm/storages/pluggable/inMemoryWrapper.js +8 -6
- package/esm/storages/pluggable/index.js +4 -2
- package/esm/storages/utils.js +65 -0
- package/esm/sync/submitters/submitterManager.js +1 -1
- package/esm/sync/submitters/telemetrySubmitter.js +4 -39
- package/esm/trackers/impressionObserver/utils.js +1 -15
- package/esm/trackers/uniqueKeysTracker.js +1 -1
- package/esm/utils/settingsValidation/index.js +7 -1
- package/package.json +2 -1
- package/src/listeners/browser.ts +9 -13
- package/src/sdkClient/sdkClient.ts +1 -1
- package/src/sdkFactory/index.ts +7 -29
- package/src/sdkFactory/types.ts +2 -2
- package/src/services/splitApi.ts +2 -2
- package/src/storages/KeyBuilderSS.ts +2 -44
- package/src/storages/inLocalStorage/index.ts +16 -11
- package/src/storages/inMemory/AttributesCacheInMemory.ts +7 -7
- package/src/storages/inMemory/InMemoryStorage.ts +11 -7
- package/src/storages/inMemory/InMemoryStorageCS.ts +11 -7
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +66 -33
- package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +3 -3
- package/src/storages/inRedis/ImpressionsCacheInRedis.ts +2 -22
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +3 -2
- package/src/storages/inRedis/index.ts +4 -1
- package/src/storages/pluggable/ImpressionCountsCachePluggable.ts +3 -3
- package/src/storages/pluggable/ImpressionsCachePluggable.ts +3 -23
- package/src/storages/pluggable/TelemetryCachePluggable.ts +3 -2
- package/src/storages/pluggable/inMemoryWrapper.ts +6 -6
- package/src/storages/pluggable/index.ts +4 -2
- package/src/storages/types.ts +45 -64
- package/src/storages/utils.ts +78 -0
- package/src/sync/submitters/submitter.ts +2 -2
- package/src/sync/submitters/submitterManager.ts +1 -1
- package/src/sync/submitters/telemetrySubmitter.ts +5 -41
- package/src/sync/submitters/types.ts +7 -5
- package/src/trackers/impressionObserver/utils.ts +1 -16
- package/src/trackers/impressionsTracker.ts +2 -2
- package/src/trackers/strategy/strategyDebug.ts +4 -4
- package/src/trackers/strategy/strategyNone.ts +9 -9
- package/src/trackers/strategy/strategyOptimized.ts +9 -9
- package/src/trackers/uniqueKeysTracker.ts +6 -6
- package/src/utils/redis/RedisMock.ts +5 -5
- package/src/utils/settingsValidation/index.ts +5 -1
- package/types/storages/KeyBuilderSS.d.ts +1 -3
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +19 -8
- package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +0 -1
- package/types/storages/pluggable/ImpressionsCachePluggable.d.ts +1 -2
- package/types/storages/types.d.ts +35 -45
- package/types/storages/utils.d.ts +8 -0
- package/types/sync/submitters/submitter.d.ts +2 -2
- package/types/sync/submitters/telemetrySubmitter.d.ts +2 -10
- package/types/sync/submitters/types.d.ts +8 -6
- package/types/trackers/impressionObserver/utils.d.ts +0 -8
- package/types/trackers/strategy/strategyNone.d.ts +2 -2
- package/types/trackers/strategy/strategyOptimized.d.ts +2 -2
- package/types/trackers/uniqueKeysTracker.d.ts +1 -1
- package/cjs/storages/metadataBuilder.js +0 -12
- package/esm/storages/metadataBuilder.js +0 -8
- package/src/storages/metadataBuilder.ts +0 -11
|
@@ -76,6 +76,8 @@ export type StoredImpressionWithMetadata = {
|
|
|
76
76
|
c: number,
|
|
77
77
|
/** time */
|
|
78
78
|
m: number
|
|
79
|
+
/** previous time */
|
|
80
|
+
pt?: number
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -112,9 +114,9 @@ export type SEGMENT = 'se';
|
|
|
112
114
|
export type MY_SEGMENT = 'ms';
|
|
113
115
|
export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
|
|
114
116
|
|
|
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
|
|
117
|
+
export type LastSync = Partial<Record<OperationType, number | undefined>>
|
|
118
|
+
export type HttpErrors = Partial<Record<OperationType, { [statusCode: string]: number }>>
|
|
119
|
+
export type HttpLatencies = Partial<Record<OperationType, Array<number>>>
|
|
118
120
|
|
|
119
121
|
export type TREATMENT = 't';
|
|
120
122
|
export type TREATMENTS = 'ts';
|
|
@@ -123,9 +125,9 @@ export type TREATMENTS_WITH_CONFIG = 'tcs';
|
|
|
123
125
|
export type TRACK = 'tr';
|
|
124
126
|
export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK;
|
|
125
127
|
|
|
126
|
-
export type MethodLatencies = Record<Method, Array<number
|
|
128
|
+
export type MethodLatencies = Partial<Record<Method, Array<number>>>;
|
|
127
129
|
|
|
128
|
-
export type MethodExceptions = Record<Method, number
|
|
130
|
+
export type MethodExceptions = Partial<Record<Method, number>>;
|
|
129
131
|
|
|
130
132
|
export type CONNECTION_ESTABLISHED = 0;
|
|
131
133
|
export type OCCUPANCY_PRI = 10;
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE
|
|
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
|
*/
|
|
@@ -31,9 +31,9 @@ export function impressionsTrackerFactory(
|
|
|
31
31
|
|
|
32
32
|
const impressionsCount = impressions.length;
|
|
33
33
|
const { impressionsToStore, impressionsToListener, deduped } = strategy.process(impressions);
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
const impressionsToListenerCount = impressionsToListener.length;
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
if ( impressionsToStore.length>0 ){
|
|
38
38
|
const res = impressionsCache.track(impressionsToStore);
|
|
39
39
|
|
|
@@ -4,14 +4,14 @@ import { IStrategy } from '../types';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Debug strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
* @param impressionsObserver impression observer. Previous time (pt property) is included in impression instances
|
|
9
9
|
* @returns IStrategyResult
|
|
10
10
|
*/
|
|
11
11
|
export function strategyDebugFactory(
|
|
12
12
|
impressionsObserver: IImpressionObserver
|
|
13
13
|
): IStrategy {
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
return {
|
|
16
16
|
process(impressions: ImpressionDTO[]) {
|
|
17
17
|
impressions.forEach((impression) => {
|
|
@@ -19,8 +19,8 @@ export function strategyDebugFactory(
|
|
|
19
19
|
impression.pt = impressionsObserver.testAndSet(impression);
|
|
20
20
|
});
|
|
21
21
|
return {
|
|
22
|
-
impressionsToStore: impressions,
|
|
23
|
-
impressionsToListener: impressions,
|
|
22
|
+
impressionsToStore: impressions,
|
|
23
|
+
impressionsToListener: impressions,
|
|
24
24
|
deduped: 0
|
|
25
25
|
};
|
|
26
26
|
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import {
|
|
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:
|
|
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 {
|
|
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:
|
|
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
|
-
*
|
|
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
|
}
|
|
@@ -12,9 +12,9 @@ const ASYNC_METHODS = ['rpush', 'hincrby'];
|
|
|
12
12
|
const PIPELINE_METHODS = ['rpush', 'hincrby'];
|
|
13
13
|
|
|
14
14
|
export class RedisMock {
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
private pipelineMethods: any = { exec: jest.fn(asyncFunction) }
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
constructor() {
|
|
19
19
|
IDENTITY_METHODS.forEach(method => {
|
|
20
20
|
this[method] = jest.fn(identityFunction);
|
|
@@ -25,9 +25,9 @@ export class RedisMock {
|
|
|
25
25
|
PIPELINE_METHODS.forEach(method => {
|
|
26
26
|
this.pipelineMethods[method] = this[method];
|
|
27
27
|
});
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
this.pipeline = jest.fn(() => {return this.pipelineMethods;});
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
|
|
33
33
|
}
|
|
@@ -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,6 +1,7 @@
|
|
|
1
1
|
import { KeyBuilder } from './KeyBuilder';
|
|
2
2
|
import { IMetadata } from '../dtos/types';
|
|
3
3
|
import { Method } from '../sync/submitters/types';
|
|
4
|
+
export declare const METHOD_NAMES: Record<Method, string>;
|
|
4
5
|
export declare class KeyBuilderSS extends KeyBuilder {
|
|
5
6
|
latencyPrefix: string;
|
|
6
7
|
exceptionPrefix: string;
|
|
@@ -17,6 +18,3 @@ export declare class KeyBuilderSS extends KeyBuilder {
|
|
|
17
18
|
buildExceptionKey(method: Method): string;
|
|
18
19
|
buildInitKey(): string;
|
|
19
20
|
}
|
|
20
|
-
export declare function parseMetadata(field: string): [metadata: string] | string;
|
|
21
|
-
export declare function parseExceptionField(field: string): [metadata: string, method: Method] | string;
|
|
22
|
-
export declare function parseLatencyField(field: string): [metadata: string, method: Method, bucket: number] | string;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import { ImpressionDataType, EventDataType,
|
|
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(
|
|
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():
|
|
36
|
+
getLastSynchronization(): Partial<Record<OperationType, number | undefined>>;
|
|
28
37
|
recordSuccessfulSync(resource: OperationType, timeMs: number): void;
|
|
29
38
|
private httpErrors;
|
|
30
|
-
popHttpErrors():
|
|
39
|
+
popHttpErrors(): Partial<Record<OperationType, {
|
|
40
|
+
[statusCode: string]: number;
|
|
41
|
+
}>>;
|
|
31
42
|
recordHttpError(resource: OperationType, status: number): void;
|
|
32
43
|
private httpLatencies;
|
|
33
|
-
popHttpLatencies():
|
|
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():
|
|
62
|
+
popExceptions(): Partial<Record<Method, number>>;
|
|
52
63
|
recordException(method: Method): void;
|
|
53
64
|
private latencies;
|
|
54
|
-
popLatencies():
|
|
65
|
+
popLatencies(): Partial<Record<Method, number[]>>;
|
|
55
66
|
recordLatency(method: Method, latencyMs: number): void;
|
|
56
67
|
}
|
|
@@ -11,7 +11,6 @@ export declare class ImpressionsCacheInRedis implements IImpressionsCacheAsync {
|
|
|
11
11
|
private readonly metadata;
|
|
12
12
|
constructor(log: ILogger, key: string, redis: Redis, metadata: IMetadata);
|
|
13
13
|
track(impressions: ImpressionDTO[]): Promise<void>;
|
|
14
|
-
private _toJSON;
|
|
15
14
|
count(): Promise<number>;
|
|
16
15
|
drop(count?: number): Promise<any>;
|
|
17
16
|
popNWithMetadata(count: number): Promise<StoredImpressionWithMetadata[]>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IPluggableStorageWrapper, IImpressionsCacheAsync } from '../types';
|
|
2
2
|
import { IMetadata } from '../../dtos/types';
|
|
3
3
|
import { ImpressionDTO } from '../../types';
|
|
4
|
-
import { ILogger } from '../../logger/types';
|
|
5
4
|
import { StoredImpressionWithMetadata } from '../../sync/submitters/types';
|
|
5
|
+
import { ILogger } from '../../logger/types';
|
|
6
6
|
export declare class ImpressionsCachePluggable implements IImpressionsCacheAsync {
|
|
7
7
|
private readonly log;
|
|
8
8
|
private readonly key;
|
|
@@ -16,7 +16,6 @@ export declare class ImpressionsCachePluggable implements IImpressionsCacheAsync
|
|
|
16
16
|
* or rejected if the wrapper operation fails.
|
|
17
17
|
*/
|
|
18
18
|
track(impressions: ImpressionDTO[]): Promise<void>;
|
|
19
|
-
private _toJSON;
|
|
20
19
|
/**
|
|
21
20
|
* Returns a promise that resolves with the count of stored impressions, or 0 if there was some error.
|
|
22
21
|
* The promise will never be rejected.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { MaybeThenable,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
* Interface of a pluggable storage wrapper.
|
|
7
6
|
*/
|
|
@@ -65,21 +64,21 @@ export interface IPluggableStorageWrapper {
|
|
|
65
64
|
getMany: (keys: string[]) => Promise<(string | null)[]>;
|
|
66
65
|
/** Integer operations */
|
|
67
66
|
/**
|
|
68
|
-
* Increments the number stored at `key` by `increment
|
|
67
|
+
* Increments the number stored at `key` by `increment`, or set it to `increment` if the value doesn't exist.
|
|
69
68
|
*
|
|
70
69
|
* @function incr
|
|
71
70
|
* @param {string} key Key to increment
|
|
72
|
-
* @param {number} increment Value to increment by
|
|
71
|
+
* @param {number} increment Value to increment by. Defaults to 1.
|
|
73
72
|
* @returns {Promise<number>} A promise that resolves with the value of key after the increment. The promise rejects if the operation fails,
|
|
74
73
|
* for example, if there is a connection error or the key contains a string that can not be represented as integer.
|
|
75
74
|
*/
|
|
76
75
|
incr: (key: string, increment?: number) => Promise<number>;
|
|
77
76
|
/**
|
|
78
|
-
* Decrements the number stored at `key` by `decrement
|
|
77
|
+
* Decrements the number stored at `key` by `decrement`, or set it to minus `decrement` if the value doesn't exist.
|
|
79
78
|
*
|
|
80
79
|
* @function decr
|
|
81
80
|
* @param {string} key Key to decrement
|
|
82
|
-
* @param {number} decrement Value to decrement by
|
|
81
|
+
* @param {number} decrement Value to decrement by. Defaults to 1.
|
|
83
82
|
* @returns {Promise<number>} A promise that resolves with the value of key after the decrement. The promise rejects if the operation fails,
|
|
84
83
|
* for example, if there is a connection error or the key contains a string that can not be represented as integer.
|
|
85
84
|
*/
|
|
@@ -264,48 +263,43 @@ export interface IImpressionsCacheBase {
|
|
|
264
263
|
export interface IEventsCacheBase {
|
|
265
264
|
track(data: SplitIO.EventData, size?: number): MaybeThenable<boolean>;
|
|
266
265
|
}
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
export interface IImpressionCountsCacheBase {
|
|
267
|
+
track(featureName: string, timeFrame: number, amount: number): void;
|
|
268
|
+
}
|
|
269
|
+
export interface IUniqueKeysCacheBase {
|
|
270
|
+
track(key: string, value: string): void;
|
|
271
|
+
}
|
|
272
|
+
/** Impressions and events cache for standalone and partial consumer modes (sync methods) */
|
|
273
|
+
export interface IRecorderCacheSync<T> {
|
|
269
274
|
isEmpty(): boolean;
|
|
270
275
|
clear(): void;
|
|
271
276
|
pop(toMerge?: T): T;
|
|
272
277
|
}
|
|
273
|
-
export interface IImpressionsCacheSync extends IImpressionsCacheBase,
|
|
278
|
+
export interface IImpressionsCacheSync extends IImpressionsCacheBase, IRecorderCacheSync<ImpressionDTO[]> {
|
|
274
279
|
track(data: ImpressionDTO[]): void;
|
|
275
280
|
setOnFullQueueCb(cb: () => void): void;
|
|
276
281
|
}
|
|
277
|
-
export interface IEventsCacheSync extends IEventsCacheBase,
|
|
282
|
+
export interface IEventsCacheSync extends IEventsCacheBase, IRecorderCacheSync<SplitIO.EventData[]> {
|
|
278
283
|
track(data: SplitIO.EventData, size?: number): boolean;
|
|
279
284
|
setOnFullQueueCb(cb: () => void): void;
|
|
280
285
|
}
|
|
281
|
-
|
|
282
|
-
|
|
286
|
+
export interface IImpressionCountsCacheSync extends IImpressionCountsCacheBase, IRecorderCacheSync<Record<string, number>> {
|
|
287
|
+
}
|
|
288
|
+
export interface IUniqueKeysCacheSync extends IUniqueKeysCacheBase, IRecorderCacheSync<UniqueKeysPayloadSs | UniqueKeysPayloadCs> {
|
|
289
|
+
setOnFullQueueCb(cb: () => void): void;
|
|
290
|
+
}
|
|
291
|
+
/** Impressions and events cache for consumer and producer modes (async methods) */
|
|
292
|
+
export interface IRecorderCacheAsync<T> {
|
|
283
293
|
count(): Promise<number>;
|
|
284
294
|
drop(count?: number): Promise<void>;
|
|
285
295
|
popNWithMetadata(count: number): Promise<T>;
|
|
286
296
|
}
|
|
287
|
-
export interface IImpressionsCacheAsync extends IImpressionsCacheBase,
|
|
297
|
+
export interface IImpressionsCacheAsync extends IImpressionsCacheBase, IRecorderCacheAsync<StoredImpressionWithMetadata[]> {
|
|
288
298
|
track(data: ImpressionDTO[]): Promise<void>;
|
|
289
299
|
}
|
|
290
|
-
export interface IEventsCacheAsync extends IEventsCacheBase,
|
|
300
|
+
export interface IEventsCacheAsync extends IEventsCacheBase, IRecorderCacheAsync<StoredEventWithMetadata[]> {
|
|
291
301
|
track(data: SplitIO.EventData, size?: number): Promise<boolean>;
|
|
292
302
|
}
|
|
293
|
-
/**
|
|
294
|
-
* Impression counts cache for impressions dedup in standalone and producer mode.
|
|
295
|
-
* Only in memory. Named `ImpressionsCounter` in spec.
|
|
296
|
-
*/
|
|
297
|
-
export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<Record<string, number>> {
|
|
298
|
-
track(featureName: string, timeFrame: number, amount: number): void;
|
|
299
|
-
isEmpty(): boolean;
|
|
300
|
-
pop(toMerge?: Record<string, number>): Record<string, number>;
|
|
301
|
-
}
|
|
302
|
-
export interface IUniqueKeysCacheBase {
|
|
303
|
-
track(key: string, value: string): void;
|
|
304
|
-
isEmpty(): boolean;
|
|
305
|
-
pop(): UniqueKeysPayloadSs | UniqueKeysPayloadCs;
|
|
306
|
-
setOnFullQueueCb(cb: () => void): void;
|
|
307
|
-
clear(): void;
|
|
308
|
-
}
|
|
309
303
|
/**
|
|
310
304
|
* Telemetry storage interface for standalone and partial consumer modes.
|
|
311
305
|
* Methods are sync because data is stored in memory.
|
|
@@ -356,7 +350,7 @@ export interface ITelemetryEvaluationProducerSync {
|
|
|
356
350
|
}
|
|
357
351
|
export interface ITelemetryStorageProducerSync extends ITelemetryInitProducerSync, ITelemetryRuntimeProducerSync, ITelemetryEvaluationProducerSync {
|
|
358
352
|
}
|
|
359
|
-
export interface ITelemetryCacheSync extends ITelemetryStorageConsumerSync, ITelemetryStorageProducerSync {
|
|
353
|
+
export interface ITelemetryCacheSync extends ITelemetryStorageConsumerSync, ITelemetryStorageProducerSync, IRecorderCacheSync<TelemetryUsageStatsPayload> {
|
|
360
354
|
}
|
|
361
355
|
/**
|
|
362
356
|
* Telemetry storage interface for consumer mode.
|
|
@@ -377,7 +371,7 @@ export interface ITelemetryCacheAsync extends ITelemetryEvaluationProducerAsync,
|
|
|
377
371
|
/**
|
|
378
372
|
* Storages
|
|
379
373
|
*/
|
|
380
|
-
export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCache extends ISegmentsCacheBase, TImpressionsCache extends IImpressionsCacheBase, TImpressionsCountCache extends
|
|
374
|
+
export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCache extends ISegmentsCacheBase, TImpressionsCache extends IImpressionsCacheBase, TImpressionsCountCache extends IImpressionCountsCacheBase, TEventsCache extends IEventsCacheBase, TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync, TUniqueKeysCache extends IUniqueKeysCacheBase> {
|
|
381
375
|
splits: TSplitsCache;
|
|
382
376
|
segments: TSegmentsCache;
|
|
383
377
|
impressions: TImpressionsCache;
|
|
@@ -388,23 +382,19 @@ export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCa
|
|
|
388
382
|
destroy(): void | Promise<void>;
|
|
389
383
|
shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this;
|
|
390
384
|
}
|
|
391
|
-
export interface IStorageSync extends IStorageBase<ISplitsCacheSync, ISegmentsCacheSync, IImpressionsCacheSync, IImpressionCountsCacheSync, IEventsCacheSync, ITelemetryCacheSync,
|
|
385
|
+
export interface IStorageSync extends IStorageBase<ISplitsCacheSync, ISegmentsCacheSync, IImpressionsCacheSync, IImpressionCountsCacheSync, IEventsCacheSync, ITelemetryCacheSync, IUniqueKeysCacheSync> {
|
|
392
386
|
}
|
|
393
|
-
export interface IStorageAsync extends IStorageBase<ISplitsCacheAsync, ISegmentsCacheAsync, IImpressionsCacheAsync | IImpressionsCacheSync,
|
|
387
|
+
export interface IStorageAsync extends IStorageBase<ISplitsCacheAsync, ISegmentsCacheAsync, IImpressionsCacheAsync | IImpressionsCacheSync, IImpressionCountsCacheBase, IEventsCacheAsync | IEventsCacheSync, ITelemetryCacheAsync | ITelemetryCacheSync, IUniqueKeysCacheBase> {
|
|
394
388
|
}
|
|
395
389
|
/** StorageFactory */
|
|
396
390
|
export declare type DataLoader = (storage: IStorageSync, matchingKey: string) => void;
|
|
397
391
|
export interface IStorageFactoryParams {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
impressionsMode?: string;
|
|
404
|
-
matchingKey?: string;
|
|
405
|
-
splitFiltersValidation?: ISplitFiltersValidation;
|
|
392
|
+
settings: ISettings;
|
|
393
|
+
/**
|
|
394
|
+
* 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.
|
|
395
|
+
* It is meant for emitting SDK_READY event in consumer mode, and waiting before using the storage in the synchronizer.
|
|
396
|
+
*/
|
|
406
397
|
onReadyCb: (error?: any) => void;
|
|
407
|
-
metadata: IMetadata;
|
|
408
398
|
}
|
|
409
399
|
export declare type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS' | 'PLUGGABLE';
|
|
410
400
|
export declare type IStorageSyncFactory = {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IMetadata } from '../dtos/types';
|
|
2
|
+
import { Method } from '../sync/submitters/types';
|
|
3
|
+
import { ImpressionDTO, ISettings } from '../types';
|
|
4
|
+
export declare function metadataBuilder(settings: Pick<ISettings, 'version' | 'runtime'>): IMetadata;
|
|
5
|
+
export declare function impressionsToJSON(impressions: ImpressionDTO[], metadata: IMetadata): string[];
|
|
6
|
+
export declare function parseMetadata(field: string): [metadata: string] | string;
|
|
7
|
+
export declare function parseExceptionField(field: string): [metadata: string, method: Method] | string;
|
|
8
|
+
export declare function parseLatencyField(field: string): [metadata: string, method: Method, bucket: number] | string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ISyncTask } from '../types';
|
|
2
|
-
import {
|
|
2
|
+
import { IRecorderCacheSync } from '../../storages/types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
4
|
import { IResponse } from '../../services/types';
|
|
5
5
|
/**
|
|
6
6
|
* Base function to create submitters, such as ImpressionsSubmitter and EventsSubmitter
|
|
7
7
|
*/
|
|
8
|
-
export declare function submitterFactory<T>(log: ILogger, postClient: (body: string) => Promise<IResponse>, sourceCache:
|
|
8
|
+
export declare function submitterFactory<T>(log: ILogger, postClient: (body: string) => Promise<IResponse>, sourceCache: IRecorderCacheSync<T>, postRate: number, dataName: string, fromCacheToPayload?: (cacheData: T) => any, maxRetries?: number, debugLogs?: boolean): ISyncTask<[], void>;
|
|
9
9
|
/**
|
|
10
10
|
* Decorates a provided submitter with a first execution window
|
|
11
11
|
*/
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ITelemetryCacheSync } from '../../storages/types';
|
|
2
|
+
import { TelemetryConfigStatsPayload, TelemetryConfigStats } from './types';
|
|
3
3
|
import { ISettings, SDKMode } from '../../types';
|
|
4
4
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
5
|
-
/**
|
|
6
|
-
* Converts data from telemetry cache into /metrics/usage request payload.
|
|
7
|
-
*/
|
|
8
|
-
export declare function telemetryCacheStatsAdapter(telemetry: ITelemetryCacheSync, splits?: ISplitsCacheSync, segments?: ISegmentsCacheSync): {
|
|
9
|
-
isEmpty(): boolean;
|
|
10
|
-
clear(): void;
|
|
11
|
-
pop(): TelemetryUsageStatsPayload;
|
|
12
|
-
};
|
|
13
5
|
export declare function getTelemetryConfigStats(mode: SDKMode, storageType: string): TelemetryConfigStats;
|
|
14
6
|
/**
|
|
15
7
|
* Converts data from telemetry cache and settings into /metrics/config request payload.
|
|
@@ -69,6 +69,8 @@ export declare type StoredImpressionWithMetadata = {
|
|
|
69
69
|
c: number;
|
|
70
70
|
/** time */
|
|
71
71
|
m: number;
|
|
72
|
+
/** previous time */
|
|
73
|
+
pt?: number;
|
|
72
74
|
};
|
|
73
75
|
};
|
|
74
76
|
export declare type StoredEventWithMetadata = {
|
|
@@ -97,19 +99,19 @@ export declare type TOKEN = 'to';
|
|
|
97
99
|
export declare type SEGMENT = 'se';
|
|
98
100
|
export declare type MY_SEGMENT = 'ms';
|
|
99
101
|
export declare type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
|
|
100
|
-
export declare type LastSync = Record<OperationType, number | undefined
|
|
101
|
-
export declare type HttpErrors = Record<OperationType, {
|
|
102
|
+
export declare type LastSync = Partial<Record<OperationType, number | undefined>>;
|
|
103
|
+
export declare type HttpErrors = Partial<Record<OperationType, {
|
|
102
104
|
[statusCode: string]: number;
|
|
103
|
-
}
|
|
104
|
-
export declare type HttpLatencies = Record<OperationType, Array<number
|
|
105
|
+
}>>;
|
|
106
|
+
export declare type HttpLatencies = Partial<Record<OperationType, Array<number>>>;
|
|
105
107
|
export declare type TREATMENT = 't';
|
|
106
108
|
export declare type TREATMENTS = 'ts';
|
|
107
109
|
export declare type TREATMENT_WITH_CONFIG = 'tc';
|
|
108
110
|
export declare type TREATMENTS_WITH_CONFIG = 'tcs';
|
|
109
111
|
export declare type TRACK = 'tr';
|
|
110
112
|
export declare type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK;
|
|
111
|
-
export declare type MethodLatencies = Record<Method, Array<number
|
|
112
|
-
export declare type MethodExceptions = Record<Method, number
|
|
113
|
+
export declare type MethodLatencies = Partial<Record<Method, Array<number>>>;
|
|
114
|
+
export declare type MethodExceptions = Partial<Record<Method, number>>;
|
|
113
115
|
export declare type CONNECTION_ESTABLISHED = 0;
|
|
114
116
|
export declare type OCCUPANCY_PRI = 10;
|
|
115
117
|
export declare type OCCUPANCY_SEC = 20;
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
import { ISettings } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Checks if impressions previous time should be added or not.
|
|
4
|
-
*/
|
|
5
|
-
export declare function shouldAddPt(settings: ISettings): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Checks if it should dedupe impressions or not.
|
|
8
|
-
*/
|
|
9
|
-
export declare function shouldBeOptimized(settings: ISettings): boolean;
|
|
10
2
|
/**
|
|
11
3
|
* Storage is async if mode is consumer or partial consumer
|
|
12
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IImpressionCountsCacheBase } from '../../storages/types';
|
|
2
2
|
import { IStrategy, IUniqueKeysTracker } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* None strategy for impressions tracker.
|
|
@@ -7,4 +7,4 @@ import { IStrategy, IUniqueKeysTracker } from '../types';
|
|
|
7
7
|
* @param uniqueKeysTracker unique keys tracker in charge of tracking the unique keys per split.
|
|
8
8
|
* @returns IStrategyResult
|
|
9
9
|
*/
|
|
10
|
-
export declare function strategyNoneFactory(impressionsCounter:
|
|
10
|
+
export declare function strategyNoneFactory(impressionsCounter: IImpressionCountsCacheBase, uniqueKeysTracker: IUniqueKeysTracker): IStrategy;
|