@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.
Files changed (51) hide show
  1. package/CHANGES.txt +2 -10
  2. package/cjs/storages/AbstractMySegmentsCacheSync.js +23 -31
  3. package/cjs/storages/AbstractSplitsCacheSync.js +2 -3
  4. package/cjs/storages/dataLoader.js +102 -43
  5. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +16 -16
  6. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +23 -20
  7. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +37 -33
  8. package/cjs/storages/inLocalStorage/index.js +13 -28
  9. package/cjs/storages/inLocalStorage/validateCache.js +23 -25
  10. package/cjs/storages/inMemory/InMemoryStorageCS.js +32 -14
  11. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +4 -0
  12. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +3 -2
  13. package/cjs/sync/syncManagerOnline.js +24 -28
  14. package/cjs/utils/env/isLocalStorageAvailable.js +5 -28
  15. package/cjs/utils/settingsValidation/storage/storageCS.js +1 -1
  16. package/esm/storages/AbstractMySegmentsCacheSync.js +23 -31
  17. package/esm/storages/AbstractSplitsCacheSync.js +2 -3
  18. package/esm/storages/dataLoader.js +99 -41
  19. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +16 -16
  20. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +23 -20
  21. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +37 -33
  22. package/esm/storages/inLocalStorage/index.js +14 -29
  23. package/esm/storages/inLocalStorage/validateCache.js +23 -25
  24. package/esm/storages/inMemory/InMemoryStorageCS.js +32 -14
  25. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +4 -0
  26. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +3 -2
  27. package/esm/sync/syncManagerOnline.js +24 -28
  28. package/esm/utils/env/isLocalStorageAvailable.js +3 -24
  29. package/esm/utils/settingsValidation/storage/storageCS.js +1 -1
  30. package/package.json +1 -1
  31. package/src/sdkFactory/index.ts +3 -2
  32. package/src/storages/AbstractMySegmentsCacheSync.ts +20 -26
  33. package/src/storages/AbstractSplitsCacheSync.ts +2 -3
  34. package/src/storages/dataLoader.ts +107 -49
  35. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +17 -18
  36. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +24 -22
  37. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +37 -34
  38. package/src/storages/inLocalStorage/index.ts +16 -33
  39. package/src/storages/inLocalStorage/validateCache.ts +23 -26
  40. package/src/storages/inMemory/InMemoryStorageCS.ts +37 -14
  41. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +4 -0
  42. package/src/storages/types.ts +6 -20
  43. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +2 -1
  44. package/src/sync/syncManagerOnline.ts +22 -27
  45. package/src/types.ts +0 -35
  46. package/src/utils/env/isLocalStorageAvailable.ts +3 -24
  47. package/src/utils/settingsValidation/storage/storageCS.ts +1 -1
  48. package/types/splitio.d.ts +46 -27
  49. package/cjs/storages/inLocalStorage/storageAdapter.js +0 -48
  50. package/esm/storages/inLocalStorage/storageAdapter.js +0 -44
  51. package/src/storages/inLocalStorage/storageAdapter.ts +0 -50
@@ -9,10 +9,9 @@ var AbstractSplitsCacheSync = /** @class */ (function () {
9
9
  }
10
10
  AbstractSplitsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
11
11
  var _this = this;
12
- var updated = toAdd.map(function (addedFF) { return _this.addSplit(addedFF); }).some(function (result) { return result; });
13
- updated = toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }).some(function (result) { return result; }) || updated;
14
12
  this.setChangeNumber(changeNumber);
15
- return updated;
13
+ var updated = toAdd.map(function (addedFF) { return _this.addSplit(addedFF); }).some(function (result) { return result; });
14
+ return toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }).some(function (result) { return result; }) || updated;
16
15
  };
