@splitsoftware/splitio-commons 0.1.1-rc.20 → 1.0.1-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/CHANGES.txt +9 -0
- package/README.md +3 -2
- package/cjs/listeners/browser.js +3 -1
- package/cjs/logger/constants.js +4 -4
- package/cjs/logger/messages/error.js +2 -1
- package/cjs/logger/messages/warn.js +0 -1
- package/cjs/sdkClient/sdkClient.js +4 -4
- package/cjs/sdkClient/sdkClientMethodCS.js +16 -5
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +17 -6
- package/cjs/sdkFactory/index.js +6 -3
- package/cjs/storages/inMemory/InMemoryStorage.js +0 -3
- package/cjs/storages/inRedis/index.js +1 -2
- package/cjs/storages/pluggable/SplitsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/inMemoryWrapper.js +19 -5
- package/cjs/storages/pluggable/index.js +38 -15
- package/cjs/storages/pluggable/wrapperAdapter.js +3 -3
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +0 -1
- package/cjs/sync/submitters/submitterManager.js +19 -0
- package/cjs/sync/syncManagerOnline.js +20 -26
- package/cjs/trackers/impressionObserver/utils.js +1 -1
- package/cjs/utils/constants/index.js +3 -2
- package/cjs/utils/settingsValidation/mode.js +1 -1
- package/cjs/utils/settingsValidation/storage/storageCS.js +17 -3
- package/esm/listeners/browser.js +3 -1
- package/esm/logger/constants.js +3 -3
- package/esm/logger/messages/error.js +2 -1
- package/esm/logger/messages/warn.js +0 -1
- package/esm/sdkClient/sdkClient.js +5 -5
- package/esm/sdkClient/sdkClientMethodCS.js +16 -5
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +17 -6
- package/esm/sdkFactory/index.js +6 -3
- package/esm/storages/inMemory/InMemoryStorage.js +0 -3
- package/esm/storages/inRedis/index.js +1 -2
- package/esm/storages/pluggable/SplitsCachePluggable.js +1 -1
- package/esm/storages/pluggable/inMemoryWrapper.js +19 -5
- package/esm/storages/pluggable/index.js +40 -16
- package/esm/storages/pluggable/wrapperAdapter.js +3 -3
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +0 -1
- package/esm/sync/submitters/submitterManager.js +15 -0
- package/esm/sync/syncManagerOnline.js +20 -26
- package/esm/trackers/impressionObserver/utils.js +2 -2
- package/esm/utils/constants/index.js +2 -1
- package/esm/utils/settingsValidation/mode.js +2 -2
- package/esm/utils/settingsValidation/storage/storageCS.js +19 -5
- package/package.json +1 -1
- package/src/listeners/browser.ts +3 -1
- package/src/logger/constants.ts +3 -3
- package/src/logger/messages/error.ts +2 -1
- package/src/logger/messages/warn.ts +0 -1
- package/src/sdkClient/sdkClient.ts +6 -6
- package/src/sdkClient/sdkClientMethodCS.ts +14 -4
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +15 -5
- package/src/sdkFactory/index.ts +7 -3
- package/src/services/splitApi.ts +4 -1
- package/src/storages/inLocalStorage/index.ts +2 -2
- package/src/storages/inMemory/InMemoryStorage.ts +0 -3
- package/src/storages/inMemory/InMemoryStorageCS.ts +2 -2
- package/src/storages/inRedis/index.ts +1 -1
- package/src/storages/pluggable/EventsCachePluggable.ts +3 -3
- package/src/storages/pluggable/ImpressionsCachePluggable.ts +3 -3
- package/src/storages/pluggable/SegmentsCachePluggable.ts +3 -3
- package/src/storages/pluggable/SplitsCachePluggable.ts +4 -4
- package/src/storages/pluggable/inMemoryWrapper.ts +20 -6
- package/src/storages/pluggable/index.ts +46 -16
- package/src/storages/pluggable/wrapperAdapter.ts +5 -5
- package/src/storages/types.ts +24 -24
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +0 -1
- package/src/sync/submitters/submitterManager.ts +22 -0
- package/src/sync/syncManagerOnline.ts +26 -32
- package/src/sync/types.ts +1 -1
- package/src/trackers/impressionObserver/ImpressionObserver.ts +1 -1
- package/src/trackers/impressionObserver/utils.ts +2 -2
- package/src/types.ts +5 -5
- package/src/utils/constants/index.ts +6 -4
- package/src/utils/settingsValidation/mode.ts +2 -2
- package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
- package/types/logger/constants.d.ts +3 -3
- package/types/services/splitApi.d.ts +1 -1
- package/types/storages/inMemory/InMemoryStorageCS.d.ts +2 -2
- package/types/storages/pluggable/EventsCachePluggable.d.ts +2 -2
- package/types/storages/pluggable/ImpressionsCachePluggable.d.ts +2 -2
- package/types/storages/pluggable/SegmentsCachePluggable.d.ts +5 -5
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +3 -3
- package/types/storages/pluggable/inMemoryWrapper.d.ts +6 -3
- package/types/storages/pluggable/index.d.ts +2 -2
- package/types/storages/pluggable/wrapperAdapter.d.ts +4 -4
- package/types/storages/types.d.ts +21 -22
- package/types/sync/submitters/submitterManager.d.ts +4 -0
- package/types/sync/syncManagerOnline.d.ts +1 -1
- package/types/sync/types.d.ts +1 -1
- package/types/trackers/impressionObserver/ImpressionObserver.d.ts +1 -1
- package/types/types.d.ts +5 -5
- package/types/utils/constants/index.d.ts +6 -4
- package/types/utils/settingsValidation/storage/storageCS.d.ts +6 -4
package/src/storages/types.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { MaybeThenable, IMetadata, ISplitFiltersValidation } from '../dtos/types';
|
|
2
2
|
import { ILogger } from '../logger/types';
|
|
3
3
|
import { StoredEventWithMetadata, StoredImpressionWithMetadata } from '../sync/submitters/types';
|
|
4
|
-
import { SplitIO, ImpressionDTO } from '../types';
|
|
4
|
+
import { SplitIO, ImpressionDTO, SDKMode } from '../types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Interface of a
|
|
7
|
+
* Interface of a pluggable storage wrapper.
|
|
8
8
|
*/
|
|
9
|
-
export interface
|
|
9
|
+
export interface IPluggableStorageWrapper {
|
|
10
10
|
|
|
11
11
|
/** Key-Value operations */
|
|
12
12
|
|
|
@@ -28,7 +28,7 @@ export interface ICustomStorageWrapper {
|
|
|
28
28
|
* @returns {Promise<void>} A promise that resolves if the operation success, whether the key was added or updated.
|
|
29
29
|
* The promise rejects if the operation fails.
|
|
30
30
|
*/
|
|
31
|
-
set: (key: string, value: string) => Promise<
|
|
31
|
+
set: (key: string, value: string) => Promise<boolean | void>
|
|
32
32
|
/**
|
|
33
33
|
* Add or update an item with a specified `key` and `value`.
|
|
34
34
|
*
|
|
@@ -47,7 +47,7 @@ export interface ICustomStorageWrapper {
|
|
|
47
47
|
* @returns {Promise<void>} A promise that resolves if the operation success, whether the key existed and was removed or it didn't exist.
|
|
48
48
|
* The promise rejects if the operation fails, for example, if there is a connection error.
|
|
49
49
|
*/
|
|
50
|
-
del: (key: string) => Promise<
|
|
50
|
+
del: (key: string) => Promise<boolean | void>
|
|
51
51
|
/**
|
|
52
52
|
* Returns all keys matching the given prefix.
|
|
53
53
|
*
|
|
@@ -140,20 +140,20 @@ export interface ICustomStorageWrapper {
|
|
|
140
140
|
* @function addItems
|
|
141
141
|
* @param {string} key Set key
|
|
142
142
|
* @param {string} items Items to add
|
|
143
|
-
* @returns {Promise<void>} A promise that resolves if the operation success.
|
|
143
|
+
* @returns {Promise<boolean | void>} A promise that resolves if the operation success.
|
|
144
144
|
* The promise rejects if the operation fails, for example, if there is a connection error or the key holds a value that is not a set.
|
|
145
145
|
*/
|
|
146
|
-
addItems: (key: string, items: string[]) => Promise<void>
|
|
146
|
+
addItems: (key: string, items: string[]) => Promise<boolean | void>
|
|
147
147
|
/**
|
|
148
148
|
* Remove the specified `items` from the set stored at `key`. Those items that are not part of the set are ignored.
|
|
149
149
|
*
|
|
150
150
|
* @function removeItems
|
|
151
151
|
* @param {string} key Set key
|
|
152
152
|
* @param {string} items Items to remove
|
|
153
|
-
* @returns {Promise<void>} A promise that resolves if the operation success. If key does not exist, the promise also resolves.
|
|
153
|
+
* @returns {Promise<boolean | void>} A promise that resolves if the operation success. If key does not exist, the promise also resolves.
|
|
154
154
|
* The promise rejects if the operation fails, for example, if there is a connection error or the key holds a value that is not a set.
|
|
155
155
|
*/
|
|
156
|
-
removeItems: (key: string, items: string[]) => Promise<void>
|
|
156
|
+
removeItems: (key: string, items: string[]) => Promise<boolean | void>
|
|
157
157
|
/**
|
|
158
158
|
* Returns all the items of the `key` set.
|
|
159
159
|
*
|
|
@@ -169,7 +169,7 @@ export interface ICustomStorageWrapper {
|
|
|
169
169
|
/**
|
|
170
170
|
* Connects to the underlying storage.
|
|
171
171
|
* It is meant for storages that requires to be connected to some database or server. Otherwise it can just return a resolved promise.
|
|
172
|
-
* Note: will be called once on SplitFactory instantiation.
|
|
172
|
+
* Note: will be called once on SplitFactory instantiation and once per each shared client instantiation.
|
|
173
173
|
*
|
|
174
174
|
* @function connect
|
|
175
175
|
* @returns {Promise<void>} A promise that resolves when the wrapper successfully connect to the underlying storage.
|
|
@@ -177,15 +177,15 @@ export interface ICustomStorageWrapper {
|
|
|
177
177
|
*/
|
|
178
178
|
connect: () => Promise<void>
|
|
179
179
|
/**
|
|
180
|
-
* Disconnects the underlying storage.
|
|
180
|
+
* Disconnects from the underlying storage.
|
|
181
181
|
* It is meant for storages that requires to be closed, in order to release resources. Otherwise it can just return a resolved promise.
|
|
182
|
-
* Note: will be called once on SplitFactory client destroy.
|
|
182
|
+
* Note: will be called once on SplitFactory main client destroy.
|
|
183
183
|
*
|
|
184
|
-
* @function
|
|
184
|
+
* @function disconnect
|
|
185
185
|
* @returns {Promise<void>} A promise that resolves when the operation ends.
|
|
186
186
|
* The promise never rejects.
|
|
187
187
|
*/
|
|
188
|
-
|
|
188
|
+
disconnect: () => Promise<void>
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/** Splits cache */
|
|
@@ -271,7 +271,7 @@ export interface ISegmentsCacheSync extends ISegmentsCacheBase {
|
|
|
271
271
|
export interface ISegmentsCacheAsync extends ISegmentsCacheBase {
|
|
272
272
|
addToSegment(name: string, segmentKeys: string[]): Promise<boolean | void>
|
|
273
273
|
removeFromSegment(name: string, segmentKeys: string[]): Promise<boolean | void>
|
|
274
|
-
isInSegment(name: string, key
|
|
274
|
+
isInSegment(name: string, key: string): Promise<boolean>
|
|
275
275
|
registerSegments(names: string[]): Promise<boolean | void>
|
|
276
276
|
getRegisteredSegments(): Promise<string[]>
|
|
277
277
|
setChangeNumber(name: string, changeNumber: number): Promise<boolean | void>
|
|
@@ -395,7 +395,8 @@ export interface IStorageBase<
|
|
|
395
395
|
events: TEventsCache,
|
|
396
396
|
latencies?: TLatenciesCache,
|
|
397
397
|
counts?: TCountsCache,
|
|
398
|
-
destroy(): void
|
|
398
|
+
destroy(): void | Promise<void>,
|
|
399
|
+
shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this
|
|
399
400
|
}
|
|
400
401
|
|
|
401
402
|
export type IStorageSync = IStorageBase<
|
|
@@ -407,15 +408,11 @@ export type IStorageSync = IStorageBase<
|
|
|
407
408
|
ICountsCacheSync
|
|
408
409
|
>
|
|
409
410
|
|
|
410
|
-
export interface IStorageSyncCS extends IStorageSync {
|
|
411
|
-
shared(matchingKey: string): IStorageSync
|
|
412
|
-
}
|
|
413
|
-
|
|
414
411
|
export type IStorageAsync = IStorageBase<
|
|
415
412
|
ISplitsCacheAsync,
|
|
416
413
|
ISegmentsCacheAsync,
|
|
417
|
-
IImpressionsCacheAsync,
|
|
418
|
-
IEventsCacheAsync,
|
|
414
|
+
IImpressionsCacheAsync | IImpressionsCacheSync,
|
|
415
|
+
IEventsCacheAsync | IEventsCacheSync,
|
|
419
416
|
ILatenciesCacheAsync,
|
|
420
417
|
ICountsCacheAsync
|
|
421
418
|
>
|
|
@@ -433,14 +430,17 @@ export interface IStorageFactoryParams {
|
|
|
433
430
|
matchingKey?: string, /* undefined on server-side SDKs */
|
|
434
431
|
splitFiltersValidation?: ISplitFiltersValidation,
|
|
435
432
|
|
|
433
|
+
// ATM, only used by PluggableStorage
|
|
434
|
+
mode?: SDKMode,
|
|
435
|
+
|
|
436
436
|
// This callback is invoked when the storage is ready to be used. Error-first callback style: if an error is passed,
|
|
437
437
|
// it means that the storge fail to connect and shouldn't be used.
|
|
438
438
|
// It is meant for emitting SDK_READY event in consumer mode, and for synchronizer to wait before using the storage.
|
|
439
|
-
onReadyCb
|
|
439
|
+
onReadyCb: (error?: any) => void,
|
|
440
440
|
metadata: IMetadata,
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
-
export type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS' | '
|
|
443
|
+
export type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS' | 'PLUGGABLE';
|
|
444
444
|
|
|
445
445
|
export type IStorageSyncFactory = {
|
|
446
446
|
type: StorageType,
|
|
@@ -38,7 +38,7 @@ export function mySegmentsUpdaterFactory(
|
|
|
38
38
|
// mySegmentsPromise = tracker.start(tracker.TaskNames.MY_SEGMENTS_FETCH, startingUp ? metricCollectors : false, mySegmentsPromise);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// @TODO if allowing
|
|
41
|
+
// @TODO if allowing pluggable storages, handle async execution
|
|
42
42
|
function updateSegments(segmentsData: SegmentsData) {
|
|
43
43
|
|
|
44
44
|
let shouldNotifyUpdate;
|
|
@@ -83,7 +83,6 @@ export default class SplitsUpdateWorker implements IUpdateWorker {
|
|
|
83
83
|
* @param {string} defaultTreatment default treatment value
|
|
84
84
|
*/
|
|
85
85
|
killSplit({ changeNumber, splitName, defaultTreatment }: ISplitKillData) {
|
|
86
|
-
// @TODO handle retry due to errors in storage, once we allow the definition of custom async storages
|
|
87
86
|
if (this.splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
|
|
88
87
|
// trigger an SDK_UPDATE if Split was killed locally
|
|
89
88
|
this.splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, true);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { syncTaskComposite } from '../syncTaskComposite';
|
|
2
|
+
import { eventsSyncTaskFactory } from './eventsSyncTask';
|
|
3
|
+
import { impressionsSyncTaskFactory } from './impressionsSyncTask';
|
|
4
|
+
import { impressionCountsSyncTaskFactory } from './impressionCountsSyncTask';
|
|
5
|
+
import { ISplitApi } from '../../services/types';
|
|
6
|
+
import { IStorageSync } from '../../storages/types';
|
|
7
|
+
import { ISettings } from '../../types';
|
|
8
|
+
|
|
9
|
+
export function submitterManagerFactory(
|
|
10
|
+
settings: ISettings,
|
|
11
|
+
storage: IStorageSync,
|
|
12
|
+
splitApi: ISplitApi,
|
|
13
|
+
) {
|
|
14
|
+
const log = settings.log;
|
|
15
|
+
const submitters = [
|
|
16
|
+
impressionsSyncTaskFactory(log, splitApi.postTestImpressionsBulk, storage.impressions, settings.scheduler.impressionsRefreshRate, settings.core.labelsEnabled),
|
|
17
|
+
eventsSyncTaskFactory(log, splitApi.postEventsBulk, storage.events, settings.scheduler.eventsPushRate, settings.startup.eventsFirstPushWindow)
|
|
18
|
+
// @TODO add telemetry submitter
|
|
19
|
+
];
|
|
20
|
+
if (storage.impressionCounts) submitters.push(impressionCountsSyncTaskFactory(log, splitApi.postTestImpressionsCount, storage.impressionCounts));
|
|
21
|
+
return syncTaskComposite(submitters);
|
|
22
|
+
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { eventsSyncTaskFactory } from './submitters/eventsSyncTask';
|
|
4
|
-
import { impressionsSyncTaskFactory } from './submitters/impressionsSyncTask';
|
|
5
|
-
import { impressionCountsSyncTaskFactory } from './submitters/impressionCountsSyncTask';
|
|
1
|
+
import { ISyncManagerCS, ISyncManagerFactoryParams } from './types';
|
|
2
|
+
import { submitterManagerFactory } from './submitters/submitterManager';
|
|
6
3
|
import { IReadinessManager } from '../readiness/types';
|
|
7
4
|
import { IStorageSync } from '../storages/types';
|
|
8
5
|
import { IPushManagerFactoryParams, IPushManager, IPushManagerCS } from './streaming/types';
|
|
@@ -19,7 +16,7 @@ import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '..
|
|
|
19
16
|
* @param pushManagerFactory optional to build a SyncManager with or without streaming support
|
|
20
17
|
*/
|
|
21
18
|
export function syncManagerOnlineFactory(
|
|
22
|
-
pollingManagerFactory
|
|
19
|
+
pollingManagerFactory?: (...args: IPollingManagerFactoryParams) => IPollingManager,
|
|
23
20
|
pushManagerFactory?: (...args: IPushManagerFactoryParams) => IPushManager | undefined
|
|
24
21
|
): (params: ISyncManagerFactoryParams) => ISyncManagerCS {
|
|
25
22
|
|
|
@@ -37,30 +34,24 @@ export function syncManagerOnlineFactory(
|
|
|
37
34
|
const log = settings.log;
|
|
38
35
|
|
|
39
36
|
/** Polling Manager */
|
|
40
|
-
const pollingManager = pollingManagerFactory(splitApi, storage, readiness, settings);
|
|
37
|
+
const pollingManager = pollingManagerFactory && pollingManagerFactory(splitApi, storage, readiness, settings);
|
|
41
38
|
|
|
42
39
|
/** Push Manager */
|
|
43
|
-
const pushManager = settings.streamingEnabled && pushManagerFactory ?
|
|
40
|
+
const pushManager = settings.streamingEnabled && pollingManager && pushManagerFactory ?
|
|
44
41
|
pushManagerFactory(pollingManager, storage, readiness, splitApi.fetchAuth, platform, settings) :
|
|
45
42
|
undefined;
|
|
46
43
|
|
|
47
44
|
/** Submitter Manager */
|
|
48
|
-
// It is not inyected
|
|
49
|
-
const
|
|
50
|
-
impressionsSyncTaskFactory(log, splitApi.postTestImpressionsBulk, storage.impressions, settings.scheduler.impressionsRefreshRate, settings.core.labelsEnabled),
|
|
51
|
-
eventsSyncTaskFactory(log, splitApi.postEventsBulk, storage.events, settings.scheduler.eventsPushRate, settings.startup.eventsFirstPushWindow)
|
|
52
|
-
// @TODO add telemetry submitter
|
|
53
|
-
];
|
|
54
|
-
if (storage.impressionCounts) submitters.push(impressionCountsSyncTaskFactory(log, splitApi.postTestImpressionsCount, storage.impressionCounts));
|
|
55
|
-
const submitter = syncTaskComposite(submitters);
|
|
45
|
+
// It is not inyected as push and polling managers, because at the moment it is required
|
|
46
|
+
const submitter = submitterManagerFactory(settings, storage, splitApi);
|
|
56
47
|
|
|
57
48
|
|
|
58
49
|
/** Sync Manager logic */
|
|
59
50
|
|
|
60
51
|
function startPolling() {
|
|
61
|
-
if (!pollingManager
|
|
52
|
+
if (!pollingManager!.isRunning()) {
|
|
62
53
|
log.info(SYNC_START_POLLING);
|
|
63
|
-
pollingManager
|
|
54
|
+
pollingManager!.start();
|
|
64
55
|
} else {
|
|
65
56
|
log.info(SYNC_CONTINUE_POLLING);
|
|
66
57
|
}
|
|
@@ -69,10 +60,10 @@ export function syncManagerOnlineFactory(
|
|
|
69
60
|
function stopPollingAndSyncAll() {
|
|
70
61
|
log.info(SYNC_STOP_POLLING);
|
|
71
62
|
// if polling, stop
|
|
72
|
-
if (pollingManager
|
|
63
|
+
if (pollingManager!.isRunning()) pollingManager!.stop();
|
|
73
64
|
|
|
74
65
|
// fetch splits and segments. There is no need to catch this promise (it is always resolved)
|
|
75
|
-
pollingManager
|
|
66
|
+
pollingManager!.syncAll();
|
|
76
67
|
}
|
|
77
68
|
|
|
78
69
|
if (pushManager) {
|
|
@@ -91,15 +82,17 @@ export function syncManagerOnlineFactory(
|
|
|
91
82
|
*/
|
|
92
83
|
start() {
|
|
93
84
|
// start syncing splits and segments
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
85
|
+
if (pollingManager) {
|
|
86
|
+
if (pushManager) {
|
|
87
|
+
// Doesn't call `syncAll` when the syncManager is resuming
|
|
88
|
+
if (startFirstTime) {
|
|
89
|
+
pollingManager.syncAll();
|
|
90
|
+
startFirstTime = false;
|
|
91
|
+
}
|
|
92
|
+
pushManager.start();
|
|
93
|
+
} else {
|
|
94
|
+
pollingManager.start();
|
|
99
95
|
}
|
|
100
|
-
pushManager.start();
|
|
101
|
-
} else {
|
|
102
|
-
pollingManager.start();
|
|
103
96
|
}
|
|
104
97
|
|
|
105
98
|
// start periodic data recording (events, impressions, telemetry).
|
|
@@ -113,7 +106,7 @@ export function syncManagerOnlineFactory(
|
|
|
113
106
|
stop() {
|
|
114
107
|
// stop syncing
|
|
115
108
|
if (pushManager) pushManager.stop();
|
|
116
|
-
if (pollingManager.isRunning()) pollingManager.stop();
|
|
109
|
+
if (pollingManager && pollingManager.isRunning()) pollingManager.stop();
|
|
117
110
|
|
|
118
111
|
// stop periodic data recording (events, impressions, telemetry).
|
|
119
112
|
if (submitter) submitter.stop();
|
|
@@ -130,8 +123,9 @@ export function syncManagerOnlineFactory(
|
|
|
130
123
|
},
|
|
131
124
|
|
|
132
125
|
// [Only used for client-side]
|
|
133
|
-
//
|
|
134
|
-
shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync)
|
|
126
|
+
// If polling and push managers are defined (standalone mode), they implement the interfaces for client-side
|
|
127
|
+
shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync) {
|
|
128
|
+
if (!pollingManager) return;
|
|
135
129
|
|
|
136
130
|
const mySegmentsSyncTask = (pollingManager as IPollingManagerCS).add(matchingKey, readinessManager, storage);
|
|
137
131
|
|
|
@@ -139,7 +133,7 @@ export function syncManagerOnlineFactory(
|
|
|
139
133
|
isRunning: mySegmentsSyncTask.isRunning,
|
|
140
134
|
start() {
|
|
141
135
|
if (pushManager) {
|
|
142
|
-
if (pollingManager
|
|
136
|
+
if (pollingManager!.isRunning()) {
|
|
143
137
|
// if doing polling, we must start the periodic fetch of data
|
|
144
138
|
if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
|
|
145
139
|
} else {
|
package/src/sync/types.ts
CHANGED
|
@@ -47,7 +47,7 @@ export interface ISyncManager extends ITask {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export interface ISyncManagerCS extends ISyncManager {
|
|
50
|
-
shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync): ISyncManager
|
|
50
|
+
shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync): ISyncManager | undefined
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface ISyncManagerFactoryParams {
|
|
@@ -2,7 +2,7 @@ import { ImpressionDTO } from '../../types';
|
|
|
2
2
|
import LRUCache from '../../utils/LRUCache';
|
|
3
3
|
import { IImpressionObserver } from './types';
|
|
4
4
|
|
|
5
|
-
export default class ImpressionObserver<K extends string | number> implements IImpressionObserver {
|
|
5
|
+
export default class ImpressionObserver<K extends string | number = string> implements IImpressionObserver {
|
|
6
6
|
private cache: LRUCache<K, number>;
|
|
7
7
|
private hasher: (impression: ImpressionDTO) => K;
|
|
8
8
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
|
|
1
|
+
import { CONSUMER_PARTIAL_MODE, OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
|
|
2
2
|
import { ISettings } from '../../types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Checks if impressions previous time should be added or not.
|
|
6
6
|
*/
|
|
7
7
|
export function shouldAddPt(settings: ISettings) {
|
|
8
|
-
return [PRODUCER_MODE, STANDALONE_MODE].indexOf(settings.mode) > -1 ? true : false;
|
|
8
|
+
return [PRODUCER_MODE, STANDALONE_MODE, CONSUMER_PARTIAL_MODE].indexOf(settings.mode) > -1 ? true : false;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
package/src/types.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { IIntegration, IIntegrationFactoryParams } from './integrations/types';
|
|
|
3
3
|
import { ILogger } from './logger/types';
|
|
4
4
|
/* eslint-disable no-use-before-define */
|
|
5
5
|
|
|
6
|
-
import { IStorageFactoryParams,
|
|
6
|
+
import { IStorageFactoryParams, IStorageSync, IStorageAsync, IStorageSyncFactory, IStorageAsyncFactory } from './storages/types';
|
|
7
7
|
import { ISyncManagerFactoryParams, ISyncManagerCS } from './sync/types';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -52,7 +52,7 @@ type EventConsts = {
|
|
|
52
52
|
* SDK Modes.
|
|
53
53
|
* @typedef {string} SDKMode
|
|
54
54
|
*/
|
|
55
|
-
export type SDKMode = 'standalone' | 'consumer' | 'localhost';
|
|
55
|
+
export type SDKMode = 'standalone' | 'consumer' | 'localhost' | 'consumer_partial';
|
|
56
56
|
/**
|
|
57
57
|
* Settings interface. This is a representation of the settings the SDK expose, that's why
|
|
58
58
|
* most of it's props are readonly. Only features should be rewritten when localhost mode is active.
|
|
@@ -85,7 +85,7 @@ export interface ISettings {
|
|
|
85
85
|
retriesOnFailureBeforeReady: number,
|
|
86
86
|
eventsFirstPushWindow: number
|
|
87
87
|
},
|
|
88
|
-
readonly storage: IStorageSyncFactory,
|
|
88
|
+
readonly storage: IStorageSyncFactory | IStorageAsyncFactory,
|
|
89
89
|
readonly integrations?: Array<(params: IIntegrationFactoryParams) => IIntegration | void>,
|
|
90
90
|
readonly urls: {
|
|
91
91
|
events: string,
|
|
@@ -93,7 +93,7 @@ export interface ISettings {
|
|
|
93
93
|
auth: string,
|
|
94
94
|
streaming: string
|
|
95
95
|
},
|
|
96
|
-
readonly debug: boolean | LogLevel,
|
|
96
|
+
readonly debug: boolean | LogLevel | ILogger,
|
|
97
97
|
readonly version: string,
|
|
98
98
|
features: SplitIO.MockedFeaturesFilePath | SplitIO.MockedFeaturesMap,
|
|
99
99
|
readonly streamingEnabled: boolean,
|
|
@@ -841,7 +841,7 @@ export namespace SplitIO {
|
|
|
841
841
|
* Defines which kind of storage we should instanciate.
|
|
842
842
|
* @property {Object} storage
|
|
843
843
|
*/
|
|
844
|
-
storage?: (params: IStorageFactoryParams) =>
|
|
844
|
+
storage?: (params: IStorageFactoryParams) => IStorageSync | IStorageAsync,
|
|
845
845
|
/**
|
|
846
846
|
* List of URLs that the SDK will use as base for it's synchronization functionalities, applicable only when running as standalone.
|
|
847
847
|
* Do not change these settings unless you're working an advanced use case, like connecting to the Split proxy.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StorageType } from '../../storages/types';
|
|
2
|
+
import { SDKMode } from '../../types';
|
|
2
3
|
|
|
3
4
|
// Special treatments
|
|
4
5
|
export const CONTROL = 'control';
|
|
@@ -20,13 +21,14 @@ export const DEBUG = 'DEBUG';
|
|
|
20
21
|
export const OPTIMIZED = 'OPTIMIZED';
|
|
21
22
|
|
|
22
23
|
// SDK Modes
|
|
23
|
-
export const LOCALHOST_MODE = 'localhost';
|
|
24
|
-
export const STANDALONE_MODE = 'standalone';
|
|
24
|
+
export const LOCALHOST_MODE: SDKMode = 'localhost';
|
|
25
|
+
export const STANDALONE_MODE: SDKMode = 'standalone';
|
|
25
26
|
export const PRODUCER_MODE = 'producer';
|
|
26
|
-
export const CONSUMER_MODE = 'consumer';
|
|
27
|
+
export const CONSUMER_MODE: SDKMode = 'consumer';
|
|
28
|
+
export const CONSUMER_PARTIAL_MODE: SDKMode = 'consumer_partial';
|
|
27
29
|
|
|
28
30
|
// Storage types
|
|
29
31
|
export const STORAGE_MEMORY: StorageType = 'MEMORY';
|
|
30
32
|
export const STORAGE_LOCALSTORAGE: StorageType = 'LOCALSTORAGE';
|
|
31
33
|
export const STORAGE_REDIS: StorageType = 'REDIS';
|
|
32
|
-
export const
|
|
34
|
+
export const STORAGE_PLUGGABLE: StorageType = 'PLUGGABLE';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { LOCALHOST_MODE, STANDALONE_MODE, PRODUCER_MODE, CONSUMER_MODE } from '../constants';
|
|
1
|
+
import { LOCALHOST_MODE, STANDALONE_MODE, PRODUCER_MODE, CONSUMER_MODE, CONSUMER_PARTIAL_MODE } from '../constants';
|
|
2
2
|
|
|
3
3
|
export default function mode(key: string, mode: string) {
|
|
4
4
|
// Leaving the comparison as is, in case we change the mode name but not the setting.
|
|
5
5
|
if (key === 'localhost') return LOCALHOST_MODE;
|
|
6
6
|
|
|
7
|
-
if ([STANDALONE_MODE, PRODUCER_MODE, CONSUMER_MODE].indexOf(mode) === -1) throw Error('Invalid mode provided');
|
|
7
|
+
if ([STANDALONE_MODE, PRODUCER_MODE, CONSUMER_MODE, CONSUMER_PARTIAL_MODE].indexOf(mode) === -1) throw Error('Invalid mode provided');
|
|
8
8
|
|
|
9
9
|
return mode;
|
|
10
10
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { InMemoryStorageCSFactory } from '../../../storages/inMemory/InMemoryStorageCS';
|
|
2
2
|
import { ISettings, SDKMode } from '../../../types';
|
|
3
3
|
import { ILogger } from '../../../logger/types';
|
|
4
|
-
import {
|
|
5
|
-
import { LOCALHOST_MODE, STORAGE_LOCALSTORAGE, STORAGE_MEMORY } from '../../../utils/constants';
|
|
6
|
-
import { IStorageFactoryParams,
|
|
4
|
+
import { ERROR_STORAGE_INVALID } from '../../../logger/constants';
|
|
5
|
+
import { LOCALHOST_MODE, STANDALONE_MODE, STORAGE_PLUGGABLE, STORAGE_LOCALSTORAGE, STORAGE_MEMORY } from '../../../utils/constants';
|
|
6
|
+
import { IStorageFactoryParams, IStorageSync } from '../../../storages/types';
|
|
7
7
|
|
|
8
|
-
export function __InLocalStorageMockFactory(params: IStorageFactoryParams):
|
|
8
|
+
export function __InLocalStorageMockFactory(params: IStorageFactoryParams): IStorageSync {
|
|
9
9
|
const result = InMemoryStorageCSFactory(params);
|
|
10
10
|
result.splits.checkCache = () => true; // to emit SDK_READY_FROM_CACHE
|
|
11
11
|
return result;
|
|
@@ -17,15 +17,17 @@ __InLocalStorageMockFactory.type = STORAGE_MEMORY;
|
|
|
17
17
|
*
|
|
18
18
|
* @param {any} settings config object provided by the user to initialize the sdk
|
|
19
19
|
*
|
|
20
|
-
* @returns {Object} valid storage factory.
|
|
20
|
+
* @returns {Object} valid storage factory. Default to `InMemoryStorageCSFactory` if the provided storage is invalid or not compatible with the sdk mode if mode is standalone or localhost
|
|
21
|
+
*
|
|
22
|
+
* @throws error if mode is consumer and the provided storage is not compatible
|
|
21
23
|
*/
|
|
22
|
-
export function validateStorageCS(settings: { log: ILogger, storage?: any, mode
|
|
24
|
+
export function validateStorageCS(settings: { log: ILogger, storage?: any, mode: SDKMode }): ISettings['storage'] {
|
|
23
25
|
let { storage = InMemoryStorageCSFactory, log, mode } = settings;
|
|
24
26
|
|
|
25
27
|
// If an invalid storage is provided, fallback into MEMORY
|
|
26
|
-
if (typeof storage !== 'function' ||
|
|
28
|
+
if (typeof storage !== 'function' || [STORAGE_MEMORY, STORAGE_LOCALSTORAGE, STORAGE_PLUGGABLE].indexOf(storage.type) === -1) {
|
|
27
29
|
storage = InMemoryStorageCSFactory;
|
|
28
|
-
log.
|
|
30
|
+
log.error(ERROR_STORAGE_INVALID);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
// In localhost mode with InLocalStorage, fallback to a mock InLocalStorage to emit SDK_READY_FROM_CACHE
|
|
@@ -33,6 +35,17 @@ export function validateStorageCS(settings: { log: ILogger, storage?: any, mode?
|
|
|
33
35
|
return __InLocalStorageMockFactory;
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
if ([LOCALHOST_MODE, STANDALONE_MODE].indexOf(mode) === -1) {
|
|
39
|
+
// Consumer modes require an async storage
|
|
40
|
+
if (storage.type !== STORAGE_PLUGGABLE) throw new Error('A PluggableStorage instance is required on consumer mode');
|
|
41
|
+
} else {
|
|
42
|
+
// Standalone and localhost modes require a sync storage
|
|
43
|
+
if (storage.type === STORAGE_PLUGGABLE) {
|
|
44
|
+
storage = InMemoryStorageCSFactory;
|
|
45
|
+
log.error(ERROR_STORAGE_INVALID, [' It requires consumer mode.']);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
36
49
|
// return default InMemory storage if provided one is not valid
|
|
37
50
|
return storage;
|
|
38
51
|
}
|
|
@@ -89,9 +89,8 @@ export declare const WARN_INTEGRATION_INVALID = 218;
|
|
|
89
89
|
export declare const WARN_SPLITS_FILTER_IGNORED = 219;
|
|
90
90
|
export declare const WARN_SPLITS_FILTER_INVALID = 220;
|
|
91
91
|
export declare const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
92
|
-
export declare const
|
|
93
|
-
export declare const
|
|
94
|
-
export declare const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 224;
|
|
92
|
+
export declare const WARN_API_KEY = 222;
|
|
93
|
+
export declare const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
|
|
95
94
|
export declare const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
96
95
|
export declare const ERROR_LOGLEVEL_INVALID = 301;
|
|
97
96
|
export declare const ERROR_CLIENT_LISTENER = 302;
|
|
@@ -116,6 +115,7 @@ export declare const ERROR_EMPTY_ARRAY = 320;
|
|
|
116
115
|
export declare const ERROR_INVALID_IMPRESSIONS_MODE = 321;
|
|
117
116
|
export declare const ERROR_HTTP = 322;
|
|
118
117
|
export declare const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
|
|
118
|
+
export declare const ERROR_STORAGE_INVALID = 324;
|
|
119
119
|
export declare const LOG_PREFIX_SETTINGS = "settings";
|
|
120
120
|
export declare const LOG_PREFIX_INSTANTIATION = "Factory instantiation";
|
|
121
121
|
export declare const LOG_PREFIX_ENGINE = "engine";
|
|
@@ -7,4 +7,4 @@ import { ISplitApi } from './types';
|
|
|
7
7
|
* @param settings validated settings object
|
|
8
8
|
* @param platform object containing environment-specific `getFetch` and `getOptions` dependencies
|
|
9
9
|
*/
|
|
10
|
-
export declare function splitApiFactory(settings: ISettings, platform: Pick<IPlatform, 'getFetch' | 'getOptions'>): ISplitApi;
|
|
10
|
+
export declare function splitApiFactory(settings: Pick<ISettings, 'urls' | 'sync' | 'log' | 'version' | 'runtime' | 'core'>, platform: Pick<IPlatform, 'getFetch' | 'getOptions'>): ISplitApi;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IStorageSync, IStorageFactoryParams } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
4
4
|
*
|
|
5
5
|
* @param params parameters required by EventsCacheSync
|
|
6
6
|
*/
|
|
7
|
-
export declare function InMemoryStorageCSFactory(params: IStorageFactoryParams):
|
|
7
|
+
export declare function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorageSync;
|
|
8
8
|
export declare namespace InMemoryStorageCSFactory {
|
|
9
9
|
var type: import("../types").StorageType;
|
|
10
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IPluggableStorageWrapper, IEventsCacheAsync } from '../types';
|
|
2
2
|
import { IMetadata } from '../../dtos/types';
|
|
3
3
|
import { SplitIO } from '../../types';
|
|
4
4
|
import { ILogger } from '../../logger/types';
|
|
@@ -8,7 +8,7 @@ export declare class EventsCachePluggable implements IEventsCacheAsync {
|
|
|
8
8
|
private readonly wrapper;
|
|
9
9
|
private readonly key;
|
|
10
10
|
private readonly metadata;
|
|
11
|
-
constructor(log: ILogger, key: string, wrapper:
|
|
11
|
+
constructor(log: ILogger, key: string, wrapper: IPluggableStorageWrapper, metadata: IMetadata);
|
|
12
12
|
/**
|
|
13
13
|
* Push given event to the storage.
|
|
14
14
|
* @param eventData Event item to push.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IPluggableStorageWrapper, IImpressionsCacheAsync } from '../types';
|
|
2
2
|
import { IMetadata } from '../../dtos/types';
|
|
3
3
|
import { ImpressionDTO } from '../../types';
|
|
4
4
|
import { ILogger } from '../../logger/types';
|
|
@@ -8,7 +8,7 @@ export declare class ImpressionsCachePluggable implements IImpressionsCacheAsync
|
|
|
8
8
|
private readonly key;
|
|
9
9
|
private readonly wrapper;
|
|
10
10
|
private readonly metadata;
|
|
11
|
-
constructor(log: ILogger, key: string, wrapper:
|
|
11
|
+
constructor(log: ILogger, key: string, wrapper: IPluggableStorageWrapper, metadata: IMetadata);
|
|
12
12
|
/**
|
|
13
13
|
* Push given impressions to the storage.
|
|
14
14
|
* @param impressions List of impresions to push.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import KeyBuilderSS from '../KeyBuilderSS';
|
|
2
|
-
import {
|
|
2
|
+
import { IPluggableStorageWrapper, ISegmentsCacheAsync } from '../types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
4
|
/**
|
|
5
5
|
* ISegmentsCacheAsync implementation for pluggable storages.
|
|
@@ -8,19 +8,19 @@ export declare class SegmentsCachePluggable implements ISegmentsCacheAsync {
|
|
|
8
8
|
private readonly log;
|
|
9
9
|
private readonly keys;
|
|
10
10
|
private readonly wrapper;
|
|
11
|
-
constructor(log: ILogger, keys: KeyBuilderSS, wrapper:
|
|
11
|
+
constructor(log: ILogger, keys: KeyBuilderSS, wrapper: IPluggableStorageWrapper);
|
|
12
12
|
/**
|
|
13
13
|
* Add a list of `segmentKeys` to the given segment `name`.
|
|
14
14
|
* The returned promise is resolved when the operation success
|
|
15
15
|
* or rejected if wrapper operation fails.
|
|
16
16
|
*/
|
|
17
|
-
addToSegment(name: string, segmentKeys: string[]): Promise<void>;
|
|
17
|
+
addToSegment(name: string, segmentKeys: string[]): Promise<boolean | void>;
|
|
18
18
|
/**
|
|
19
19
|
* Remove a list of `segmentKeys` from the given segment `name`.
|
|
20
20
|
* The returned promise is resolved when the operation success
|
|
21
21
|
* or rejected if wrapper operation fails.
|
|
22
22
|
*/
|
|
23
|
-
removeFromSegment(name: string, segmentKeys: string[]): Promise<void>;
|
|
23
|
+
removeFromSegment(name: string, segmentKeys: string[]): Promise<boolean | void>;
|
|
24
24
|
/**
|
|
25
25
|
* Returns a promise that resolves with a boolean value indicating if `key` is part of `name` segment.
|
|
26
26
|
* Promise can be rejected if wrapper operation fails.
|
|
@@ -43,7 +43,7 @@ export declare class SegmentsCachePluggable implements ISegmentsCacheAsync {
|
|
|
43
43
|
* The returned promise is resolved when the operation success,
|
|
44
44
|
* or rejected if it fails (e.g., wrapper operation fails).
|
|
45
45
|
*/
|
|
46
|
-
registerSegments(segments: string[]): Promise<void>;
|
|
46
|
+
registerSegments(segments: string[]): Promise<boolean | void>;
|
|
47
47
|
/**
|
|
48
48
|
* Returns a promise that resolves with the set of registered segments in a list,
|
|
49
49
|
* or rejected if it fails (e.g., wrapper operation fails).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import KeyBuilder from '../KeyBuilder';
|
|
2
|
-
import {
|
|
2
|
+
import { IPluggableStorageWrapper } from '../types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
4
|
import AbstractSplitsCacheAsync from '../AbstractSplitsCacheAsync';
|
|
5
5
|
/**
|
|
@@ -10,12 +10,12 @@ export declare class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
10
10
|
private readonly keys;
|
|
11
11
|
private readonly wrapper;
|
|
12
12
|
/**
|
|
13
|
-
* Create a SplitsCache that uses a
|
|
13
|
+
* Create a SplitsCache that uses a storage wrapper.
|
|
14
14
|
* @param log Logger instance.
|
|
15
15
|
* @param keys Key builder.
|
|
16
16
|
* @param wrapper Adapted wrapper storage.
|
|
17
17
|
*/
|
|
18
|
-
constructor(log: ILogger, keys: KeyBuilder, wrapper:
|
|
18
|
+
constructor(log: ILogger, keys: KeyBuilder, wrapper: IPluggableStorageWrapper);
|
|
19
19
|
private _decrementCounts;
|
|
20
20
|
private _incrementCounts;
|
|
21
21
|
/**
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IPluggableStorageWrapper } from '../types';
|
|
2
2
|
import { ISet } from '../../utils/lang/sets';
|
|
3
3
|
/**
|
|
4
|
-
* Creates a
|
|
4
|
+
* Creates a IPluggableStorageWrapper implementation that stores items in memory.
|
|
5
5
|
* The `_cache` property is the object were items are stored.
|
|
6
6
|
* Intended for testing purposes.
|
|
7
|
+
*
|
|
8
|
+
* @param connDelay delay in millis for `connect` resolve. If not provided, `connect` resolves inmediatelly.
|
|
7
9
|
*/
|
|
8
|
-
export declare function inMemoryWrapperFactory():
|
|
10
|
+
export declare function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWrapper & {
|
|
9
11
|
_cache: Record<string, string | string[] | ISet<string>>;
|
|
12
|
+
_setConnDelay(connDelay: number): void;
|
|
10
13
|
};
|