@splitsoftware/splitio-commons 1.6.1 → 1.6.2-rc.2
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 +2 -1
- package/cjs/logger/constants.js +2 -1
- package/cjs/sdkFactory/index.js +14 -5
- package/cjs/services/splitApi.js +20 -0
- package/cjs/storages/inLocalStorage/index.js +4 -0
- package/cjs/storages/inMemory/InMemoryStorage.js +5 -1
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -1
- package/cjs/storages/inMemory/uniqueKeysCacheInMemory.js +73 -0
- package/cjs/storages/inMemory/uniqueKeysCacheInMemoryCS.js +78 -0
- package/cjs/sync/submitters/submitterManager.js +3 -0
- package/cjs/sync/submitters/telemetrySubmitter.js +1 -0
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +26 -0
- package/cjs/trackers/impressionsTracker.js +7 -28
- package/cjs/trackers/strategy/strategyDebug.js +25 -0
- package/cjs/trackers/strategy/strategyNone.js +29 -0
- package/cjs/trackers/strategy/strategyOptimized.js +34 -0
- package/cjs/trackers/uniqueKeysTracker.js +31 -0
- package/cjs/utils/constants/index.js +4 -2
- package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
- package/cjs/utils/settingsValidation/index.js +3 -0
- package/esm/listeners/browser.js +3 -2
- package/esm/logger/constants.js +1 -0
- package/esm/sdkFactory/index.js +14 -5
- package/esm/services/splitApi.js +20 -0
- package/esm/storages/inLocalStorage/index.js +5 -1
- package/esm/storages/inMemory/InMemoryStorage.js +6 -2
- package/esm/storages/inMemory/InMemoryStorageCS.js +6 -2
- package/esm/storages/inMemory/uniqueKeysCacheInMemory.js +70 -0
- package/esm/storages/inMemory/uniqueKeysCacheInMemoryCS.js +75 -0
- package/esm/sync/submitters/submitterManager.js +3 -0
- package/esm/sync/submitters/telemetrySubmitter.js +2 -1
- package/esm/sync/submitters/uniqueKeysSubmitter.js +22 -0
- package/esm/trackers/impressionsTracker.js +7 -28
- package/esm/trackers/strategy/strategyDebug.js +21 -0
- package/esm/trackers/strategy/strategyNone.js +25 -0
- package/esm/trackers/strategy/strategyOptimized.js +30 -0
- package/esm/trackers/uniqueKeysTracker.js +27 -0
- package/esm/utils/constants/index.js +2 -0
- package/esm/utils/settingsValidation/impressionsMode.js +3 -3
- package/esm/utils/settingsValidation/index.js +3 -0
- package/package.json +1 -1
- package/src/listeners/browser.ts +3 -2
- package/src/logger/constants.ts +1 -0
- package/src/sdkFactory/index.ts +16 -5
- package/src/sdkFactory/types.ts +7 -4
- package/src/services/splitApi.ts +22 -0
- package/src/services/types.ts +6 -0
- package/src/storages/inLocalStorage/index.ts +4 -1
- package/src/storages/inMemory/InMemoryStorage.ts +5 -2
- package/src/storages/inMemory/InMemoryStorageCS.ts +6 -2
- package/src/storages/inMemory/uniqueKeysCacheInMemory.ts +83 -0
- package/src/storages/inMemory/uniqueKeysCacheInMemoryCS.ts +89 -0
- package/src/storages/types.ts +22 -6
- package/src/sync/submitters/submitterManager.ts +2 -0
- package/src/sync/submitters/telemetrySubmitter.ts +4 -3
- package/src/sync/submitters/types.ts +20 -1
- package/src/sync/submitters/uniqueKeysSubmitter.ts +35 -0
- package/src/trackers/impressionsTracker.ts +12 -35
- package/src/trackers/strategy/strategyDebug.ts +28 -0
- package/src/trackers/strategy/strategyNone.ts +34 -0
- package/src/trackers/strategy/strategyOptimized.ts +42 -0
- package/src/trackers/types.ts +26 -0
- package/src/trackers/uniqueKeysTracker.ts +37 -0
- package/src/types.ts +3 -1
- package/src/utils/constants/index.ts +2 -0
- package/src/utils/settingsValidation/impressionsMode.ts +3 -3
- package/src/utils/settingsValidation/index.ts +4 -0
- package/types/logger/browser/{debugLogger.d.ts → DebugLogger.d.ts} +0 -0
- package/types/logger/browser/{errorLogger.d.ts → ErrorLogger.d.ts} +0 -0
- package/types/logger/browser/{infoLogger.d.ts → InfoLogger.d.ts} +0 -0
- package/types/logger/browser/{warnLogger.d.ts → WarnLogger.d.ts} +0 -0
- package/types/logger/constants.d.ts +1 -0
- package/types/sdkFactory/types.d.ts +4 -2
- package/types/services/types.d.ts +4 -0
- package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +32 -0
- package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +37 -0
- package/types/storages/types.d.ts +14 -4
- package/types/sync/submitters/types.d.ts +18 -1
- package/types/sync/submitters/uniqueKeysSubmitter.d.ts +5 -0
- package/types/trackers/filter/bloomFilter.d.ts +10 -0
- package/types/trackers/filter/dictionaryFilter.d.ts +8 -0
- package/types/trackers/filter/types.d.ts +5 -0
- package/types/trackers/impressionsTracker.d.ts +4 -6
- package/types/trackers/strategy/strategyDebug.d.ts +9 -0
- package/types/trackers/strategy/strategyNone.d.ts +10 -0
- package/types/trackers/strategy/strategyOptimized.d.ts +11 -0
- package/types/trackers/types.d.ts +21 -0
- package/types/trackers/uniqueKeysTracker.d.ts +13 -0
- package/types/types.d.ts +3 -1
- package/types/utils/constants/index.d.ts +2 -0
- package/types/utils/settingsValidation/index.d.ts +1 -0
- package/types/utils/timeTracker/index.d.ts +70 -1
- package/src/logger/.DS_Store +0 -0
- package/types/integrations/ga/GaToSplitPlugin.d.ts +0 -3
- package/types/integrations/ga/SplitToGaPlugin.d.ts +0 -4
- package/types/integrations/ga/autoRequire.d.ts +0 -4
- package/types/logger/codes.d.ts +0 -2
- package/types/logger/codesConstants.d.ts +0 -117
- package/types/logger/codesConstantsBrowser.d.ts +0 -2
- package/types/logger/codesConstantsNode.d.ts +0 -14
- package/types/logger/codesDebug.d.ts +0 -1
- package/types/logger/codesDebugBrowser.d.ts +0 -1
- package/types/logger/codesDebugNode.d.ts +0 -1
- package/types/logger/codesError.d.ts +0 -1
- package/types/logger/codesErrorNode.d.ts +0 -1
- package/types/logger/codesInfo.d.ts +0 -1
- package/types/logger/codesWarn.d.ts +0 -1
- package/types/logger/codesWarnNode.d.ts +0 -1
- package/types/logger/debugLogger.d.ts +0 -2
- package/types/logger/errorLogger.d.ts +0 -2
- package/types/logger/infoLogger.d.ts +0 -2
- package/types/logger/messages/debugBrowser.d.ts +0 -1
- package/types/logger/messages/debugNode.d.ts +0 -1
- package/types/logger/messages/errorNode.d.ts +0 -1
- package/types/logger/messages/warnNode.d.ts +0 -1
- package/types/logger/noopLogger.d.ts +0 -2
- package/types/logger/warnLogger.d.ts +0 -2
- package/types/sdkFactory/userConsentProps.d.ts +0 -6
- package/types/sdkManager/sdkManagerMethod.d.ts +0 -6
- package/types/storages/getRegisteredSegments.d.ts +0 -10
- package/types/storages/inMemory/index.d.ts +0 -10
- package/types/storages/parseSegments.d.ts +0 -6
- package/types/sync/polling/syncTasks/splitsSyncTask.copy.d.ts +0 -35
- package/types/sync/polling/syncTasks/splitsSyncTask.morelikeoriginal.d.ts +0 -35
- package/types/sync/streaming/AuthClient/indexV1.d.ts +0 -12
- package/types/sync/streaming/AuthClient/indexV2.d.ts +0 -8
- package/types/sync/streaming/pushManagerCS.d.ts +0 -1
- package/types/sync/streaming/pushManagerNoUsers.d.ts +0 -13
- package/types/sync/streaming/pushManagerSS.d.ts +0 -1
- package/types/sync/submitters/telemetrySyncTask.d.ts +0 -0
- package/types/sync/syncManagerFromFile.d.ts +0 -2
- package/types/sync/syncManagerFromObject.d.ts +0 -2
- package/types/sync/syncManagerOffline.d.ts +0 -9
- package/types/trackers/telemetryRecorder.d.ts +0 -0
- package/types/utils/EventEmitter.d.ts +0 -4
- package/types/utils/consent.d.ts +0 -2
- package/types/utils/lang/errors.d.ts +0 -10
- package/types/utils/murmur3/commons.d.ts +0 -12
- package/types/utils/settingsValidation/buildMetadata.d.ts +0 -3
- package/types/utils/settingsValidation/localhost/index.d.ts +0 -9
- package/types/utils/settingsValidation/logger.d.ts +0 -11
- package/types/utils/settingsValidation/runtime/browser.d.ts +0 -2
- package/types/utils/settingsValidation/runtime/node.d.ts +0 -2
- package/types/utils/settingsValidation/userConsent.d.ts +0 -5
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
2
|
+
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
3
|
+
import { submitterFactory } from './submitter';
|
|
4
|
+
|
|
5
|
+
const DATA_NAME = 'uniqueKeys';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Submitter that periodically posts impression counts
|
|
9
|
+
*/
|
|
10
|
+
export function uniqueKeysSubmitterFactory(params: ISdkFactoryContextSync) {
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
settings: { log, scheduler: { uniqueKeysRefreshRate }, core: {key}},
|
|
14
|
+
splitApi: { postUniqueKeysBulkCs, postUniqueKeysBulkSs },
|
|
15
|
+
storage: { uniqueKeys }
|
|
16
|
+
} = params;
|
|
17
|
+
|
|
18
|
+
const isClientSide = key !== undefined;
|
|
19
|
+
const postUniqueKeysBulk = isClientSide ? postUniqueKeysBulkCs : postUniqueKeysBulkSs;
|
|
20
|
+
|
|
21
|
+
const syncTask = submitterFactory(log, postUniqueKeysBulk, uniqueKeys!, uniqueKeysRefreshRate, 'unique keys');
|
|
22
|
+
|
|
23
|
+
// register unique keys submitter to be executed when uniqueKeys cache is full
|
|
24
|
+
uniqueKeys!.setOnFullQueueCb(() => {
|
|
25
|
+
if (syncTask.isRunning()) {
|
|
26
|
+
log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
27
|
+
syncTask.execute();
|
|
28
|
+
}
|
|
29
|
+
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
30
|
+
// Data will be sent when submitter is resumed.
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return syncTask;
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { IImpressionsHandler, IImpressionsTracker } from './types';
|
|
3
|
+
import { IImpressionsCacheBase, ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
|
|
4
|
+
import { IImpressionsHandler, IImpressionsTracker, IStrategy } from './types';
|
|
6
5
|
import { SplitIO, ImpressionDTO, ISettings } from '../types';
|
|
7
|
-
import { IImpressionObserver } from './impressionObserver/types';
|
|
8
6
|
import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIONS_LISTENER } from '../logger/constants';
|
|
9
7
|
import { CONSENT_DECLINED, DEDUPED, QUEUED } from '../utils/constants';
|
|
10
8
|
|
|
@@ -15,18 +13,14 @@ import { CONSENT_DECLINED, DEDUPED, QUEUED } from '../utils/constants';
|
|
|
15
13
|
* @param metadata runtime metadata (ip, hostname and version)
|
|
16
14
|
* @param impressionListener optional impression listener
|
|
17
15
|
* @param integrationsManager optional integrations manager
|
|
18
|
-
* @param
|
|
19
|
-
* @param countsCache optional cache to save impressions count. If provided, impressions will be deduped (OPTIMIZED mode)
|
|
16
|
+
* @param strategy strategy for impressions tracking.
|
|
20
17
|
*/
|
|
21
18
|
export function impressionsTrackerFactory(
|
|
22
19
|
settings: ISettings,
|
|
23
20
|
impressionsCache: IImpressionsCacheBase,
|
|
21
|
+
strategy: IStrategy,
|
|
24
22
|
integrationsManager?: IImpressionsHandler,
|
|
25
|
-
|
|
26
|
-
observer?: IImpressionObserver,
|
|
27
|
-
// if countsCache is provided, it implies `isOptimized` flag (i.e., if impressions should be deduped or not)
|
|
28
|
-
countsCache?: IImpressionCountsCacheSync,
|
|
29
|
-
telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync
|
|
23
|
+
telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync,
|
|
30
24
|
): IImpressionsTracker {
|
|
31
25
|
|
|
32
26
|
const { log, impressionListener, runtime: { ip, hostname }, version } = settings;
|
|
@@ -36,27 +30,10 @@ export function impressionsTrackerFactory(
|
|
|
36
30
|
if (settings.userConsent === CONSENT_DECLINED) return;
|
|
37
31
|
|
|
38
32
|
const impressionsCount = impressions.length;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (observer) {
|
|
44
|
-
// Adds previous time if it is enabled
|
|
45
|
-
impression.pt = observer.testAndSet(impression);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const now = Date.now();
|
|
49
|
-
if (countsCache) {
|
|
50
|
-
// Increments impression counter per featureName
|
|
51
|
-
countsCache.track(impression.feature, now, 1);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Checks if the impression should be added in queue to be sent
|
|
55
|
-
if (!countsCache || !impression.pt || impression.pt < truncateTimeFrame(now)) {
|
|
56
|
-
impressionsToStore.push(impression);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
33
|
+
const { impressionsToStore, impressionsToListener, deduped } = strategy.process(impressions);
|
|
34
|
+
|
|
35
|
+
const impressionsToListenerCount = impressionsToListener.length;
|
|
36
|
+
|
|
60
37
|
const res = impressionsCache.track(impressionsToStore);
|
|
61
38
|
|
|
62
39
|
// If we're on an async storage, handle error and log it.
|
|
@@ -71,16 +48,16 @@ export function impressionsTrackerFactory(
|
|
|
71
48
|
// @TODO we are not dropping impressions on full queue yet, so DROPPED stats are not recorded
|
|
72
49
|
if (telemetryCache) {
|
|
73
50
|
(telemetryCache as ITelemetryCacheSync).recordImpressionStats(QUEUED, impressionsToStore.length);
|
|
74
|
-
(telemetryCache as ITelemetryCacheSync).recordImpressionStats(DEDUPED,
|
|
51
|
+
(telemetryCache as ITelemetryCacheSync).recordImpressionStats(DEDUPED, deduped);
|
|
75
52
|
}
|
|
76
53
|
}
|
|
77
54
|
|
|
78
55
|
// @TODO next block might be handled by the integration manager. In that case, the metadata object doesn't need to be passed in the constructor
|
|
79
56
|
if (impressionListener || integrationsManager) {
|
|
80
|
-
for (let i = 0; i <
|
|
57
|
+
for (let i = 0; i < impressionsToListenerCount; i++) {
|
|
81
58
|
const impressionData: SplitIO.ImpressionData = {
|
|
82
59
|
// copy of impression, to avoid unexpected behaviour if modified by integrations or impressionListener
|
|
83
|
-
impression: objectAssign({},
|
|
60
|
+
impression: objectAssign({}, impressionsToListener[i]),
|
|
84
61
|
attributes,
|
|
85
62
|
ip,
|
|
86
63
|
hostname,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ImpressionDTO } from '../../types';
|
|
2
|
+
import { IImpressionObserver } from '../impressionObserver/types';
|
|
3
|
+
import { IStrategy } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Debug strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
|
|
7
|
+
*
|
|
8
|
+
* @param impressionsObserver impression observer. Previous time (pt property) is included in impression instances
|
|
9
|
+
* @returns IStrategyResult
|
|
10
|
+
*/
|
|
11
|
+
export function strategyDebugFactory(
|
|
12
|
+
impressionsObserver: IImpressionObserver
|
|
13
|
+
): IStrategy {
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
process(impressions: ImpressionDTO[]) {
|
|
17
|
+
impressions.forEach((impression) => {
|
|
18
|
+
// Adds previous time if it is enabled
|
|
19
|
+
impression.pt = impressionsObserver.testAndSet(impression);
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
impressionsToStore: impressions,
|
|
23
|
+
impressionsToListener: impressions,
|
|
24
|
+
deduped: 0
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IImpressionCountsCacheSync } from '../../storages/types';
|
|
2
|
+
import { ImpressionDTO } from '../../types';
|
|
3
|
+
import { IStrategy, IUniqueKeysTracker } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* None strategy for impressions tracker.
|
|
7
|
+
*
|
|
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.
|
|
10
|
+
* @returns IStrategyResult
|
|
11
|
+
*/
|
|
12
|
+
export function strategyNoneFactory(
|
|
13
|
+
impressionsCounter: IImpressionCountsCacheSync,
|
|
14
|
+
uniqueKeysTracker: IUniqueKeysTracker
|
|
15
|
+
): IStrategy {
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
process(impressions: ImpressionDTO[]) {
|
|
19
|
+
impressions.forEach((impression) => {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
// Increments impression counter per featureName
|
|
22
|
+
impressionsCounter.track(impression.feature, now, 1);
|
|
23
|
+
// Keep track by unique key
|
|
24
|
+
uniqueKeysTracker.track(impression.keyName, impression.feature);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
impressionsToStore: [],
|
|
29
|
+
impressionsToListener: impressions,
|
|
30
|
+
deduped: 0
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { IImpressionCountsCacheSync } from '../../storages/types';
|
|
2
|
+
import { ImpressionDTO } from '../../types';
|
|
3
|
+
import { truncateTimeFrame } from '../../utils/time';
|
|
4
|
+
import { IImpressionObserver } from '../impressionObserver/types';
|
|
5
|
+
import { IStrategy } from '../types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Optimized strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
|
|
9
|
+
*
|
|
10
|
+
* @param impressionsObserver impression observer. previous time (pt property) is included in impression instances
|
|
11
|
+
* @param impressionsCounter cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
|
|
12
|
+
* @returns IStrategyResult
|
|
13
|
+
*/
|
|
14
|
+
export function strategyOptimizedFactory(
|
|
15
|
+
impressionsObserver: IImpressionObserver,
|
|
16
|
+
impressionsCounter: IImpressionCountsCacheSync,
|
|
17
|
+
): IStrategy {
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
process(impressions: ImpressionDTO[]) {
|
|
21
|
+
const impressionsToStore: ImpressionDTO[] = [];
|
|
22
|
+
impressions.forEach((impression) => {
|
|
23
|
+
impression.pt = impressionsObserver.testAndSet(impression);
|
|
24
|
+
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
|
|
27
|
+
// Increments impression counter per featureName
|
|
28
|
+
impressionsCounter.track(impression.feature, now, 1);
|
|
29
|
+
|
|
30
|
+
// Checks if the impression should be added in queue to be sent
|
|
31
|
+
if (!impression.pt || impression.pt < truncateTimeFrame(now)) {
|
|
32
|
+
impressionsToStore.push(impression);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
impressionsToStore: impressionsToStore,
|
|
37
|
+
impressionsToListener: impressions,
|
|
38
|
+
deduped: impressions.length - impressionsToStore.length
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
package/src/trackers/types.ts
CHANGED
|
@@ -42,3 +42,29 @@ export interface ITelemetryTracker {
|
|
|
42
42
|
*/
|
|
43
43
|
streamingEvent(e: StreamingEventType | AUTH_REJECTION, d?: number): void
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
export interface IFilterAdapter {
|
|
47
|
+
add(key: string, featureName: string): boolean;
|
|
48
|
+
contains(key: string, featureName: string): boolean;
|
|
49
|
+
clear(): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface IImpressionSenderAdapter {
|
|
53
|
+
recordUniqueKeys(data: Object): void;
|
|
54
|
+
recordImpressionCounts(data: Object): void
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Unique keys tracker */
|
|
58
|
+
export interface IUniqueKeysTracker {
|
|
59
|
+
track(key: string, featureName: string): void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface IStrategyResult {
|
|
63
|
+
impressionsToStore: ImpressionDTO[],
|
|
64
|
+
impressionsToListener: ImpressionDTO[],
|
|
65
|
+
deduped: number
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface IStrategy {
|
|
69
|
+
process(impressions: ImpressionDTO[]): IStrategyResult
|
|
70
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { LOG_PREFIX_UNIQUE_KEYS_TRACKER } from '../logger/constants';
|
|
2
|
+
import { ILogger } from '../logger/types';
|
|
3
|
+
import { IUniqueKeysCacheBase } from '../storages/types';
|
|
4
|
+
import { IFilterAdapter, IUniqueKeysTracker } from './types';
|
|
5
|
+
|
|
6
|
+
const noopFilterAdapter = {
|
|
7
|
+
add() {return true;},
|
|
8
|
+
contains() {return true;},
|
|
9
|
+
clear() {}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Trackes uniques keys
|
|
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
|
+
*
|
|
17
|
+
* @param log Logger instance
|
|
18
|
+
* @param filterAdapter filter adapter
|
|
19
|
+
* @param uniqueKeysCache cache to save unique keys
|
|
20
|
+
*/
|
|
21
|
+
export function uniqueKeysTrackerFactory(
|
|
22
|
+
log: ILogger,
|
|
23
|
+
uniqueKeysCache: IUniqueKeysCacheBase,
|
|
24
|
+
filterAdapter: IFilterAdapter = noopFilterAdapter,
|
|
25
|
+
): IUniqueKeysTracker {
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
track(key: string, featureName: string): void {
|
|
29
|
+
if (!filterAdapter.add(key, featureName)) {
|
|
30
|
+
log.debug(`${LOG_PREFIX_UNIQUE_KEYS_TRACKER}The feature ${featureName} and key ${key} exist in the filter`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
uniqueKeysCache.track(key, featureName);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -80,6 +80,8 @@ export interface ISettings {
|
|
|
80
80
|
featuresRefreshRate: number,
|
|
81
81
|
impressionsRefreshRate: number,
|
|
82
82
|
impressionsQueueSize: number,
|
|
83
|
+
uniqueKeysRefreshRate: number,
|
|
84
|
+
uniqueKeysCacheSize: number,
|
|
83
85
|
/**
|
|
84
86
|
* @deprecated
|
|
85
87
|
*/
|
|
@@ -718,7 +720,7 @@ export namespace SplitIO {
|
|
|
718
720
|
* ImpressionsMode type
|
|
719
721
|
* @typedef {string} ImpressionsMode
|
|
720
722
|
*/
|
|
721
|
-
export type ImpressionsMode = 'OPTIMIZED' | 'DEBUG'
|
|
723
|
+
export type ImpressionsMode = 'OPTIMIZED' | 'DEBUG' | 'NONE'
|
|
722
724
|
/**
|
|
723
725
|
* Defines the format of Split data to preload on the factory storage (cache).
|
|
724
726
|
*/
|
|
@@ -19,6 +19,7 @@ export const SPLIT_EVENT = 'EVENT';
|
|
|
19
19
|
// Impression collection modes
|
|
20
20
|
export const DEBUG = 'DEBUG';
|
|
21
21
|
export const OPTIMIZED = 'OPTIMIZED';
|
|
22
|
+
export const NONE = 'NONE';
|
|
22
23
|
|
|
23
24
|
// SDK Modes
|
|
24
25
|
export const LOCALHOST_MODE: SDKMode = 'localhost';
|
|
@@ -49,6 +50,7 @@ export const CONSUMER_PARTIAL_ENUM = 2;
|
|
|
49
50
|
|
|
50
51
|
export const OPTIMIZED_ENUM = 0;
|
|
51
52
|
export const DEBUG_ENUM = 1;
|
|
53
|
+
export const NONE_ENUM = 2;
|
|
52
54
|
|
|
53
55
|
export const SPLITS = 'sp';
|
|
54
56
|
export const IMPRESSIONS = 'im';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
2
2
|
import { ILogger } from '../../logger/types';
|
|
3
3
|
import { SplitIO } from '../../types';
|
|
4
|
-
import { DEBUG, OPTIMIZED } from '../constants';
|
|
4
|
+
import { DEBUG, OPTIMIZED, NONE } from '../constants';
|
|
5
5
|
import { stringToUpperCase } from '../lang';
|
|
6
6
|
|
|
7
7
|
export function validImpressionsMode(log: ILogger, impressionsMode: any): SplitIO.ImpressionsMode {
|
|
8
8
|
impressionsMode = stringToUpperCase(impressionsMode);
|
|
9
9
|
|
|
10
|
-
if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) > -1) return impressionsMode;
|
|
10
|
+
if ([DEBUG, OPTIMIZED, NONE].indexOf(impressionsMode) > -1) return impressionsMode;
|
|
11
11
|
|
|
12
|
-
log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED], OPTIMIZED]);
|
|
12
|
+
log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED, NONE], OPTIMIZED]);
|
|
13
13
|
return OPTIMIZED;
|
|
14
14
|
}
|
|
@@ -36,6 +36,8 @@ export const base = {
|
|
|
36
36
|
telemetryRefreshRate: 3600,
|
|
37
37
|
// publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
|
|
38
38
|
impressionsRefreshRate: 300,
|
|
39
|
+
// publish unique Keys each 900 sec (15 min)
|
|
40
|
+
uniqueKeysRefreshRate: 900,
|
|
39
41
|
// fetch offline changes each 15 sec
|
|
40
42
|
offlineRefreshRate: 15,
|
|
41
43
|
// publish events every 60 seconds after the first flush
|
|
@@ -130,11 +132,13 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
130
132
|
scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
|
|
131
133
|
scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
|
|
132
134
|
scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
|
|
135
|
+
scheduler.uniqueKeysRefreshRate = fromSecondsToMillis(scheduler.uniqueKeysRefreshRate);
|
|
133
136
|
scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
|
|
134
137
|
|
|
135
138
|
// Default impressionsRefreshRate for DEBUG mode is 60 secs
|
|
136
139
|
if (get(config, 'scheduler.impressionsRefreshRate') === undefined && withDefaults.sync.impressionsMode === DEBUG) scheduler.impressionsRefreshRate = 60;
|
|
137
140
|
scheduler.impressionsRefreshRate = fromSecondsToMillis(scheduler.impressionsRefreshRate);
|
|
141
|
+
|
|
138
142
|
|
|
139
143
|
// Log deprecation for old telemetry param
|
|
140
144
|
if (scheduler.metricsRefreshRate) log.warn('`metricsRefreshRate` will be deprecated soon. For configuring telemetry rates, update `telemetryRefreshRate` value in configs');
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -138,4 +138,5 @@ export declare const LOG_PREFIX_SYNC_POLLING: string;
|
|
|
138
138
|
export declare const LOG_PREFIX_SYNC_SUBMITTERS: string;
|
|
139
139
|
export declare const LOG_PREFIX_IMPRESSIONS_TRACKER = "impressions-tracker: ";
|
|
140
140
|
export declare const LOG_PREFIX_EVENTS_TRACKER = "events-tracker: ";
|
|
141
|
+
export declare const LOG_PREFIX_UNIQUE_KEYS_TRACKER = "unique-keys-tracker: ";
|
|
141
142
|
export declare const LOG_PREFIX_CLEANUP = "cleanup: ";
|
|
@@ -6,7 +6,7 @@ import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
|
|
|
6
6
|
import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStorageFactoryParams } from '../storages/types';
|
|
7
7
|
import { ISyncManager } from '../sync/types';
|
|
8
8
|
import { IImpressionObserver } from '../trackers/impressionObserver/types';
|
|
9
|
-
import { IImpressionsTracker, IEventTracker, ITelemetryTracker } from '../trackers/types';
|
|
9
|
+
import { IImpressionsTracker, IEventTracker, ITelemetryTracker, IFilterAdapter, IUniqueKeysTracker } from '../trackers/types';
|
|
10
10
|
import { SplitIO, ISettings, IEventEmitter } from '../types';
|
|
11
11
|
/**
|
|
12
12
|
* Environment related dependencies.
|
|
@@ -42,6 +42,7 @@ export interface ISdkFactoryContext {
|
|
|
42
42
|
eventTracker: IEventTracker;
|
|
43
43
|
telemetryTracker: ITelemetryTracker;
|
|
44
44
|
storage: IStorageSync | IStorageAsync;
|
|
45
|
+
uniqueKeysTracker?: IUniqueKeysTracker;
|
|
45
46
|
signalListener?: ISignalListener;
|
|
46
47
|
splitApi?: ISplitApi;
|
|
47
48
|
syncManager?: ISyncManager;
|
|
@@ -70,11 +71,12 @@ export interface ISdkFactoryParams {
|
|
|
70
71
|
(): SplitIO.ICsClient;
|
|
71
72
|
(key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient;
|
|
72
73
|
} | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient));
|
|
74
|
+
impressionsObserverFactory: () => IImpressionObserver;
|
|
75
|
+
filterAdapterFactory?: () => IFilterAdapter;
|
|
73
76
|
SignalListener?: new (syncManager: ISyncManager | undefined, // Used by NodeSignalListener to flush data, and by BrowserSignalListener to close streaming connection.
|
|
74
77
|
settings: ISettings, // Used by BrowserSignalListener
|
|
75
78
|
storage: IStorageSync | IStorageAsync, // Used by BrowserSignalListener
|
|
76
79
|
serviceApi: ISplitApi | undefined) => ISignalListener;
|
|
77
80
|
integrationsManagerFactory?: (params: IIntegrationFactoryParams) => IIntegrationManager | undefined;
|
|
78
|
-
impressionsObserverFactory?: () => IImpressionObserver;
|
|
79
81
|
extraProps?: (params: ISdkFactoryContext) => object;
|
|
80
82
|
}
|
|
@@ -20,6 +20,8 @@ export declare type IFetchSplitChanges = (since: number, noCache?: boolean, till
|
|
|
20
20
|
export declare type IFetchSegmentChanges = (since: number, segmentName: string, noCache?: boolean, till?: number) => Promise<IResponse>;
|
|
21
21
|
export declare type IFetchMySegments = (userMatchingKey: string, noCache?: boolean) => Promise<IResponse>;
|
|
22
22
|
export declare type IPostEventsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
|
|
23
|
+
export declare type IPostUniqueKeysBulkCs = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
|
|
24
|
+
export declare type IPostUniqueKeysBulkSs = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
|
|
23
25
|
export declare type IPostTestImpressionsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
|
|
24
26
|
export declare type IPostTestImpressionsCount = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
|
|
25
27
|
export declare type IPostMetricsConfig = (body: string) => Promise<IResponse>;
|
|
@@ -32,6 +34,8 @@ export interface ISplitApi {
|
|
|
32
34
|
fetchSegmentChanges: IFetchSegmentChanges;
|
|
33
35
|
fetchMySegments: IFetchMySegments;
|
|
34
36
|
postEventsBulk: IPostEventsBulk;
|
|
37
|
+
postUniqueKeysBulkCs: IPostUniqueKeysBulkCs;
|
|
38
|
+
postUniqueKeysBulkSs: IPostUniqueKeysBulkSs;
|
|
35
39
|
postTestImpressionsBulk: IPostTestImpressionsBulk;
|
|
36
40
|
postTestImpressionsCount: IPostTestImpressionsCount;
|
|
37
41
|
postMetricsConfig: IPostMetricsConfig;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IUniqueKeysCacheBase } from '../types';
|
|
2
|
+
import { UniqueKeysPayloadSs } from '../../sync/submitters/types';
|
|
3
|
+
export declare class UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
4
|
+
private onFullQueue?;
|
|
5
|
+
private readonly maxStorage;
|
|
6
|
+
private uniqueTrackerSize;
|
|
7
|
+
private uniqueKeysTracker;
|
|
8
|
+
constructor(uniqueKeysQueueSize?: number);
|
|
9
|
+
setOnFullQueueCb(cb: () => void): void;
|
|
10
|
+
/**
|
|
11
|
+
* Store unique keys in sequential order
|
|
12
|
+
* key: string = feature name.
|
|
13
|
+
* value: Set<string> = set of unique keys.
|
|
14
|
+
*/
|
|
15
|
+
track(key: string, featureName: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Clear the data stored on the cache.
|
|
18
|
+
*/
|
|
19
|
+
clear(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Pop the collected data, used as payload for posting.
|
|
22
|
+
*/
|
|
23
|
+
pop(): UniqueKeysPayloadSs;
|
|
24
|
+
/**
|
|
25
|
+
* Check if the cache is empty.
|
|
26
|
+
*/
|
|
27
|
+
isEmpty(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Converts `uniqueKeys` data from cache into request payload for SS.
|
|
30
|
+
*/
|
|
31
|
+
private fromUniqueKeysCollector;
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IUniqueKeysCacheBase } from '../types';
|
|
2
|
+
import { UniqueKeysPayloadCs } from '../../sync/submitters/types';
|
|
3
|
+
export declare class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
|
|
4
|
+
private onFullQueue?;
|
|
5
|
+
private readonly maxStorage;
|
|
6
|
+
private uniqueTrackerSize;
|
|
7
|
+
private uniqueKeysTracker;
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
|
|
11
|
+
* Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
|
|
12
|
+
*/
|
|
13
|
+
constructor(uniqueKeysQueueSize?: number);
|
|
14
|
+
setOnFullQueueCb(cb: () => void): void;
|
|
15
|
+
/**
|
|
16
|
+
* Store unique keys in sequential order
|
|
17
|
+
* key: string = key.
|
|
18
|
+
* value: HashSet<string> = set of split names.
|
|
19
|
+
*/
|
|
20
|
+
track(key: string, featureName: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Clear the data stored on the cache.
|
|
23
|
+
*/
|
|
24
|
+
clear(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Pop the collected data, used as payload for posting.
|
|
27
|
+
*/
|
|
28
|
+
pop(): UniqueKeysPayloadCs;
|
|
29
|
+
/**
|
|
30
|
+
* Check if the cache is empty.
|
|
31
|
+
*/
|
|
32
|
+
isEmpty(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Converts `uniqueKeys` data from cache into request payload.
|
|
35
|
+
*/
|
|
36
|
+
private fromUniqueKeysCollector;
|
|
37
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MaybeThenable, IMetadata, ISplitFiltersValidation } from '../dtos/types';
|
|
2
2
|
import { ILogger } from '../logger/types';
|
|
3
|
-
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent } from '../sync/submitters/types';
|
|
3
|
+
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs } from '../sync/submitters/types';
|
|
4
4
|
import { SplitIO, ImpressionDTO, SDKMode } from '../types';
|
|
5
5
|
/**
|
|
6
6
|
* Interface of a pluggable storage wrapper.
|
|
@@ -297,6 +297,13 @@ export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<R
|
|
|
297
297
|
isEmpty(): boolean;
|
|
298
298
|
pop(toMerge?: Record<string, number>): Record<string, number>;
|
|
299
299
|
}
|
|
300
|
+
export interface IUniqueKeysCacheBase {
|
|
301
|
+
track(key: string, value: string): void;
|
|
302
|
+
isEmpty(): boolean;
|
|
303
|
+
pop(): UniqueKeysPayloadSs | UniqueKeysPayloadCs;
|
|
304
|
+
setOnFullQueueCb(cb: () => void): void;
|
|
305
|
+
clear(): void;
|
|
306
|
+
}
|
|
300
307
|
/**
|
|
301
308
|
* Telemetry storage interface for standalone and partial consumer modes.
|
|
302
309
|
* Methods are sync because data is stored in memory.
|
|
@@ -366,28 +373,31 @@ export interface ITelemetryCacheAsync extends ITelemetryEvaluationProducerAsync
|
|
|
366
373
|
/**
|
|
367
374
|
* Storages
|
|
368
375
|
*/
|
|
369
|
-
export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCache extends ISegmentsCacheBase, TImpressionsCache extends IImpressionsCacheBase, TEventsCache extends IEventsCacheBase, TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync> {
|
|
376
|
+
export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCache extends ISegmentsCacheBase, TImpressionsCache extends IImpressionsCacheBase, TEventsCache extends IEventsCacheBase, TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync, TUniqueKeysCache extends IUniqueKeysCacheBase> {
|
|
370
377
|
splits: TSplitsCache;
|
|
371
378
|
segments: TSegmentsCache;
|
|
372
379
|
impressions: TImpressionsCache;
|
|
373
380
|
impressionCounts?: IImpressionCountsCacheSync;
|
|
374
381
|
events: TEventsCache;
|
|
375
382
|
telemetry?: TTelemetryCache;
|
|
383
|
+
uniqueKeys?: TUniqueKeysCache;
|
|
376
384
|
destroy(): void | Promise<void>;
|
|
377
385
|
shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this;
|
|
378
386
|
}
|
|
379
|
-
export interface IStorageSync extends IStorageBase<ISplitsCacheSync, ISegmentsCacheSync, IImpressionsCacheSync, IEventsCacheSync, ITelemetryCacheSync> {
|
|
387
|
+
export interface IStorageSync extends IStorageBase<ISplitsCacheSync, ISegmentsCacheSync, IImpressionsCacheSync, IEventsCacheSync, ITelemetryCacheSync, IUniqueKeysCacheBase> {
|
|
380
388
|
}
|
|
381
|
-
export interface IStorageAsync extends IStorageBase<ISplitsCacheAsync, ISegmentsCacheAsync, IImpressionsCacheAsync | IImpressionsCacheSync, IEventsCacheAsync | IEventsCacheSync, ITelemetryCacheAsync> {
|
|
389
|
+
export interface IStorageAsync extends IStorageBase<ISplitsCacheAsync, ISegmentsCacheAsync, IImpressionsCacheAsync | IImpressionsCacheSync, IEventsCacheAsync | IEventsCacheSync, ITelemetryCacheAsync, IUniqueKeysCacheBase> {
|
|
382
390
|
}
|
|
383
391
|
/** StorageFactory */
|
|
384
392
|
export declare type DataLoader = (storage: IStorageSync, matchingKey: string) => void;
|
|
385
393
|
export interface IStorageFactoryParams {
|
|
386
394
|
log: ILogger;
|
|
387
395
|
impressionsQueueSize?: number;
|
|
396
|
+
uniqueKeysCacheSize?: number;
|
|
388
397
|
eventsQueueSize?: number;
|
|
389
398
|
optimize?: boolean;
|
|
390
399
|
mode: SDKMode;
|
|
400
|
+
impressionsMode?: string;
|
|
391
401
|
matchingKey?: string;
|
|
392
402
|
splitFiltersValidation?: ISplitFiltersValidation;
|
|
393
403
|
onReadyCb: (error?: any) => void;
|
|
@@ -32,6 +32,22 @@ export declare type ImpressionCountsPayload = {
|
|
|
32
32
|
rc: number;
|
|
33
33
|
}[];
|
|
34
34
|
};
|
|
35
|
+
export declare type UniqueKeysPayloadSs = {
|
|
36
|
+
keys: {
|
|
37
|
+
/** Split name */
|
|
38
|
+
f: string;
|
|
39
|
+
/** keyNames */
|
|
40
|
+
ks: string[];
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
43
|
+
export declare type UniqueKeysPayloadCs = {
|
|
44
|
+
keys: {
|
|
45
|
+
/** keyNames */
|
|
46
|
+
k: string;
|
|
47
|
+
/** Split name */
|
|
48
|
+
fs: string[];
|
|
49
|
+
}[];
|
|
50
|
+
};
|
|
35
51
|
export declare type StoredImpressionWithMetadata = {
|
|
36
52
|
/** Metadata */
|
|
37
53
|
m: IMetadata;
|
|
@@ -132,7 +148,8 @@ export declare type CONSUMER_PARTIAL_ENUM = 2;
|
|
|
132
148
|
export declare type OperationMode = STANDALONE_ENUM | CONSUMER_ENUM | CONSUMER_PARTIAL_ENUM;
|
|
133
149
|
export declare type OPTIMIZED_ENUM = 0;
|
|
134
150
|
export declare type DEBUG_ENUM = 1;
|
|
135
|
-
export declare type
|
|
151
|
+
export declare type NONE_ENUM = 2;
|
|
152
|
+
export declare type ImpressionsMode = OPTIMIZED_ENUM | DEBUG_ENUM | NONE_ENUM;
|
|
136
153
|
export declare type RefreshRates = {
|
|
137
154
|
sp: number;
|
|
138
155
|
se?: number;
|
|
@@ -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
|
+
}
|