@splitsoftware/splitio-commons 2.4.2-rc.2 → 2.5.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +2 -10
- package/cjs/storages/AbstractMySegmentsCacheSync.js +23 -31
- package/cjs/storages/AbstractSplitsCacheSync.js +2 -3
- package/cjs/storages/dataLoader.js +102 -43
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +16 -16
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +23 -20
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +37 -33
- package/cjs/storages/inLocalStorage/index.js +13 -28
- package/cjs/storages/inLocalStorage/validateCache.js +23 -25
- package/cjs/storages/inMemory/InMemoryStorageCS.js +32 -14
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +4 -0
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +3 -2
- package/cjs/sync/syncManagerOnline.js +24 -28
- package/cjs/utils/env/isLocalStorageAvailable.js +5 -28
- package/cjs/utils/settingsValidation/storage/storageCS.js +1 -1
- package/esm/storages/AbstractMySegmentsCacheSync.js +23 -31
- package/esm/storages/AbstractSplitsCacheSync.js +2 -3
- package/esm/storages/dataLoader.js +99 -41
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +16 -16
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +23 -20
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +37 -33
- package/esm/storages/inLocalStorage/index.js +14 -29
- package/esm/storages/inLocalStorage/validateCache.js +23 -25
- package/esm/storages/inMemory/InMemoryStorageCS.js +32 -14
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +4 -0
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +3 -2
- package/esm/sync/syncManagerOnline.js +24 -28
- package/esm/utils/env/isLocalStorageAvailable.js +3 -24
- package/esm/utils/settingsValidation/storage/storageCS.js +1 -1
- package/package.json +1 -1
- package/src/sdkFactory/index.ts +3 -2
- package/src/storages/AbstractMySegmentsCacheSync.ts +20 -26
- package/src/storages/AbstractSplitsCacheSync.ts +2 -3
- package/src/storages/dataLoader.ts +107 -49
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +17 -18
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +24 -22
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +37 -34
- package/src/storages/inLocalStorage/index.ts +16 -33
- package/src/storages/inLocalStorage/validateCache.ts +23 -26
- package/src/storages/inMemory/InMemoryStorageCS.ts +37 -14
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +4 -0
- package/src/storages/types.ts +6 -20
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +2 -1
- package/src/sync/syncManagerOnline.ts +22 -27
- package/src/types.ts +0 -35
- package/src/utils/env/isLocalStorageAvailable.ts +3 -24
- package/src/utils/settingsValidation/storage/storageCS.ts +1 -1
- package/types/splitio.d.ts +46 -27
- package/cjs/storages/inLocalStorage/storageAdapter.js +0 -48
- package/esm/storages/inLocalStorage/storageAdapter.js +0 -44
- package/src/storages/inLocalStorage/storageAdapter.ts +0 -50
|
@@ -7,6 +7,8 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
7
7
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
8
8
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
9
9
|
import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
10
|
+
import { getMatching } from '../../utils/key';
|
|
11
|
+
import { setCache } from '../dataLoader';
|
|
10
12
|
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -15,7 +17,9 @@ import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
|
15
17
|
* @param params - parameters required by EventsCacheSync
|
|
16
18
|
*/
|
|
17
19
|
export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorageSync {
|
|
18
|
-
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize }, sync: { __splitFiltersValidation } } } = params;
|
|
20
|
+
const { settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize }, sync: { __splitFiltersValidation }, preloadedData }, onReadyFromCacheCb } = params;
|
|
21
|
+
|
|
22
|
+
const storages: Record<string, IStorageSync> = {};
|
|
19
23
|
|
|
20
24
|
const splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
21
25
|
const rbSegments = new RBSegmentsCacheInMemory();
|
|
@@ -36,20 +40,31 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
36
40
|
destroy() { },
|
|
37
41
|
|
|
38
42
|
// When using shared instantiation with MEMORY we reuse everything but segments (they are unique per key)
|
|
39
|
-
shared() {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
shared(matchingKey: string) {
|
|
44
|
+
if (!storages[matchingKey]) {
|
|
45
|
+
const segments = new MySegmentsCacheInMemory();
|
|
46
|
+
const largeSegments = new MySegmentsCacheInMemory();
|
|
47
|
+
|
|
48
|
+
if (preloadedData) {
|
|
49
|
+
setCache(log, preloadedData, { segments, largeSegments }, matchingKey);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
storages[matchingKey] = {
|
|
53
|
+
splits: this.splits,
|
|
54
|
+
rbSegments: this.rbSegments,
|
|
55
|
+
segments,
|
|
56
|
+
largeSegments,
|
|
57
|
+
impressions: this.impressions,
|
|
58
|
+
impressionCounts: this.impressionCounts,
|
|
59
|
+
events: this.events,
|
|
60
|
+
telemetry: this.telemetry,
|
|
61
|
+
uniqueKeys: this.uniqueKeys,
|
|
62
|
+
|
|
63
|
+
destroy() { }
|
|
64
|
+
};
|
|
65
|
+
}
|
|
50
66
|
|
|
51
|
-
|
|
52
|
-
};
|
|
67
|
+
return storages[matchingKey];
|
|
53
68
|
},
|
|
54
69
|
};
|
|
55
70
|
|
|
@@ -63,6 +78,14 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
63
78
|
storage.uniqueKeys.track = noopTrack;
|
|
64
79
|
}
|
|
65
80
|
|
|
81
|
+
const matchingKey = getMatching(params.settings.core.key);
|
|
82
|
+
storages[matchingKey] = storage;
|
|
83
|
+
|
|
84
|
+
if (preloadedData) {
|
|
85
|
+
setCache(log, preloadedData, storage, matchingKey);
|
|
86
|
+
if (splits.getChangeNumber() > -1) onReadyFromCacheCb();
|
|
87
|
+
}
|
|
88
|
+
|
|
66
89
|
return storage;
|
|
67
90
|
}
|
|
68
91
|
|
|
@@ -51,6 +51,10 @@ export class RBSegmentsCacheInMemory implements IRBSegmentsCacheSync {
|
|
|
51
51
|
return this.cache[name] || null;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
getAll(): IRBSegment[] {
|
|
55
|
+
return this.getNames().map(key => this.get(key)!);
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
contains(names: Set<string>): boolean {
|
|
55
59
|
const namesArray = setToArray(names);
|
|
56
60
|
const namesInStorage = this.getNames();
|
package/src/storages/types.ts
CHANGED
|
@@ -4,22 +4,6 @@ import { MySegmentsData } from '../sync/polling/types';
|
|
|
4
4
|
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
|
|
5
5
|
import { ISettings } from '../types';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Internal interface based on a subset of the Web Storage API interface
|
|
9
|
-
* (https://developer.mozilla.org/en-US/docs/Web/API/Storage) used by the SDK
|
|
10
|
-
*/
|
|
11
|
-
export interface StorageAdapter {
|
|
12
|
-
// Methods to support async storages
|
|
13
|
-
load?: () => Promise<void>;
|
|
14
|
-
save?: () => Promise<void>;
|
|
15
|
-
// Methods based on https://developer.mozilla.org/en-US/docs/Web/API/Storage
|
|
16
|
-
readonly length: number;
|
|
17
|
-
getItem(key: string): string | null;
|
|
18
|
-
key(index: number): string | null;
|
|
19
|
-
removeItem(key: string): void;
|
|
20
|
-
setItem(key: string, value: string): void;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
7
|
/**
|
|
24
8
|
* Interface of a pluggable storage wrapper.
|
|
25
9
|
*/
|
|
@@ -251,6 +235,7 @@ export interface IRBSegmentsCacheSync extends IRBSegmentsCacheBase {
|
|
|
251
235
|
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): boolean,
|
|
252
236
|
get(name: string): IRBSegment | null,
|
|
253
237
|
getChangeNumber(): number,
|
|
238
|
+
getAll(): IRBSegment[],
|
|
254
239
|
clear(): void,
|
|
255
240
|
contains(names: Set<string>): boolean,
|
|
256
241
|
// Used only for smart pausing in client-side standalone. Returns true if the storage contains a RBSegment using segments or large segments matchers
|
|
@@ -481,7 +466,7 @@ export interface IStorageBase<
|
|
|
481
466
|
telemetry?: TTelemetryCache,
|
|
482
467
|
uniqueKeys: TUniqueKeysCache,
|
|
483
468
|
destroy(): void | Promise<void>,
|
|
484
|
-
shared?: (matchingKey: string, onReadyCb
|
|
469
|
+
shared?: (matchingKey: string, onReadyCb?: (error?: any) => void) => this
|
|
485
470
|
}
|
|
486
471
|
|
|
487
472
|
export interface IStorageSync extends IStorageBase<
|
|
@@ -495,7 +480,7 @@ export interface IStorageSync extends IStorageBase<
|
|
|
495
480
|
IUniqueKeysCacheSync
|
|
496
481
|
> {
|
|
497
482
|
// Defined in client-side
|
|
498
|
-
validateCache?: () =>
|
|
483
|
+
validateCache?: () => boolean, // @TODO support async
|
|
499
484
|
largeSegments?: ISegmentsCacheSync,
|
|
500
485
|
}
|
|
501
486
|
|
|
@@ -512,8 +497,6 @@ export interface IStorageAsync extends IStorageBase<
|
|
|
512
497
|
|
|
513
498
|
/** StorageFactory */
|
|
514
499
|
|
|
515
|
-
export type DataLoader = (storage: IStorageSync, matchingKey: string) => void
|
|
516
|
-
|
|
517
500
|
export interface IStorageFactoryParams {
|
|
518
501
|
settings: ISettings,
|
|
519
502
|
/**
|
|
@@ -521,6 +504,9 @@ export interface IStorageFactoryParams {
|
|
|
521
504
|
* It is meant for emitting SDK_READY event in consumer mode, and waiting before using the storage in the synchronizer.
|
|
522
505
|
*/
|
|
523
506
|
onReadyCb: (error?: any) => void,
|
|
507
|
+
/**
|
|
508
|
+
* For emitting SDK_READY_FROM_CACHE event in consumer mode with Redis and standalone mode with preloaded data
|
|
509
|
+
*/
|
|
524
510
|
onReadyFromCacheCb: () => void,
|
|
525
511
|
}
|
|
526
512
|
|
|
@@ -59,7 +59,8 @@ export function fromObjectUpdaterFactory(
|
|
|
59
59
|
|
|
60
60
|
if (startingUp) {
|
|
61
61
|
startingUp = false;
|
|
62
|
-
|
|
62
|
+
const isCacheLoaded = storage.validateCache ? storage.validateCache() : false;
|
|
63
|
+
Promise.resolve().then(() => {
|
|
63
64
|
// Emits SDK_READY_FROM_CACHE
|
|
64
65
|
if (isCacheLoaded) readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
|
|
65
66
|
// Emits SDK_READY
|
|
@@ -89,41 +89,36 @@ export function syncManagerOnlineFactory(
|
|
|
89
89
|
start() {
|
|
90
90
|
running = true;
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!running) return;
|
|
97
|
-
|
|
98
|
-
if (startFirstTime) {
|
|
99
|
-
// Emits SDK_READY_FROM_CACHE
|
|
100
|
-
if (isCacheLoaded) readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
|
|
92
|
+
if (startFirstTime) {
|
|
93
|
+
const isCacheLoaded = storage.validateCache ? storage.validateCache() : false;
|
|
94
|
+
if (isCacheLoaded) Promise.resolve().then(() => { readiness.splits.emit(SDK_SPLITS_CACHE_LOADED); });
|
|
95
|
+
}
|
|
101
96
|
|
|
102
|
-
|
|
97
|
+
// start syncing splits and segments
|
|
98
|
+
if (pollingManager) {
|
|
103
99
|
|
|
104
|
-
//
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (syncEnabled) {
|
|
109
|
-
if (pushManager) {
|
|
110
|
-
// Doesn't call `syncAll` when the syncManager is resuming
|
|
111
|
-
if (startFirstTime) {
|
|
112
|
-
pollingManager.syncAll();
|
|
113
|
-
}
|
|
114
|
-
pushManager.start();
|
|
115
|
-
} else {
|
|
116
|
-
pollingManager.start();
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
100
|
+
// If synchronization is disabled pushManager and pollingManager should not start
|
|
101
|
+
if (syncEnabled) {
|
|
102
|
+
if (pushManager) {
|
|
103
|
+
// Doesn't call `syncAll` when the syncManager is resuming
|
|
119
104
|
if (startFirstTime) {
|
|
120
105
|
pollingManager.syncAll();
|
|
121
106
|
}
|
|
107
|
+
pushManager.start();
|
|
108
|
+
} else {
|
|
109
|
+
pollingManager.start();
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
if (startFirstTime) {
|
|
113
|
+
pollingManager.syncAll();
|
|
122
114
|
}
|
|
123
115
|
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// start periodic data recording (events, impressions, telemetry).
|
|
119
|
+
submitterManager.start(!isConsentGranted(settings));
|
|
124
120
|
|
|
125
|
-
|
|
126
|
-
});
|
|
121
|
+
startFirstTime = false;
|
|
127
122
|
},
|
|
128
123
|
|
|
129
124
|
/**
|
package/src/types.ts
CHANGED
|
@@ -42,38 +42,3 @@ export interface IBasicClient extends SplitIO.IBasicClient {
|
|
|
42
42
|
isClientSide?: boolean;
|
|
43
43
|
key?: SplitIO.SplitKey;
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Defines the format of rollout plan data to preload the factory storage (cache).
|
|
47
|
-
*/
|
|
48
|
-
export interface PreloadedData {
|
|
49
|
-
/**
|
|
50
|
-
* Timestamp of the last moment the data was synchronized with Split servers.
|
|
51
|
-
* If this value is older than 10 days ago (expiration time policy), the data is not used to update the storage content.
|
|
52
|
-
*/
|
|
53
|
-
// @TODO configurable expiration time policy?
|
|
54
|
-
lastUpdated: number;
|
|
55
|
-
/**
|
|
56
|
-
* Change number of the preloaded data.
|
|
57
|
-
* If this value is older than the current changeNumber at the storage, the data is not used to update the storage content.
|
|
58
|
-
*/
|
|
59
|
-
since: number;
|
|
60
|
-
/**
|
|
61
|
-
* Map of feature flags to their stringified definitions.
|
|
62
|
-
*/
|
|
63
|
-
splitsData: {
|
|
64
|
-
[splitName: string]: string;
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
|
-
* Optional map of user keys to their list of segments.
|
|
68
|
-
*/
|
|
69
|
-
mySegmentsData?: {
|
|
70
|
-
[key: string]: string[];
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Optional map of segments to their stringified definitions.
|
|
74
|
-
* This property is ignored if `mySegmentsData` was provided.
|
|
75
|
-
*/
|
|
76
|
-
segmentsData?: {
|
|
77
|
-
[segmentName: string]: string;
|
|
78
|
-
};
|
|
79
|
-
}
|
|
@@ -1,32 +1,11 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
1
2
|
export function isLocalStorageAvailable(): boolean {
|
|
2
|
-
try {
|
|
3
|
-
// eslint-disable-next-line no-undef
|
|
4
|
-
return isValidStorageWrapper(localStorage);
|
|
5
|
-
} catch (e) {
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function isValidStorageWrapper(wrapper: any): boolean {
|
|
11
3
|
var mod = '__SPLITSOFTWARE__';
|
|
12
4
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
wrapper.removeItem(mod);
|
|
5
|
+
localStorage.setItem(mod, mod);
|
|
6
|
+
localStorage.removeItem(mod);
|
|
16
7
|
return true;
|
|
17
8
|
} catch (e) {
|
|
18
9
|
return false;
|
|
19
10
|
}
|
|
20
11
|
}
|
|
21
|
-
|
|
22
|
-
export function isWebStorage(wrapper: any): boolean {
|
|
23
|
-
if (typeof wrapper.length === 'number') {
|
|
24
|
-
try {
|
|
25
|
-
wrapper.key(0);
|
|
26
|
-
return true;
|
|
27
|
-
} catch (e) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
@@ -8,7 +8,7 @@ import { IStorageFactoryParams, IStorageSync } from '../../../storages/types';
|
|
|
8
8
|
|
|
9
9
|
export function __InLocalStorageMockFactory(params: IStorageFactoryParams): IStorageSync {
|
|
10
10
|
const result = InMemoryStorageCSFactory(params);
|
|
11
|
-
result.validateCache = () =>
|
|
11
|
+
result.validateCache = () => true; // to emit SDK_READY_FROM_CACHE
|
|
12
12
|
return result;
|
|
13
13
|
}
|
|
14
14
|
__InLocalStorageMockFactory.type = STORAGE_MEMORY;
|
package/types/splitio.d.ts
CHANGED
|
@@ -350,6 +350,10 @@ interface IClientSideSyncSharedSettings extends IClientSideSharedSettings, ISync
|
|
|
350
350
|
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode}
|
|
351
351
|
*/
|
|
352
352
|
features?: SplitIO.MockedFeaturesMap;
|
|
353
|
+
/**
|
|
354
|
+
* Data to initialize the SDK storage with. If provided and valid, the SDK will be ready from cache immediately.
|
|
355
|
+
*/
|
|
356
|
+
preloadedData?: SplitIO.PreloadedData;
|
|
353
357
|
/**
|
|
354
358
|
* SDK Startup settings.
|
|
355
359
|
*/
|
|
@@ -458,21 +462,6 @@ interface IClientSideSyncSharedSettings extends IClientSideSharedSettings, ISync
|
|
|
458
462
|
*/
|
|
459
463
|
declare namespace SplitIO {
|
|
460
464
|
|
|
461
|
-
interface StorageWrapper {
|
|
462
|
-
/**
|
|
463
|
-
* Returns a promise that resolves to the current value associated with the given key, or null if the given key does not exist.
|
|
464
|
-
*/
|
|
465
|
-
getItem(key: string): Promise<string | null> | string | null;
|
|
466
|
-
/**
|
|
467
|
-
* Returns a promise that resolves when the value of the pair identified by key is set to value, creating a new key/value pair if none existed for key previously.
|
|
468
|
-
*/
|
|
469
|
-
setItem(key: string, value: string): Promise<void> | void;
|
|
470
|
-
/**
|
|
471
|
-
* Returns a promise that resolves when the key/value pair with the given key is removed, if a key/value pair with the given key exists.
|
|
472
|
-
*/
|
|
473
|
-
removeItem(key: string): Promise<void> | void;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
465
|
/**
|
|
477
466
|
* EventEmitter interface based on a subset of the Node.js EventEmitter methods.
|
|
478
467
|
*/
|
|
@@ -570,6 +559,7 @@ declare namespace SplitIO {
|
|
|
570
559
|
eventsFirstPushWindow: number;
|
|
571
560
|
};
|
|
572
561
|
readonly storage: StorageSyncFactory | StorageAsyncFactory | StorageOptions;
|
|
562
|
+
readonly preloadedData?: SplitIO.PreloadedData;
|
|
573
563
|
readonly urls: {
|
|
574
564
|
events: string;
|
|
575
565
|
sdk: string;
|
|
@@ -987,12 +977,6 @@ declare namespace SplitIO {
|
|
|
987
977
|
* @defaultValue `false`
|
|
988
978
|
*/
|
|
989
979
|
clearOnInit?: boolean;
|
|
990
|
-
/**
|
|
991
|
-
* Optional storage wrapper to persist rollout plan related data. If not provided, the SDK will use the default localStorage Web API.
|
|
992
|
-
*
|
|
993
|
-
* @defaultValue `window.localStorage`
|
|
994
|
-
*/
|
|
995
|
-
wrapper?: StorageWrapper;
|
|
996
980
|
}
|
|
997
981
|
/**
|
|
998
982
|
* Storage for asynchronous (consumer) SDK.
|
|
@@ -1042,6 +1026,40 @@ declare namespace SplitIO {
|
|
|
1042
1026
|
prefix?: string;
|
|
1043
1027
|
options?: Object;
|
|
1044
1028
|
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Defines the format of rollout plan data to preload the factory storage (cache).
|
|
1031
|
+
*/
|
|
1032
|
+
type PreloadedData = {
|
|
1033
|
+
/**
|
|
1034
|
+
* Change number of feature flags.
|
|
1035
|
+
*/
|
|
1036
|
+
since: number;
|
|
1037
|
+
/**
|
|
1038
|
+
* List of feature flags.
|
|
1039
|
+
*/
|
|
1040
|
+
flags: Object[],
|
|
1041
|
+
/**
|
|
1042
|
+
* Change number of rule-based segments.
|
|
1043
|
+
*/
|
|
1044
|
+
rbSince?: number,
|
|
1045
|
+
/**
|
|
1046
|
+
* List of rule-based segments.
|
|
1047
|
+
*/
|
|
1048
|
+
rbSegments?: Object[],
|
|
1049
|
+
/**
|
|
1050
|
+
* Optional map of user keys to their memberships.
|
|
1051
|
+
*/
|
|
1052
|
+
memberships?: {
|
|
1053
|
+
[key: string]: Object
|
|
1054
|
+
},
|
|
1055
|
+
/**
|
|
1056
|
+
* Optional map of segments to their list of keys.
|
|
1057
|
+
* This property is ignored if `memberships` is provided.
|
|
1058
|
+
*/
|
|
1059
|
+
segments?: {
|
|
1060
|
+
[segmentName: string]: string[]
|
|
1061
|
+
},
|
|
1062
|
+
}
|
|
1045
1063
|
/**
|
|
1046
1064
|
* Impression listener interface. This is the interface that needs to be implemented
|
|
1047
1065
|
* by the element you provide to the SDK as impression listener.
|
|
@@ -1333,12 +1351,6 @@ declare namespace SplitIO {
|
|
|
1333
1351
|
* @defaultValue `false`
|
|
1334
1352
|
*/
|
|
1335
1353
|
clearOnInit?: boolean;
|
|
1336
|
-
/**
|
|
1337
|
-
* Optional storage wrapper to persist rollout plan related data. If not provided, the SDK will use the default localStorage Web API.
|
|
1338
|
-
*
|
|
1339
|
-
* @defaultValue `window.localStorage`
|
|
1340
|
-
*/
|
|
1341
|
-
wrapper?: StorageWrapper;
|
|
1342
1354
|
};
|
|
1343
1355
|
}
|
|
1344
1356
|
/**
|
|
@@ -1591,6 +1603,13 @@ declare namespace SplitIO {
|
|
|
1591
1603
|
* @returns The manager instance.
|
|
1592
1604
|
*/
|
|
1593
1605
|
manager(): IManager;
|
|
1606
|
+
/**
|
|
1607
|
+
* Returns the current snapshot of the SDK rollout plan in cache.
|
|
1608
|
+
*
|
|
1609
|
+
* @param keys - Optional list of keys to generate the rollout plan snapshot with the memberships of the given keys, rather than the complete segments data.
|
|
1610
|
+
* @returns The current snapshot of the SDK rollout plan.
|
|
1611
|
+
*/
|
|
1612
|
+
getCache(keys?: SplitKey[]): PreloadedData,
|
|
1594
1613
|
}
|
|
1595
1614
|
/**
|
|
1596
1615
|
* This represents the interface for the SDK instance for server-side with asynchronous storage.
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.storageAdapter = void 0;
|
|
4
|
-
var constants_1 = require("./constants");
|
|
5
|
-
function isTillKey(key) {
|
|
6
|
-
return key.endsWith('.till');
|
|
7
|
-
}
|
|
8
|
-
function storageAdapter(log, prefix, wrapper) {
|
|
9
|
-
var cache = {};
|
|
10
|
-
var connectPromise;
|
|
11
|
-
var disconnectPromise = Promise.resolve();
|
|
12
|
-
return {
|
|
13
|
-
load: function () {
|
|
14
|
-
return connectPromise || (connectPromise = Promise.resolve(wrapper.getItem(prefix)).then(function (storedCache) {
|
|
15
|
-
cache = JSON.parse(storedCache || '{}');
|
|
16
|
-
}).catch(function (e) {
|
|
17
|
-
log.error(constants_1.LOG_PREFIX + 'Rejected promise calling storage getItem, with error: ' + e);
|
|
18
|
-
}));
|
|
19
|
-
},
|
|
20
|
-
save: function () {
|
|
21
|
-
return disconnectPromise = disconnectPromise.then(function () {
|
|
22
|
-
return Promise.resolve(wrapper.setItem(prefix, JSON.stringify(cache))).catch(function (e) {
|
|
23
|
-
log.error(constants_1.LOG_PREFIX + 'Rejected promise calling storage setItem, with error: ' + e);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
},
|
|
27
|
-
get length() {
|
|
28
|
-
return Object.keys(cache).length;
|
|
29
|
-
},
|
|
30
|
-
getItem: function (key) {
|
|
31
|
-
return cache[key] || null;
|
|
32
|
-
},
|
|
33
|
-
key: function (index) {
|
|
34
|
-
return Object.keys(cache)[index] || null;
|
|
35
|
-
},
|
|
36
|
-
removeItem: function (key) {
|
|
37
|
-
delete cache[key];
|
|
38
|
-
if (isTillKey(key))
|
|
39
|
-
this.save();
|
|
40
|
-
},
|
|
41
|
-
setItem: function (key, value) {
|
|
42
|
-
cache[key] = value;
|
|
43
|
-
if (isTillKey(key))
|
|
44
|
-
this.save();
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
exports.storageAdapter = storageAdapter;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { LOG_PREFIX } from './constants';
|
|
2
|
-
function isTillKey(key) {
|
|
3
|
-
return key.endsWith('.till');
|
|
4
|
-
}
|
|
5
|
-
export function storageAdapter(log, prefix, wrapper) {
|
|
6
|
-
var cache = {};
|
|
7
|
-
var connectPromise;
|
|
8
|
-
var disconnectPromise = Promise.resolve();
|
|
9
|
-
return {
|
|
10
|
-
load: function () {
|
|
11
|
-
return connectPromise || (connectPromise = Promise.resolve(wrapper.getItem(prefix)).then(function (storedCache) {
|
|
12
|
-
cache = JSON.parse(storedCache || '{}');
|
|
13
|
-
}).catch(function (e) {
|
|
14
|
-
log.error(LOG_PREFIX + 'Rejected promise calling storage getItem, with error: ' + e);
|
|
15
|
-
}));
|
|
16
|
-
},
|
|
17
|
-
save: function () {
|
|
18
|
-
return disconnectPromise = disconnectPromise.then(function () {
|
|
19
|
-
return Promise.resolve(wrapper.setItem(prefix, JSON.stringify(cache))).catch(function (e) {
|
|
20
|
-
log.error(LOG_PREFIX + 'Rejected promise calling storage setItem, with error: ' + e);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
},
|
|
24
|
-
get length() {
|
|
25
|
-
return Object.keys(cache).length;
|
|
26
|
-
},
|
|
27
|
-
getItem: function (key) {
|
|
28
|
-
return cache[key] || null;
|
|
29
|
-
},
|
|
30
|
-
key: function (index) {
|
|
31
|
-
return Object.keys(cache)[index] || null;
|
|
32
|
-
},
|
|
33
|
-
removeItem: function (key) {
|
|
34
|
-
delete cache[key];
|
|
35
|
-
if (isTillKey(key))
|
|
36
|
-
this.save();
|
|
37
|
-
},
|
|
38
|
-
setItem: function (key, value) {
|
|
39
|
-
cache[key] = value;
|
|
40
|
-
if (isTillKey(key))
|
|
41
|
-
this.save();
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { ILogger } from '../../logger/types';
|
|
2
|
-
import SplitIO from '../../../types/splitio';
|
|
3
|
-
import { LOG_PREFIX } from './constants';
|
|
4
|
-
import { StorageAdapter } from '../types';
|
|
5
|
-
|
|
6
|
-
function isTillKey(key: string) {
|
|
7
|
-
return key.endsWith('.till');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function storageAdapter(log: ILogger, prefix: string, wrapper: SplitIO.StorageWrapper): StorageAdapter {
|
|
11
|
-
let cache: Record<string, string> = {};
|
|
12
|
-
|
|
13
|
-
let connectPromise: Promise<void> | undefined;
|
|
14
|
-
let disconnectPromise = Promise.resolve();
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
load() {
|
|
18
|
-
return connectPromise || (connectPromise = Promise.resolve(wrapper.getItem(prefix)).then((storedCache) => {
|
|
19
|
-
cache = JSON.parse(storedCache || '{}');
|
|
20
|
-
}).catch((e) => {
|
|
21
|
-
log.error(LOG_PREFIX + 'Rejected promise calling storage getItem, with error: ' + e);
|
|
22
|
-
}));
|
|
23
|
-
},
|
|
24
|
-
save() {
|
|
25
|
-
return disconnectPromise = disconnectPromise.then(() => {
|
|
26
|
-
return Promise.resolve(wrapper.setItem(prefix, JSON.stringify(cache))).catch((e) => {
|
|
27
|
-
log.error(LOG_PREFIX + 'Rejected promise calling storage setItem, with error: ' + e);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
get length() {
|
|
33
|
-
return Object.keys(cache).length;
|
|
34
|
-
},
|
|
35
|
-
getItem(key: string) {
|
|
36
|
-
return cache[key] || null;
|
|
37
|
-
},
|
|
38
|
-
key(index: number) {
|
|
39
|
-
return Object.keys(cache)[index] || null;
|
|
40
|
-
},
|
|
41
|
-
removeItem(key: string) {
|
|
42
|
-
delete cache[key];
|
|
43
|
-
if (isTillKey(key)) this.save!();
|
|
44
|
-
},
|
|
45
|
-
setItem(key: string, value: string) {
|
|
46
|
-
cache[key] = value;
|
|
47
|
-
if (isTillKey(key)) this.save!();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
}
|