17
16
  AbstractSplitsCacheSync.prototype.getSplits = function (names) {
18
17
  var _this = this;
@@ -1,46 +1,104 @@
1
- // This value might be eventually set via a config parameter
2
- var DEFAULT_CACHE_EXPIRATION_IN_MILLIS = 864000000; // 10 days
1
+ import { setToArray } from '../utils/lang/sets';
2
+ import { getMatching } from '../utils/key';
3
3
  /**
4
- * Factory of client-side storage loader
5
- *
6
- * @param preloadedData - validated data following the format proposed in https://github.com/godaddy/split-javascript-data-loader
7
- * and extended with a `mySegmentsData` property.
8
- * @returns function to preload the storage
4
+ * Sets the given synchronous storage with the provided preloaded data snapshot.
5
+ * If `matchingKey` is provided, the storage is handled as a client-side storage (segments and largeSegments are instances of MySegmentsCache).
6
+ * Otherwise, the storage is handled as a server-side storage (segments is an instance of SegmentsCache).
9
7
  */
10
- export function dataLoaderFactory(preloadedData) {
11
- /**
12
- * Storage-agnostic adaptation of `loadDataIntoLocalStorage` function
13
- * (https://github.com/godaddy/split-javascript-data-loader/blob/master/src/load-data.js)
14
- *
15
- * @param storage - object containing `splits` and `segments` cache (client-side variant)
16
- * @param userId - user key string of the provided MySegmentsCache
17
- */
18
- // @TODO extend to support SegmentsCache (server-side variant) by making `userId` optional and adding the corresponding logic.
19
- // @TODO extend to load data on shared mySegments storages. Be specific when emitting SDK_READY_FROM_CACHE on shared clients. Maybe the serializer should provide the `useSegments` flag.
20
- return function loadData(storage, userId) {
21
- // Do not load data if current preloadedData is empty
22
- if (Object.keys(preloadedData).length === 0)
23
- return;
24
- var _a = preloadedData.lastUpdated, lastUpdated = _a === void 0 ? -1 : _a, _b = preloadedData.segmentsData, segmentsData = _b === void 0 ? {} : _b, _c = preloadedData.since, since = _c === void 0 ? -1 : _c, _d = preloadedData.splitsData, splitsData = _d === void 0 ? {} : _d;
25
- var storedSince = storage.splits.getChangeNumber();
26
- var expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
27
- // Do not load data if current localStorage data is more recent,
28
- // or if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
29
- if (storedSince > since || lastUpdated < expirationTimestamp)
30
- return;
31
- // cleaning up the localStorage data, since some cached splits might need be part of the preloaded data
32
- storage.splits.clear();
33
- // splitsData in an object where the property is the split name and the pertaining value is a stringified json of its data
34
- storage.splits.update(Object.keys(splitsData).map(function (splitName) { return JSON.parse(splitsData[splitName]); }), [], since);
35
- // add mySegments data
36
- var mySegmentsData = preloadedData.mySegmentsData && preloadedData.mySegmentsData[userId];
37
- if (!mySegmentsData) {
38
- // segmentsData in an object where the property is the segment name and the pertaining value is a stringified object that contains the `added` array of userIds
39
- mySegmentsData = Object.keys(segmentsData).filter(function (segmentName) {
40
- var userIds = JSON.parse(segmentsData[segmentName]).added;
41
- return Array.isArray(userIds) && userIds.indexOf(userId) > -1;
42
- });
8
+ export function setCache(log, preloadedData, storage, matchingKey) {
9
+ // Do not load data if current preloadedData is empty
10
+ if (Object.keys(preloadedData).length === 0)
11
+ return;
12
+ var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments, largeSegments = storage.largeSegments;
13
+ log.debug("set cache" + (matchingKey ? " for key " + matchingKey : ''));
14
+ if (splits) {
15
+ splits.clear();
16
+ splits.update(preloadedData.flags || [], [], preloadedData.since || -1);
17
+ }
18
+ if (rbSegments) {
19
+ rbSegments.clear();
20
+ rbSegments.update(preloadedData.rbSegments || [], [], preloadedData.rbSince || -1);
21
+ }
22
+ var segmentsData = preloadedData.segments || {};
23
+ if (matchingKey) { // add memberships data (client-side)
24
+ var memberships = preloadedData.memberships && preloadedData.memberships[matchingKey];
25
+ if (!memberships && segmentsData) {
26
+ memberships = {
27
+ ms: {
28
+ k: Object.keys(segmentsData).filter(function (segmentName) {
29
+ var segmentKeys = segmentsData[segmentName];
30
+ return segmentKeys.indexOf(matchingKey) > -1;
31
+ }).map(function (segmentName) { return ({ n: segmentName }); })
32
+ }
33
+ };
43
34
  }
44
- storage.segments.resetSegments({ k: mySegmentsData.map(function (s) { return ({ n: s }); }) });
35
+ if (memberships) {
36
+ if (memberships.ms)
37
+ segments.resetSegments(memberships.ms);
38
+ if (memberships.ls && largeSegments)
39
+ largeSegments.resetSegments(memberships.ls);
40
+ }
41
+ }
42
+ else { // add segments data (server-side)
43
+ Object.keys(segmentsData).forEach(function (segmentName) {
44
+ var segmentKeys = segmentsData[segmentName];
45
+ segments.update(segmentName, segmentKeys, [], -1);
46
+ });
47
+ }
48
+ }
49
+ /**
50
+ * Gets the preloaded data snapshot from the given synchronous storage.
51
+ * If `keys` are provided, the memberships for those keys is returned, to protect segments data.
52
+ * Otherwise, the segments data is returned.
53
+ */
54
+ export function getCache(log, storage, keys) {
55
+ log.debug("get cache" + (keys ? " for keys " + keys : ''));
56
+ return {
57
+ since: storage.splits.getChangeNumber(),
58
+ flags: storage.splits.getAll(),
59
+ rbSince: storage.rbSegments.getChangeNumber(),
60
+ rbSegments: storage.rbSegments.getAll(),
61
+ segments: keys ?
62
+ undefined : // @ts-ignore accessing private prop
63
+ Object.keys(storage.segments.segmentCache).reduce(function (prev, cur) {
64
+ prev[cur] = setToArray(storage.segments.segmentCache[cur]);
65
+ return prev;
66
+ }, {}),
67
+ memberships: keys ?
68
+ keys.reduce(function (prev, key) {
69
+ if (storage.shared) {
70
+ // Client-side segments
71
+ // @ts-ignore accessing private prop
72
+ var sharedStorage = storage.shared(key);
73
+ prev[getMatching(key)] = {
74
+ ms: {
75
+ // @ts-ignore accessing private prop
76
+ k: Object.keys(sharedStorage.segments.segmentCache).map(function (segmentName) { return ({ n: segmentName }); }),
77
+ },
78
+ ls: sharedStorage.largeSegments ? {
79
+ // @ts-ignore accessing private prop
80
+ k: Object.keys(sharedStorage.largeSegments.segmentCache).map(function (segmentName) { return ({ n: segmentName }); }),
81
+ } : undefined
82
+ };
83
+ }
84
+ else {
85
+ prev[getMatching(key)] = {
86
+ ms: {
87
+ // Server-side segments
88
+ // @ts-ignore accessing private prop
89
+ k: Object.keys(storage.segments.segmentCache).reduce(function (prev, segmentName) {
90
+ return storage.segments.segmentCache[segmentName].has(key) ?
91
+ prev.concat({ n: segmentName }) :
92
+ prev;
93
+ }, [])
94
+ },
95
+ ls: {
96
+ k: []
97
+ }
98
+ };
99
+ }
100
+ return prev;
101
+ }, {}) :
102
+ undefined
45
103
  };
46
104
  }
@@ -4,20 +4,19 @@ import { AbstractMySegmentsCacheSync } from '../AbstractMySegmentsCacheSync';
4
4
  import { LOG_PREFIX, DEFINED } from './constants';
5
5
  var MySegmentsCacheInLocal = /** @class */ (function (_super) {
6
6
  __extends(MySegmentsCacheInLocal, _super);
7
- function MySegmentsCacheInLocal(log, keys, storage) {
7
+ function MySegmentsCacheInLocal(log, keys) {
8
8
  var _this = _super.call(this) || this;
9
9
  _this.log = log;
10
10
  _this.keys = keys;
11
- _this.storage = storage;
12
11
  return _this;
13
12
  // There is not need to flush segments cache like splits cache, since resetSegments receives the up-to-date list of active segments
14
13
  }
15
14
  MySegmentsCacheInLocal.prototype.addSegment = function (name) {
16
15
  var segmentKey = this.keys.buildSegmentNameKey(name);
17
16
  try {
18
- if (this.storage.getItem(segmentKey) === DEFINED)
17
+ if (localStorage.getItem(segmentKey) === DEFINED)
19
18
  return false;
20
- this.storage.setItem(segmentKey, DEFINED);
19
+ localStorage.setItem(segmentKey, DEFINED);
21
20
  return true;
22
21
  }
23
22
  catch (e) {
@@ -28,9 +27,9 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
28
27
  MySegmentsCacheInLocal.prototype.removeSegment = function (name) {
29
28
  var segmentKey = this.keys.buildSegmentNameKey(name);
30
29
  try {
31
- if (this.storage.getItem(segmentKey) !== DEFINED)
30
+ if (localStorage.getItem(segmentKey) !== DEFINED)
32
31
  return false;
33
- this.storage.removeItem(segmentKey);
32
+ localStorage.removeItem(segmentKey);
34
33
  return true;
35
34
  }
36
35
  catch (e) {
@@ -39,16 +38,17 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
39
38
  }
40
39
  };
41
40
  MySegmentsCacheInLocal.prototype.isInSegment = function (name) {
42
- return this.storage.getItem(this.keys.buildSegmentNameKey(name)) === DEFINED;
41
+ return localStorage.getItem(this.keys.buildSegmentNameKey(name)) === DEFINED;
43
42
  };
44
43
  MySegmentsCacheInLocal.prototype.getRegisteredSegments = function () {
45
- var registeredSegments = [];
46
- for (var i = 0; i < this.storage.length; i++) {
47
- var segmentName = this.keys.extractSegmentName(this.storage.key(i));
44
+ var _this = this;
45
+ // Scan current values from localStorage
46
+ return Object.keys(localStorage).reduce(function (accum, key) {
47
+ var segmentName = _this.keys.extractSegmentName(key);
48
48
  if (segmentName)
49
- registeredSegments.push(segmentName);
50
- }
51
- return registeredSegments;
49
+ accum.push(segmentName);
50
+ return accum;
51
+ }, []);
52
52
  };
53
53
  MySegmentsCacheInLocal.prototype.getKeysCount = function () {
54
54
  return 1;
@@ -56,9 +56,9 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
56
56
  MySegmentsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
57
57
  try {
58
58
  if (changeNumber)
59
- this.storage.setItem(this.keys.buildTillKey(), changeNumber + '');
59
+ localStorage.setItem(this.keys.buildTillKey(), changeNumber + '');
60
60
  else
61
- this.storage.removeItem(this.keys.buildTillKey());
61
+ localStorage.removeItem(this.keys.buildTillKey());
62
62
  }
63
63
  catch (e) {
64
64
  this.log.error(e);
@@ -66,7 +66,7 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
66
66
  };
67
67
  MySegmentsCacheInLocal.prototype.getChangeNumber = function () {
68
68
  var n = -1;
69
- var value = this.storage.getItem(this.keys.buildTillKey());
69
+ var value = localStorage.getItem(this.keys.buildTillKey());
70
70
  if (value !== null) {
71
71
  value = parseInt(value, 10);
72
72
  return isNaNNumber(value) ? n : value;
@@ -3,27 +3,25 @@ import { setToArray } from '../../utils/lang/sets';
3
3
  import { usesSegments } from '../AbstractSplitsCacheSync';
4
4
  import { LOG_PREFIX } from './constants';
5
5
  var RBSegmentsCacheInLocal = /** @class */ (function () {
6
- function RBSegmentsCacheInLocal(settings, keys, storage) {
6
+ function RBSegmentsCacheInLocal(settings, keys) {
7
7
  this.keys = keys;
8
8
  this.log = settings.log;
9
- this.storage = storage;
10
9
  }
11
10
  RBSegmentsCacheInLocal.prototype.clear = function () {
12
11
  var _this = this;
13
12
  this.getNames().forEach(function (name) { return _this.remove(name); });
14
- this.storage.removeItem(this.keys.buildRBSegmentsTillKey());
13
+ localStorage.removeItem(this.keys.buildRBSegmentsTillKey());
15
14
  };
16
15
  RBSegmentsCacheInLocal.prototype.update = function (toAdd, toRemove, changeNumber) {
17
16
  var _this = this;
18
- var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
19
- updated = toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
20
17
  this.setChangeNumber(changeNumber);
21
- return updated;
18
+ var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
19
+ return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
22
20
  };
23
21
  RBSegmentsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
24
22
  try {
25
- this.storage.setItem(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
26
- this.storage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
23
+ localStorage.setItem(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
24
+ localStorage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
27
25
  }
28
26
  catch (e) {
29
27
  this.log.error(LOG_PREFIX + e);
@@ -31,19 +29,20 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
31
29
  };
32
30
  RBSegmentsCacheInLocal.prototype.updateSegmentCount = function (diff) {
33
31
  var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
34
- var count = toNumber(this.storage.getItem(segmentsCountKey)) + diff;
32
+ var count = toNumber(localStorage.getItem(segmentsCountKey)) + diff;
33
+ // @ts-expect-error
35
34
  if (count > 0)
36
- this.storage.setItem(segmentsCountKey, count + '');
35
+ localStorage.setItem(segmentsCountKey, count);
37
36
  else
38
- this.storage.removeItem(segmentsCountKey);
37
+ localStorage.removeItem(segmentsCountKey);
39
38
  };
40
39
  RBSegmentsCacheInLocal.prototype.add = function (rbSegment) {
41
40
  try {
42
41
  var name_1 = rbSegment.name;
43
42
  var rbSegmentKey = this.keys.buildRBSegmentKey(name_1);
44
- var rbSegmentFromStorage = this.storage.getItem(rbSegmentKey);
45
- var previous = rbSegmentFromStorage ? JSON.parse(rbSegmentFromStorage) : null;
46
- this.storage.setItem(rbSegmentKey, JSON.stringify(rbSegment));
43
+ var rbSegmentFromLocalStorage = localStorage.getItem(rbSegmentKey);
44
+ var previous = rbSegmentFromLocalStorage ? JSON.parse(rbSegmentFromLocalStorage) : null;
45
+ localStorage.setItem(rbSegmentKey, JSON.stringify(rbSegment));
47
46
  var usesSegmentsDiff = 0;
48
47
  if (previous && usesSegments(previous))
49
48
  usesSegmentsDiff--;
@@ -63,7 +62,7 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
63
62
  var rbSegment = this.get(name);
64
63
  if (!rbSegment)
65
64
  return false;
66
- this.storage.removeItem(this.keys.buildRBSegmentKey(name));
65
+ localStorage.removeItem(this.keys.buildRBSegmentKey(name));
67
66
  if (usesSegments(rbSegment))
68
67
  this.updateSegmentCount(-1);
69
68
  return true;
@@ -74,11 +73,11 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
74
73
  }
75
74
  };
76
75
  RBSegmentsCacheInLocal.prototype.getNames = function () {
77
- var len = this.storage.length;
76
+ var len = localStorage.length;
78
77
  var accum = [];
79
78
  var cur = 0;
80
79
  while (cur < len) {
81
- var key = this.storage.key(cur);
80
+ var key = localStorage.key(cur);
82
81
  if (key != null && this.keys.isRBSegmentKey(key))
83
82
  accum.push(this.keys.extractKey(key));
84
83
  cur++;
@@ -86,9 +85,13 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
86
85
  return accum;
87
86
  };
88
87
  RBSegmentsCacheInLocal.prototype.get = function (name) {
89
- var item = this.storage.getItem(this.keys.buildRBSegmentKey(name));
88
+ var item = localStorage.getItem(this.keys.buildRBSegmentKey(name));
90
89
  return item && JSON.parse(item);
91
90
  };
91
+ RBSegmentsCacheInLocal.prototype.getAll = function () {
92
+ var _this = this;
93
+ return this.getNames().map(function (key) { return _this.get(key); });
94
+ };
92
95
  RBSegmentsCacheInLocal.prototype.contains = function (names) {
93
96
  var namesArray = setToArray(names);
94
97
  var namesInStorage = this.getNames();
@@ -96,7 +99,7 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
96
99
  };
97
100
  RBSegmentsCacheInLocal.prototype.getChangeNumber = function () {
98
101
  var n = -1;
99
- var value = this.storage.getItem(this.keys.buildRBSegmentsTillKey());
102
+ var value = localStorage.getItem(this.keys.buildRBSegmentsTillKey());
100
103
  if (value !== null) {
101
104
  value = parseInt(value, 10);
102
105
  return isNaNNumber(value) ? n : value;
@@ -104,7 +107,7 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
104
107
  return n;
105
108
  };
106
109
  RBSegmentsCacheInLocal.prototype.usesSegments = function () {
107
- var storedCount = this.storage.getItem(this.keys.buildSplitsWithSegmentCountKey());
110
+ var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
108
111
  var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
109
112
  return isFiniteNumber(splitsWithSegmentsCount) ?
110
113
  splitsWithSegmentsCount > 0 :
@@ -3,22 +3,25 @@ import { AbstractSplitsCacheSync, usesSegments } from '../AbstractSplitsCacheSyn
3
3
  import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
4
4
  import { LOG_PREFIX } from './constants';
5
5
  import { setToArray } from '../../utils/lang/sets';
6
+ /**
7
+ * ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
8
+ */
6
9
  var SplitsCacheInLocal = /** @class */ (function (_super) {
7
10
  __extends(SplitsCacheInLocal, _super);
8
- function SplitsCacheInLocal(settings, keys, storage) {
11
+ function SplitsCacheInLocal(settings, keys) {
9
12
  var _this = _super.call(this) || this;
10
13
  _this.keys = keys;
11
14
  _this.log = settings.log;
12
15
  _this.flagSetsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
13
- _this.storage = storage;
14
16
  return _this;
15
17
  }
16
18
  SplitsCacheInLocal.prototype._decrementCount = function (key) {
17
- var count = toNumber(this.storage.getItem(key)) - 1;
19
+ var count = toNumber(localStorage.getItem(key)) - 1;
20
+ // @ts-expect-error
18
21
  if (count > 0)
19
- this.storage.setItem(key, count + '');
22
+ localStorage.setItem(key, count);
20
23
  else
21
- this.storage.removeItem(key);
24
+ localStorage.removeItem(key);
22
25
  };
23
26
  SplitsCacheInLocal.prototype._decrementCounts = function (split) {
24
27
  try {
@@ -36,10 +39,12 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
36
39
  SplitsCacheInLocal.prototype._incrementCounts = function (split) {
37
40
  try {
38
41
  var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
39
- this.storage.setItem(ttKey, (toNumber(this.storage.getItem(ttKey)) + 1) + '');
42
+ // @ts-expect-error
43
+ localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
40
44
  if (usesSegments(split)) {
41
45
  var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
42
- this.storage.setItem(segmentsCountKey, (toNumber(this.storage.getItem(segmentsCountKey)) + 1) + '');
46
+ // @ts-expect-error
47
+ localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
43
48
  }
44
49
  }
45
50
  catch (e) {
@@ -51,18 +56,17 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
51
56
  * We cannot simply call `localStorage.clear()` since that implies removing user items from the storage.
52
57
  */
53
58
  SplitsCacheInLocal.prototype.clear = function () {
54
- var _this = this;
55
59
  // collect item keys
56
- var len = this.storage.length;
60
+ var len = localStorage.length;
57
61
  var accum = [];
58
62
  for (var cur = 0; cur < len; cur++) {
59
- var key = this.storage.key(cur);
63
+ var key = localStorage.key(cur);
60
64
  if (key != null && this.keys.isSplitsCacheKey(key))
61
65
  accum.push(key);
62
66
  }
63
67
  // remove items
64
68
  accum.forEach(function (key) {
65
- _this.storage.removeItem(key);
69
+ localStorage.removeItem(key);
66
70
  });
67
71
  this.hasSync = false;
68
72
  };
@@ -70,13 +74,13 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
70
74
  try {
71
75
  var name_1 = split.name;
72
76
  var splitKey = this.keys.buildSplitKey(name_1);
73
- var splitFromStorage = this.storage.getItem(splitKey);
74
- var previousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : null;
77
+ var splitFromLocalStorage = localStorage.getItem(splitKey);
78
+ var previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
75
79
  if (previousSplit) {
76
80
  this._decrementCounts(previousSplit);
77
81
  this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
78
82
  }
79
- this.storage.setItem(splitKey, JSON.stringify(split));
83
+ localStorage.setItem(splitKey, JSON.stringify(split));
80
84
  this._incrementCounts(split);
81
85
  this.addToFlagSets(split);
82
86
  return true;
@@ -91,7 +95,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
91
95
  var split = this.getSplit(name);
92
96
  if (!split)
93
97
  return false;
94
- this.storage.removeItem(this.keys.buildSplitKey(name));
98
+ localStorage.removeItem(this.keys.buildSplitKey(name));
95
99
  this._decrementCounts(split);
96
100
  this.removeFromFlagSets(split.name, split.sets);
97
101
  return true;
@@ -102,14 +106,14 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
102
106
  }
103
107
  };
104
108
  SplitsCacheInLocal.prototype.getSplit = function (name) {
105
- var item = this.storage.getItem(this.keys.buildSplitKey(name));
109
+ var item = localStorage.getItem(this.keys.buildSplitKey(name));
106
110
  return item && JSON.parse(item);
107
111
  };
108
112
  SplitsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
109
113
  try {
110
- this.storage.setItem(this.keys.buildSplitsTillKey(), changeNumber + '');
114
+ localStorage.setItem(this.keys.buildSplitsTillKey(), changeNumber + '');
111
115
  // update "last updated" timestamp with current time
112
- this.storage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
116
+ localStorage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
113
117
  this.hasSync = true;
114
118
  return true;
115
119
  }
@@ -120,7 +124,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
120
124
  };
121
125
  SplitsCacheInLocal.prototype.getChangeNumber = function () {
122
126
  var n = -1;
123
- var value = this.storage.getItem(this.keys.buildSplitsTillKey());
127
+ var value = localStorage.getItem(this.keys.buildSplitsTillKey());
124
128
  if (value !== null) {
125
129
  value = parseInt(value, 10);
126
130
  return isNaNNumber(value) ? n : value;
@@ -128,11 +132,11 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
128
132
  return n;
129
133
  };
130
134
  SplitsCacheInLocal.prototype.getSplitNames = function () {
131
- var len = this.storage.length;
135
+ var len = localStorage.length;
132
136
  var accum = [];
133
137
  var cur = 0;
134
138
  while (cur < len) {
135
- var key = this.storage.key(cur);
139
+ var key = localStorage.key(cur);
136
140
  if (key != null && this.keys.isSplitKey(key))
137
141
  accum.push(this.keys.extractKey(key));
138
142
  cur++;
@@ -140,14 +144,14 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
140
144
  return accum;
141
145
  };
142
146
  SplitsCacheInLocal.prototype.trafficTypeExists = function (trafficType) {
143
- var ttCount = toNumber(this.storage.getItem(this.keys.buildTrafficTypeKey(trafficType)));
147
+ var ttCount = toNumber(localStorage.getItem(this.keys.buildTrafficTypeKey(trafficType)));
144
148
  return isFiniteNumber(ttCount) && ttCount > 0;
145
149
  };
146
150
  SplitsCacheInLocal.prototype.usesSegments = function () {
147
151
  // If cache hasn't been synchronized with the cloud, assume we need them.
148
152
  if (!this.hasSync)
149
153
  return true;
150
- var storedCount = this.storage.getItem(this.keys.buildSplitsWithSegmentCountKey());
154
+ var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
151
155
  var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
152
156
  return isFiniteNumber(splitsWithSegmentsCount) ?
153
157
  splitsWithSegmentsCount > 0 :
@@ -157,8 +161,8 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
157
161
  var _this = this;
158
162
  return flagSets.map(function (flagSet) {
159
163
  var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
160
- var flagSetFromStorage = _this.storage.getItem(flagSetKey);
161
- return new Set(flagSetFromStorage ? JSON.parse(flagSetFromStorage) : []);
164
+ var flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
165
+ return new Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
162
166
  });
163
167
  };
164
168
  SplitsCacheInLocal.prototype.addToFlagSets = function (featureFlag) {
@@ -169,10 +173,10 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
169
173
  if (_this.flagSetsFilter.length > 0 && !_this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === featureFlagSet; }))
170
174
  return;
171
175
  var flagSetKey = _this.keys.buildFlagSetKey(featureFlagSet);
172
- var flagSetFromStorage = _this.storage.getItem(flagSetKey);
173
- var flagSetCache = new Set(flagSetFromStorage ? JSON.parse(flagSetFromStorage) : []);
176
+ var flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
177
+ var flagSetCache = new Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
174
178
  flagSetCache.add(featureFlag.name);
175
- _this.storage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
179
+ localStorage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
176
180
  });
177
181
  };
178
182
  SplitsCacheInLocal.prototype.removeFromFlagSets = function (featureFlagName, flagSets) {
@@ -185,16 +189,16 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
185
189
  };
186
190
  SplitsCacheInLocal.prototype.removeNames = function (flagSetName, featureFlagName) {
187
191
  var flagSetKey = this.keys.buildFlagSetKey(flagSetName);
188
- var flagSetFromStorage = this.storage.getItem(flagSetKey);
189
- if (!flagSetFromStorage)
192
+ var flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
193
+ if (!flagSetFromLocalStorage)
190
194
  return;
191
- var flagSetCache = new Set(JSON.parse(flagSetFromStorage));
195
+ var flagSetCache = new Set(JSON.parse(flagSetFromLocalStorage));
192
196
  flagSetCache.delete(featureFlagName);
193
197
  if (flagSetCache.size === 0) {
194
- this.storage.removeItem(flagSetKey);
198
+ localStorage.removeItem(flagSetKey);
195
199
  return;
196
200
  }
197
- this.storage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
201
+ localStorage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
198
202
  };
199
203
  return SplitsCacheInLocal;
200
204
  }(AbstractSplitsCacheSync));
@@ -3,7 +3,7 @@ import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCache
3
3
  import { EventsCacheInMemory } from '../inMemory/EventsCacheInMemory';
4
4
  import { validatePrefix } from '../KeyBuilder';
5
5
  import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
6
- import { isLocalStorageAvailable, isValidStorageWrapper, isWebStorage } from '../../utils/env/isLocalStorageAvailable';
6
+ import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
7
7
  import { SplitsCacheInLocal } from './SplitsCacheInLocal';
8
8
  import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
9
9
  import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
@@ -14,20 +14,6 @@ import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/Telem
14
14
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
15
15
  import { getMatching } from '../../utils/key';
16
16
  import { validateCache } from './validateCache';
17
- import { storageAdapter } from './storageAdapter';
18
- function validateStorage(log, prefix, wrapper) {
19
- if (wrapper) {
20
- if (isValidStorageWrapper(wrapper)) {
21
- return isWebStorage(wrapper) ?
22
- wrapper : // localStorage and sessionStorage don't need adapter
23
- storageAdapter(log, prefix, wrapper);
24
- }
25
- log.warn(LOG_PREFIX + 'Invalid storage provided. Falling back to LocalStorage API');
26
- }
27
- if (isLocalStorageAvailable())
28
- return localStorage;
29
- log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
30
- }
31
17
  /**
32
18
  * InLocal storage factory for standalone client-side SplitFactory
33
19
  */
@@ -35,17 +21,18 @@ export function InLocalStorage(options) {
35
21
  if (options === void 0) { options = {}; }
36
22
  var prefix = validatePrefix(options.prefix);
37
23
  function InLocalStorageCSFactory(params) {
38
- var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
39
- var storage = validateStorage(log, prefix, options.wrapper);
40
- if (!storage)
24
+ // Fallback to InMemoryStorage if LocalStorage API is not available
25
+ if (!isLocalStorageAvailable()) {
26
+ params.settings.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
41
27
  return InMemoryStorageCSFactory(params);
28
+ }
29
+ var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
42
30
  var matchingKey = getMatching(settings.core.key);
43
31
  var keys = new KeyBuilderCS(prefix, matchingKey);
44
- var splits = new SplitsCacheInLocal(settings, keys, storage);
45
- var rbSegments = new RBSegmentsCacheInLocal(settings, keys, storage);
46
- var segments = new MySegmentsCacheInLocal(log, keys, storage);
47
- var largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey), storage);
48
- var validateCachePromise;
32
+ var splits = new SplitsCacheInLocal(settings, keys);
33
+ var rbSegments = new RBSegmentsCacheInLocal(settings, keys);
34
+ var segments = new MySegmentsCacheInLocal(log, keys);
35
+ var largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
49
36
  return {
50
37
  splits: splits,
51
38
  rbSegments: rbSegments,
@@ -57,18 +44,16 @@ export function InLocalStorage(options) {
57
44
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
58
45
  uniqueKeys: new UniqueKeysCacheInMemoryCS(),
59
46
  validateCache: function () {
60
- return validateCachePromise || (validateCachePromise = validateCache(options, storage, settings, keys, splits, rbSegments, segments, largeSegments));
61
- },
62
- destroy: function () {
63
- return storage.save && storage.save();
47
+ return validateCache(options, settings, keys, splits, rbSegments, segments, largeSegments);
64
48
  },
49
+ destroy: function () { },
65
50
  // When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
66
51
  shared: function (matchingKey) {
67
52
  return {
68
53
  splits: this.splits,
69
54
  rbSegments: this.rbSegments,
70
- segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey), storage),
71
- largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey), storage),
55
+ segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
56
+ largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
72
57
  impressions: this.impressions,
73
58
  impressionCounts: this.impressionCounts,
74
59
  events: this.events,