@splitsoftware/splitio-commons 1.17.1-rc.3 → 2.0.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 (216) hide show
  1. package/CHANGES.txt +7 -3
  2. package/cjs/evaluator/index.js +2 -2
  3. package/cjs/evaluator/matchers/semver_inlist.js +1 -2
  4. package/cjs/evaluator/matchers/whitelist.js +1 -2
  5. package/cjs/listeners/browser.js +1 -2
  6. package/cjs/logger/browser/DebugLogger.js +1 -2
  7. package/cjs/logger/browser/ErrorLogger.js +1 -2
  8. package/cjs/logger/browser/InfoLogger.js +1 -2
  9. package/cjs/logger/browser/WarnLogger.js +1 -2
  10. package/cjs/logger/index.js +1 -2
  11. package/cjs/readiness/readinessManager.js +5 -7
  12. package/cjs/sdkClient/clientCS.js +5 -8
  13. package/cjs/sdkClient/sdkClientMethodCS.js +5 -8
  14. package/cjs/sdkFactory/index.js +10 -33
  15. package/cjs/services/decorateHeaders.js +1 -2
  16. package/cjs/storages/AbstractSplitsCacheAsync.js +7 -0
  17. package/cjs/storages/AbstractSplitsCacheSync.js +7 -0
  18. package/cjs/storages/KeyBuilderCS.js +0 -9
  19. package/cjs/storages/dataLoader.js +32 -64
  20. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -21
  21. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +14 -7
  22. package/cjs/storages/inLocalStorage/index.js +1 -6
  23. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -16
  24. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +3 -4
  25. package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -3
  26. package/cjs/storages/inMemory/UniqueKeysCacheInMemory.js +2 -3
  27. package/cjs/storages/inMemory/UniqueKeysCacheInMemoryCS.js +2 -3
  28. package/cjs/storages/inRedis/RedisAdapter.js +3 -4
  29. package/cjs/storages/inRedis/SplitsCacheInRedis.js +1 -1
  30. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +3 -4
  31. package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +1 -2
  32. package/cjs/storages/pluggable/SplitsCachePluggable.js +1 -1
  33. package/cjs/storages/pluggable/TelemetryCachePluggable.js +6 -7
  34. package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +1 -2
  35. package/cjs/storages/pluggable/inMemoryWrapper.js +7 -8
  36. package/cjs/storages/pluggable/index.js +32 -37
  37. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +7 -2
  38. package/cjs/sync/polling/pollingManagerSS.js +3 -3
  39. package/cjs/sync/polling/updaters/splitChangesUpdater.js +13 -5
  40. package/cjs/sync/streaming/parseUtils.js +0 -1
  41. package/cjs/sync/streaming/pushManager.js +2 -3
  42. package/cjs/trackers/eventTracker.js +9 -11
  43. package/cjs/trackers/impressionsTracker.js +13 -15
  44. package/cjs/trackers/uniqueKeysTracker.js +3 -5
  45. package/cjs/utils/LRUCache/index.js +1 -2
  46. package/cjs/utils/constants/browser.js +1 -4
  47. package/cjs/utils/lang/index.js +6 -9
  48. package/cjs/utils/lang/objectAssign.js +12 -77
  49. package/cjs/utils/lang/sets.js +3 -110
  50. package/cjs/utils/settingsValidation/index.js +0 -9
  51. package/cjs/utils/settingsValidation/logger/builtinLogger.js +1 -2
  52. package/cjs/utils/settingsValidation/storage/storageCS.js +12 -1
  53. package/esm/evaluator/index.js +3 -3
  54. package/esm/evaluator/matchers/semver_inlist.js +1 -2
  55. package/esm/evaluator/matchers/whitelist.js +1 -2
  56. package/esm/listeners/browser.js +1 -2
  57. package/esm/logger/browser/DebugLogger.js +1 -2
  58. package/esm/logger/browser/ErrorLogger.js +1 -2
  59. package/esm/logger/browser/InfoLogger.js +1 -2
  60. package/esm/logger/browser/WarnLogger.js +1 -2
  61. package/esm/logger/index.js +1 -2
  62. package/esm/readiness/readinessManager.js +5 -7
  63. package/esm/sdkClient/clientCS.js +5 -8
  64. package/esm/sdkClient/sdkClientMethodCS.js +5 -8
  65. package/esm/sdkFactory/index.js +11 -34
  66. package/esm/services/decorateHeaders.js +1 -2
  67. package/esm/storages/AbstractSplitsCacheAsync.js +7 -0
  68. package/esm/storages/AbstractSplitsCacheSync.js +7 -0
  69. package/esm/storages/KeyBuilderCS.js +0 -9
  70. package/esm/storages/dataLoader.js +30 -61
  71. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -21
  72. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +14 -7
  73. package/esm/storages/inLocalStorage/index.js +2 -7
  74. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -16
  75. package/esm/storages/inMemory/SegmentsCacheInMemory.js +3 -4
  76. package/esm/storages/inMemory/SplitsCacheInMemory.js +2 -3
  77. package/esm/storages/inMemory/UniqueKeysCacheInMemory.js +2 -3
  78. package/esm/storages/inMemory/UniqueKeysCacheInMemoryCS.js +2 -3
  79. package/esm/storages/inRedis/RedisAdapter.js +3 -4
  80. package/esm/storages/inRedis/SplitsCacheInRedis.js +2 -2
  81. package/esm/storages/inRedis/TelemetryCacheInRedis.js +3 -4
  82. package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -2
  83. package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
  84. package/esm/storages/pluggable/TelemetryCachePluggable.js +6 -7
  85. package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -2
  86. package/esm/storages/pluggable/inMemoryWrapper.js +7 -8
  87. package/esm/storages/pluggable/index.js +32 -37
  88. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +8 -3
  89. package/esm/sync/polling/pollingManagerSS.js +3 -3
  90. package/esm/sync/polling/updaters/splitChangesUpdater.js +14 -6
  91. package/esm/sync/streaming/parseUtils.js +0 -1
  92. package/esm/sync/streaming/pushManager.js +2 -3
  93. package/esm/trackers/eventTracker.js +9 -11
  94. package/esm/trackers/impressionsTracker.js +13 -15
  95. package/esm/trackers/uniqueKeysTracker.js +3 -5
  96. package/esm/utils/LRUCache/index.js +1 -2
  97. package/esm/utils/constants/browser.js +0 -3
  98. package/esm/utils/lang/index.js +6 -9
  99. package/esm/utils/lang/objectAssign.js +12 -77
  100. package/esm/utils/lang/sets.js +2 -107
  101. package/esm/utils/settingsValidation/index.js +0 -9
  102. package/esm/utils/settingsValidation/logger/builtinLogger.js +1 -2
  103. package/esm/utils/settingsValidation/storage/storageCS.js +10 -0
  104. package/package.json +2 -2
  105. package/src/evaluator/index.ts +5 -5
  106. package/src/evaluator/matchers/semver_inlist.ts +1 -2
  107. package/src/evaluator/matchers/whitelist.ts +1 -3
  108. package/src/listeners/browser.ts +1 -2
  109. package/src/logger/browser/DebugLogger.ts +1 -2
  110. package/src/logger/browser/ErrorLogger.ts +1 -2
  111. package/src/logger/browser/InfoLogger.ts +1 -2
  112. package/src/logger/browser/WarnLogger.ts +1 -2
  113. package/src/logger/index.ts +3 -4
  114. package/src/readiness/readinessManager.ts +7 -9
  115. package/src/readiness/types.ts +0 -1
  116. package/src/sdkClient/clientCS.ts +5 -8
  117. package/src/sdkClient/sdkClientMethodCS.ts +3 -6
  118. package/src/sdkFactory/index.ts +12 -37
  119. package/src/sdkFactory/types.ts +1 -4
  120. package/src/services/decorateHeaders.ts +1 -2
  121. package/src/storages/AbstractSplitsCacheAsync.ts +9 -2
  122. package/src/storages/AbstractSplitsCacheSync.ts +9 -2
  123. package/src/storages/KeyBuilderCS.ts +0 -13
  124. package/src/storages/dataLoader.ts +32 -62
  125. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +1 -21
  126. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +16 -8
  127. package/src/storages/inLocalStorage/index.ts +2 -8
  128. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -19
  129. package/src/storages/inMemory/SegmentsCacheInMemory.ts +4 -5
  130. package/src/storages/inMemory/SplitsCacheInMemory.ts +4 -5
  131. package/src/storages/inMemory/UniqueKeysCacheInMemory.ts +4 -5
  132. package/src/storages/inMemory/UniqueKeysCacheInMemoryCS.ts +4 -5
  133. package/src/storages/inRedis/RedisAdapter.ts +4 -5
  134. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -3
  135. package/src/storages/inRedis/TelemetryCacheInRedis.ts +3 -4
  136. package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +1 -2
  137. package/src/storages/pluggable/SegmentsCachePluggable.ts +0 -1
  138. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -3
  139. package/src/storages/pluggable/TelemetryCachePluggable.ts +6 -7
  140. package/src/storages/pluggable/UniqueKeysCachePluggable.ts +1 -2
  141. package/src/storages/pluggable/inMemoryWrapper.ts +8 -9
  142. package/src/storages/pluggable/index.ts +33 -38
  143. package/src/storages/types.ts +9 -6
  144. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +7 -3
  145. package/src/sync/polling/pollingManagerSS.ts +2 -3
  146. package/src/sync/polling/updaters/splitChangesUpdater.ts +15 -8
  147. package/src/sync/streaming/parseUtils.ts +0 -1
  148. package/src/sync/streaming/pushManager.ts +3 -4
  149. package/src/sync/submitters/types.ts +3 -4
  150. package/src/trackers/eventTracker.ts +7 -10
  151. package/src/trackers/impressionsTracker.ts +9 -12
  152. package/src/trackers/types.ts +0 -1
  153. package/src/trackers/uniqueKeysTracker.ts +4 -6
  154. package/src/types.ts +9 -18
  155. package/src/utils/LRUCache/index.ts +2 -3
  156. package/src/utils/constants/browser.ts +0 -4
  157. package/src/utils/lang/index.ts +6 -7
  158. package/src/utils/lang/objectAssign.ts +13 -92
  159. package/src/utils/lang/sets.ts +3 -125
  160. package/src/utils/settingsValidation/index.ts +0 -10
  161. package/src/utils/settingsValidation/logger/builtinLogger.ts +1 -2
  162. package/src/utils/settingsValidation/storage/storageCS.ts +13 -0
  163. package/src/utils/settingsValidation/types.ts +0 -2
  164. package/types/logger/index.d.ts +1 -2
  165. package/types/readiness/types.d.ts +0 -1
  166. package/types/sdkClient/clientCS.d.ts +2 -3
  167. package/types/sdkFactory/types.d.ts +1 -3
  168. package/types/storages/AbstractSplitsCacheAsync.d.ts +6 -2
  169. package/types/storages/AbstractSplitsCacheSync.d.ts +6 -2
  170. package/types/storages/KeyBuilderCS.d.ts +0 -2
  171. package/types/storages/dataLoader.d.ts +6 -17
  172. package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +7 -2
  173. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -2
  174. package/types/storages/inMemory/UniqueKeysCacheInMemory.d.ts +2 -3
  175. package/types/storages/inRedis/SplitsCacheInRedis.d.ts +1 -2
  176. package/types/storages/pluggable/SplitsCachePluggable.d.ts +1 -2
  177. package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -2
  178. package/types/storages/types.d.ts +7 -6
  179. package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -2
  180. package/types/sync/submitters/types.d.ts +3 -4
  181. package/types/trackers/eventTracker.d.ts +1 -1
  182. package/types/trackers/impressionsTracker.d.ts +1 -1
  183. package/types/trackers/types.d.ts +0 -1
  184. package/types/types.d.ts +9 -17
  185. package/types/utils/LRUCache/index.d.ts +1 -2
  186. package/types/utils/constants/browser.d.ts +0 -2
  187. package/types/utils/lang/objectAssign.d.ts +3 -0
  188. package/types/utils/lang/sets.d.ts +1 -61
  189. package/types/utils/settingsValidation/index.d.ts +0 -1
  190. package/types/utils/settingsValidation/storage/storageCS.d.ts +5 -0
  191. package/types/utils/settingsValidation/types.d.ts +0 -2
  192. package/cjs/integrations/browser.js +0 -31
  193. package/cjs/integrations/ga/GaToSplit.js +0 -257
  194. package/cjs/integrations/ga/GoogleAnalyticsToSplit.js +0 -14
  195. package/cjs/integrations/ga/SplitToGa.js +0 -123
  196. package/cjs/integrations/ga/SplitToGoogleAnalytics.js +0 -14
  197. package/cjs/integrations/ga/types.js +0 -2
  198. package/cjs/sdkClient/sdkClientMethodCSWithTT.js +0 -79
  199. package/cjs/utils/lang/maps.js +0 -96
  200. package/esm/integrations/browser.js +0 -27
  201. package/esm/integrations/ga/GaToSplit.js +0 -250
  202. package/esm/integrations/ga/GoogleAnalyticsToSplit.js +0 -10
  203. package/esm/integrations/ga/SplitToGa.js +0 -120
  204. package/esm/integrations/ga/SplitToGoogleAnalytics.js +0 -10
  205. package/esm/integrations/ga/types.js +0 -1
  206. package/esm/sdkClient/sdkClientMethodCSWithTT.js +0 -75
  207. package/esm/utils/lang/maps.js +0 -92
  208. package/src/integrations/browser.ts +0 -35
  209. package/src/integrations/ga/GaToSplit.ts +0 -299
  210. package/src/integrations/ga/GoogleAnalyticsToSplit.ts +0 -14
  211. package/src/integrations/ga/SplitToGa.ts +0 -135
  212. package/src/integrations/ga/SplitToGoogleAnalytics.ts +0 -14
  213. package/src/integrations/ga/autoRequire.js +0 -33
  214. package/src/integrations/ga/types.ts +0 -153
  215. package/src/sdkClient/sdkClientMethodCSWithTT.ts +0 -101
  216. package/src/utils/lang/maps.ts +0 -108
@@ -50,7 +50,6 @@ export interface ISdkFactoryContext {
50
50
  splitApi?: ISplitApi
51
51
  syncManager?: ISyncManager,
52
52
  clients: Record<string, IBasicClient>,
53
- whenInit(cb: () => void): void
54
53
  }
55
54
 
56
55
  export interface ISdkFactoryContextSync extends ISdkFactoryContext {
@@ -69,8 +68,6 @@ export interface ISdkFactoryContextAsync extends ISdkFactoryContext {
69
68
  * Object parameter with the modules required to create an SDK factory instance
70
69
  */
71
70
  export interface ISdkFactoryParams {
72
- // If true, the `sdkFactory` is pure (no side effects), and the SDK instance includes a `init` method to run initialization side effects
73
- isPure?: boolean,
74
71
 
75
72
  // The settings must be already validated
76
73
  settings: ISettings,
@@ -96,7 +93,7 @@ export interface ISdkFactoryParams {
96
93
 
97
94
  // Sdk client method factory (ISDK::client method).
98
95
  // It Allows to distinguish SDK clients with the client-side API (`ICsSDK`) or server-side API (`ISDK` or `IAsyncSDK`).
99
- sdkClientMethodFactory: (params: ISdkFactoryContext) => ({ (): SplitIO.ICsClient; (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient; } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient))
96
+ sdkClientMethodFactory: (params: ISdkFactoryContext) => ({ (): SplitIO.ICsClient; (key: SplitIO.SplitKey): SplitIO.ICsClient; } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient))
100
97
 
101
98
  // Impression observer factory.
102
99
  impressionsObserverFactory: () => IImpressionObserver
@@ -1,8 +1,7 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
- import { _Set } from '../utils/lang/sets';
3
2
  import { ISettings } from '../types';
4
3
 
5
- const FORBIDDEN_HEADERS = new _Set([
4
+ const FORBIDDEN_HEADERS = new Set([
6
5
  'splitsdkclientkey',
7
6
  'splitsdkversion',
8
7
  'splitsdkmachineip',
@@ -1,7 +1,6 @@
1
1
  import { ISplitsCacheAsync } from './types';
2
2
  import { ISplit } from '../dtos/types';
3
3
  import { objectAssign } from '../utils/lang/objectAssign';
4
- import { ISet } from '../utils/lang/sets';
5
4
 
6
5
  /**
7
6
  * This class provides a skeletal implementation of the ISplitsCacheAsync interface
@@ -18,7 +17,7 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
18
17
  abstract getChangeNumber(): Promise<number>
19
18
  abstract getAll(): Promise<ISplit[]>
20
19
  abstract getSplitNames(): Promise<string[]>
21
- abstract getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>
20
+ abstract getNamesByFlagSets(flagSets: string[]): Promise<Set<string>[]>
22
21
  abstract trafficTypeExists(trafficType: string): Promise<boolean>
23
22
  abstract clear(): Promise<boolean | void>
24
23
 
@@ -28,6 +27,14 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
28
27
  return Promise.resolve(true);
29
28
  }
30
29
 
30
+ /**
31
+ * Check if the splits information is already stored in cache.
32
+ * Noop, just keeping the interface. This is used by client-side implementations only.
33
+ */
34
+ checkCache(): Promise<boolean> {
35
+ return Promise.resolve(false);
36
+ }
37
+
31
38
  /**
32
39
  * Kill `name` split and set `defaultTreatment` and `changeNumber`.
33
40
  * Used for SPLIT_KILL push notifications.
@@ -1,7 +1,6 @@
1
1
  import { ISplitsCacheSync } from './types';
2
2
  import { ISplit } from '../dtos/types';
3
3
  import { objectAssign } from '../utils/lang/objectAssign';
4
- import { ISet } from '../utils/lang/sets';
5
4
  import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
6
5
 
7
6
  /**
@@ -48,6 +47,14 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
48
47
 
49
48
  abstract clear(): void
50
49
 
50
+ /**
51
+ * Check if the splits information is already stored in cache. This data can be preloaded.
52
+ * It is used as condition to emit SDK_SPLITS_CACHE_LOADED, and then SDK_READY_FROM_CACHE.
53
+ */
54
+ checkCache(): boolean {
55
+ return false;
56
+ }
57
+
51
58
  /**
52
59
  * Kill `name` split and set `defaultTreatment` and `changeNumber`.
53
60
  * Used for SPLIT_KILL push notifications.
@@ -72,7 +79,7 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
72
79
  return false;
73
80
  }
74
81
 
75
- abstract getNamesByFlagSets(flagSets: string[]): ISet<string>[]
82
+ abstract getNamesByFlagSets(flagSets: string[]): Set<string>[]
76
83
 
77
84
  }
78
85
 
@@ -4,7 +4,6 @@ import { KeyBuilder } from './KeyBuilder';
4
4
  export interface MySegmentsKeyBuilder {
5
5
  buildSegmentNameKey(segmentName: string): string;
6
6
  extractSegmentName(builtSegmentKeyName: string): string | undefined;
7
- extractOldSegmentKey(builtSegmentKeyName: string): string | undefined;
8
7
  buildTillKey(): string;
9
8
  }
10
9
 
@@ -33,14 +32,6 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
33
32
  return builtSegmentKeyName.substr(prefix.length);
34
33
  }
35
34
 
36
- // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
37
- extractOldSegmentKey(builtSegmentKeyName: string) {
38
- const prefix = `${this.matchingKey}.${this.prefix}.segment.`;
39
-
40
- if (startsWith(builtSegmentKeyName, prefix))
41
- return builtSegmentKeyName.substr(prefix.length);
42
- }
43
-
44
35
  buildLastUpdatedKey() {
45
36
  return `${this.prefix}.splits.lastUpdated`;
46
37
  }
@@ -66,10 +57,6 @@ export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string):
66
57
  if (startsWith(builtSegmentKeyName, p)) return builtSegmentKeyName.substr(p.length);
67
58
  },
68
59
 
69
- extractOldSegmentKey() {
70
- return undefined;
71
- },
72
-
73
60
  buildTillKey() {
74
61
  return `${prefix}.${matchingKey}.largeSegments.till`;
75
62
  }
@@ -1,85 +1,55 @@
1
1
  import { SplitIO } from '../types';
2
- import { ISegmentsCacheSync, ISplitsCacheSync, IStorageSync } from './types';
3
- import { setToArray, ISet } from '../utils/lang/sets';
4
- import { getMatching } from '../utils/key';
2
+ import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../utils/constants/browser';
3
+ import { DataLoader, ISegmentsCacheSync, ISplitsCacheSync } from './types';
5
4
 
6
5
  /**
7
- * Storage-agnostic adaptation of `loadDataIntoLocalStorage` function
8
- * (https://github.com/godaddy/split-javascript-data-loader/blob/master/src/load-data.js)
6
+ * Factory of client-side storage loader
9
7
  *
10
- * @param preloadedData validated data following the format proposed in https://github.com/godaddy/split-javascript-data-loader and extended with a `mySegmentsData` property.
11
- * @param storage object containing `splits` and `segments` cache (client-side variant)
12
- * @param userKey user key (matching key) of the provided MySegmentsCache
13
- *
14
- * @TODO extend to load largeSegments
15
- * @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.
16
- * @TODO add logs, and input validation in this module, in favor of size reduction.
17
- * @TODO unit tests
8
+ * @param preloadedData validated data following the format proposed in https://github.com/godaddy/split-javascript-data-loader
9
+ * and extended with a `mySegmentsData` property.
10
+ * @returns function to preload the storage
18
11
  */
19
- export function loadData(preloadedData: SplitIO.PreloadedData, storage: { splits?: ISplitsCacheSync, segments: ISegmentsCacheSync, largeSegments?: ISegmentsCacheSync }, matchingKey?: string) {
20
- // Do not load data if current preloadedData is empty
21
- if (Object.keys(preloadedData).length === 0) return;
22
-
23
- const { segmentsData = {}, since = -1, splitsData = [] } = preloadedData;
12
+ export function dataLoaderFactory(preloadedData: SplitIO.PreloadedData): DataLoader {
13
+
14
+ /**
15
+ * Storage-agnostic adaptation of `loadDataIntoLocalStorage` function
16
+ * (https://github.com/godaddy/split-javascript-data-loader/blob/master/src/load-data.js)
17
+ *
18
+ * @param storage object containing `splits` and `segments` cache (client-side variant)
19
+ * @param userId user key string of the provided MySegmentsCache
20
+ *
21
+ * @TODO extend to support SegmentsCache (server-side variant) by making `userId` optional and adding the corresponding logic.
22
+ * @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.
23
+ */
24
+ return function loadData(storage: { splits: ISplitsCacheSync, segments: ISegmentsCacheSync }, userId: string) {
25
+ // Do not load data if current preloadedData is empty
26
+ if (Object.keys(preloadedData).length === 0) return;
27
+
28
+ const { lastUpdated = -1, segmentsData = {}, since = -1, splitsData = {} } = preloadedData;
24
29
 
25
- if (storage.splits) {
26
30
  const storedSince = storage.splits.getChangeNumber();
31
+ const expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
27
32
 
28
- // Do not load data if current data is more recent
29
- if (storedSince > since) return;
33
+ // Do not load data if current localStorage data is more recent,
34
+ // or if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
35
+ if (storedSince > since || lastUpdated < expirationTimestamp) return;
30
36
 
31
37
  // cleaning up the localStorage data, since some cached splits might need be part of the preloaded data
32
38
  storage.splits.clear();
33
39
  storage.splits.setChangeNumber(since);
34
40
 
35
41
  // splitsData in an object where the property is the split name and the pertaining value is a stringified json of its data
36
- storage.splits.addSplits(splitsData.map(split => ([split.name, split])));
37
- }
42
+ storage.splits.addSplits(Object.keys(splitsData).map(splitName => JSON.parse(splitsData[splitName])));
38
43
 
39
- if (matchingKey) { // add mySegments data (client-side)
40
- let mySegmentsData = preloadedData.mySegmentsData && preloadedData.mySegmentsData[matchingKey];
44
+ // add mySegments data
45
+ let mySegmentsData = preloadedData.mySegmentsData && preloadedData.mySegmentsData[userId];
41
46
  if (!mySegmentsData) {
42
47
  // 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
43
48
  mySegmentsData = Object.keys(segmentsData).filter(segmentName => {
44
- const matchingKeys = segmentsData[segmentName];
45
- return matchingKeys.indexOf(matchingKey) > -1;
49
+ const userIds = JSON.parse(segmentsData[segmentName]).added;
50
+ return Array.isArray(userIds) && userIds.indexOf(userId) > -1;
46
51
  });
47
52
  }
48
53
  storage.segments.resetSegments({ k: mySegmentsData.map(s => ({ n: s })) });
49
- } else { // add segments data (server-side)
50
- Object.keys(segmentsData).filter(segmentName => {
51
- const matchingKeys = segmentsData[segmentName];
52
- storage.segments.addToSegment(segmentName, matchingKeys);
53
- });
54
- }
55
- }
56
-
57
- export function getSnapshot(storage: IStorageSync, userKeys?: SplitIO.SplitKey[]): SplitIO.PreloadedData {
58
- return {
59
- // lastUpdated: Date.now(),
60
- since: storage.splits.getChangeNumber(),
61
- splitsData: storage.splits.getAll(),
62
- segmentsData: userKeys ?
63
- undefined : // @ts-ignore accessing private prop
64
- Object.keys(storage.segments.segmentCache).reduce((prev, cur) => { // @ts-ignore accessing private prop
65
- prev[cur] = setToArray(storage.segments.segmentCache[cur] as ISet<string>);
66
- return prev;
67
- }, {}),
68
- mySegmentsData: userKeys ?
69
- userKeys.reduce<Record<string, string[]>>((prev, userKey) => {
70
- prev[getMatching(userKey)] = storage.shared ?
71
- // Client-side segments
72
- // @ts-ignore accessing private prop
73
- Object.keys(storage.shared(userKey).segments.segmentCache) :
74
- // Server-side segments
75
- // @ts-ignore accessing private prop
76
- Object.keys(storage.segments.segmentCache).reduce<string[]>((prev, segmentName) => { // @ts-ignore accessing private prop
77
- return storage.segments.segmentCache[segmentName].has(userKey) ?
78
- prev.concat(segmentName) :
79
- prev;
80
- }, []);
81
- return prev;
82
- }, {}) :
83
- undefined
84
54
  };
85
55
  }
@@ -51,27 +51,7 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
51
51
  return Object.keys(localStorage).reduce((accum, key) => {
52
52
  let segmentName = this.keys.extractSegmentName(key);
53
53
 
54
- if (segmentName) {
55
- accum.push(segmentName);
56
- } else {
57
- // @TODO @BREAKING: This is only to clean up "old" keys. Remove this whole else code block
58
- segmentName = this.keys.extractOldSegmentKey(key);
59
-
60
- if (segmentName) { // this was an old segment key, let's clean up.
61
- const newSegmentKey = this.keys.buildSegmentNameKey(segmentName);
62
- try {
63
- // If the new format key is not there, create it.
64
- if (!localStorage.getItem(newSegmentKey)) {
65
- localStorage.setItem(newSegmentKey, DEFINED);
66
- // we are migrating a segment, let's track it.
67
- accum.push(segmentName);
68
- }
69
- localStorage.removeItem(key); // we migrated the current key, let's delete it.
70
- } catch (e) {
71
- this.log.error(e);
72
- }
73
- }
74
- }
54
+ if (segmentName) accum.push(segmentName);
75
55
 
76
56
  return accum;
77
57
  }, [] as string[]);
@@ -4,7 +4,6 @@ import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
4
4
  import { KeyBuilderCS } from '../KeyBuilderCS';
5
5
  import { ILogger } from '../../logger/types';
6
6
  import { LOG_PREFIX } from './constants';
7
- import { ISet, _Set, setToArray } from '../../utils/lang/sets';
8
7
  import { ISettings } from '../../types';
9
8
  import { getStorageHash } from '../KeyBuilder';
10
9
 
@@ -217,6 +216,15 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
217
216
  }
218
217
  }
219
218
 
219
+ /**
220
+ * Check if the splits information is already stored in browser LocalStorage.
221
+ * In this function we could add more code to check if the data is valid.
222
+ * @override
223
+ */
224
+ checkCache(): boolean {
225
+ return this.getChangeNumber() > -1;
226
+ }
227
+
220
228
  /**
221
229
  * Clean Splits cache if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
222
230
  *
@@ -241,7 +249,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
241
249
  this.updateNewFilter = true;
242
250
 
243
251
  // if there is cache, clear it
244
- if (this.getChangeNumber() > -1) this.clear();
252
+ if (this.checkCache()) this.clear();
245
253
 
246
254
  } catch (e) {
247
255
  this.log.error(LOG_PREFIX + e);
@@ -250,12 +258,12 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
250
258
  // if the filter didn't change, nothing is done
251
259
  }
252
260
 
253
- getNamesByFlagSets(flagSets: string[]): ISet<string>[] {
261
+ getNamesByFlagSets(flagSets: string[]): Set<string>[] {
254
262
  return flagSets.map(flagSet => {
255
263
  const flagSetKey = this.keys.buildFlagSetKey(flagSet);
256
264
  const flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
257
265
 
258
- return new _Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
266
+ return new Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
259
267
  });
260
268
  }
261
269
 
@@ -270,10 +278,10 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
270
278
 
271
279
  const flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
272
280
 
273
- const flagSetCache = new _Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
281
+ const flagSetCache = new Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
274
282
  flagSetCache.add(featureFlag.name);
275
283
 
276
- localStorage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
284
+ localStorage.setItem(flagSetKey, JSON.stringify(Array.from(flagSetCache)));
277
285
  });
278
286
  }
279
287
 
@@ -292,7 +300,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
292
300
 
293
301
  if (!flagSetFromLocalStorage) return;
294
302
 
295
- const flagSetCache = new _Set(JSON.parse(flagSetFromLocalStorage));
303
+ const flagSetCache = new Set(JSON.parse(flagSetFromLocalStorage));
296
304
  flagSetCache.delete(featureFlagName);
297
305
 
298
306
  if (flagSetCache.size === 0) {
@@ -300,7 +308,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
300
308
  return;
301
309
  }
302
310
 
303
- localStorage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
311
+ localStorage.setItem(flagSetKey, JSON.stringify(Array.from(flagSetCache)));
304
312
  }
305
313
 
306
314
  }
@@ -12,7 +12,7 @@ import { SplitsCacheInMemory } from '../inMemory/SplitsCacheInMemory';
12
12
  import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
13
13
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
14
14
  import { LOG_PREFIX } from './constants';
15
- import { DEBUG, LOCALHOST_MODE, NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
15
+ import { DEBUG, NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
16
16
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
17
17
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
18
18
  import { getMatching } from '../../utils/key';
@@ -36,7 +36,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
36
36
  return InMemoryStorageCSFactory(params);
37
37
  }
38
38
 
39
- const { onReadyFromCacheCb, settings, settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
39
+ const { settings, settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
40
40
  const matchingKey = getMatching(settings.core.key);
41
41
  const keys = new KeyBuilderCS(prefix, matchingKey);
42
42
  const expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
@@ -55,12 +55,6 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
55
55
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
56
56
  uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
57
57
 
58
- init() {
59
- if (settings.mode === LOCALHOST_MODE || splits.getChangeNumber() > -1) {
60
- Promise.resolve().then(onReadyFromCacheCb);
61
- }
62
- },
63
-
64
58
  destroy() {
65
59
  this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
66
60
  this.segments = new MySegmentsCacheInMemory();
@@ -7,8 +7,6 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
7
7
  import { DEBUG, LOCALHOST_MODE, NONE, 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 { loadData } from '../dataLoader';
12
10
 
13
11
  /**
14
12
  * InMemory storage factory for standalone client-side SplitFactory
@@ -16,7 +14,7 @@ import { loadData } from '../dataLoader';
16
14
  * @param params parameters required by EventsCacheSync
17
15
  */
18
16
  export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorageSync {
19
- const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation }, preloadedData }, onReadyFromCacheCb } = params;
17
+ const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
20
18
 
21
19
  const splits = new SplitsCacheInMemory(__splitFiltersValidation);
22
20
  const segments = new MySegmentsCacheInMemory();
@@ -44,18 +42,11 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
44
42
  },
45
43
 
46
44
  // When using shared instanciation with MEMORY we reuse everything but segments (they are unique per key)
47
- shared(matchingKey: string) {
48
- const segments = new MySegmentsCacheInMemory();
49
- const largeSegments = new MySegmentsCacheInMemory();
50
-
51
- if (preloadedData) {
52
- loadData(preloadedData, { segments, largeSegments }, matchingKey);
53
- }
54
-
45
+ shared() {
55
46
  return {
56
47
  splits: this.splits,
57
- segments,
58
- largeSegments,
48
+ segments: new MySegmentsCacheInMemory(),
49
+ largeSegments: new MySegmentsCacheInMemory(),
59
50
  impressions: this.impressions,
60
51
  impressionCounts: this.impressionCounts,
61
52
  events: this.events,
@@ -81,12 +72,6 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
81
72
  if (storage.uniqueKeys) storage.uniqueKeys.track = noopTrack;
82
73
  }
83
74
 
84
-
85
- if (preloadedData) {
86
- loadData(preloadedData, storage, getMatching(params.settings.core.key));
87
- if (splits.getChangeNumber() > -1) onReadyFromCacheCb();
88
- }
89
-
90
75
  return storage;
91
76
  }
92
77
 
@@ -1,5 +1,4 @@
1
1
  import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
2
- import { ISet, _Set } from '../../utils/lang/sets';
3
2
  import { isIntegerNumber } from '../../utils/lang';
4
3
 
5
4
  /**
@@ -8,12 +7,12 @@ import { isIntegerNumber } from '../../utils/lang';
8
7
  */
9
8
  export class SegmentsCacheInMemory extends AbstractSegmentsCacheSync {
10
9
 
11
- private segmentCache: Record<string, ISet<string>> = {};
10
+ private segmentCache: Record<string, Set<string>> = {};
12
11
  private segmentChangeNumber: Record<string, number> = {};
13
12
 
14
13
  addToSegment(name: string, segmentKeys: string[]): boolean {
15
14
  const values = this.segmentCache[name];
16
- const keySet = values ? values : new _Set<string>();
15
+ const keySet = values ? values : new Set<string>();
17
16
 
18
17
  segmentKeys.forEach(k => keySet.add(k));
19
18
 
@@ -24,7 +23,7 @@ export class SegmentsCacheInMemory extends AbstractSegmentsCacheSync {
24
23
 
25
24
  removeFromSegment(name: string, segmentKeys: string[]): boolean {
26
25
  const values = this.segmentCache[name];
27
- const keySet = values ? values : new _Set<string>();
26
+ const keySet = values ? values : new Set<string>();
28
27
 
29
28
  segmentKeys.forEach(k => keySet.delete(k));
30
29
 
@@ -50,7 +49,7 @@ export class SegmentsCacheInMemory extends AbstractSegmentsCacheSync {
50
49
 
51
50
  private _registerSegment(name: string) {
52
51
  if (!this.segmentCache[name]) {
53
- this.segmentCache[name] = new _Set<string>();
52
+ this.segmentCache[name] = new Set<string>();
54
53
  }
55
54
 
56
55
  return true;
@@ -1,7 +1,6 @@
1
1
  import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
2
2
  import { AbstractSplitsCacheSync, usesSegments } from '../AbstractSplitsCacheSync';
3
3
  import { isFiniteNumber } from '../../utils/lang';
4
- import { ISet, _Set } from '../../utils/lang/sets';
5
4
 
6
5
  /**
7
6
  * Default ISplitsCacheSync implementation that stores split definitions in memory.
@@ -14,7 +13,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
14
13
  private ttCache: Record<string, number> = {};
15
14
  private changeNumber: number = -1;
16
15
  private segmentsCount: number = 0;
17
- private flagSetsCache: Record<string, ISet<string>> = {};
16
+ private flagSetsCache: Record<string, Set<string>> = {};
18
17
 
19
18
  constructor(splitFiltersValidation?: ISplitFiltersValidation) {
20
19
  super();
@@ -104,8 +103,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
104
103
  return this.getChangeNumber() === -1 || this.segmentsCount > 0;
105
104
  }
106
105
 
107
- getNamesByFlagSets(flagSets: string[]): ISet<string>[] {
108
- return flagSets.map(flagSet => this.flagSetsCache[flagSet] || new _Set());
106
+ getNamesByFlagSets(flagSets: string[]): Set<string>[] {
107
+ return flagSets.map(flagSet => this.flagSetsCache[flagSet] || new Set());
109
108
  }
110
109
 
111
110
  private addToFlagSets(featureFlag: ISplit) {
@@ -114,7 +113,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
114
113
 
115
114
  if (this.flagSetsFilter.length > 0 && !this.flagSetsFilter.some(filterFlagSet => filterFlagSet === featureFlagSet)) return;
116
115
 
117
- if (!this.flagSetsCache[featureFlagSet]) this.flagSetsCache[featureFlagSet] = new _Set([]);
116
+ if (!this.flagSetsCache[featureFlagSet]) this.flagSetsCache[featureFlagSet] = new Set([]);
118
117
 
119
118
  this.flagSetsCache[featureFlagSet].add(featureFlag.name);
120
119
  });
@@ -1,17 +1,16 @@
1
1
  import { IUniqueKeysCacheBase } from '../types';
2
- import { ISet, setToArray, _Set } from '../../utils/lang/sets';
3
2
  import { UniqueKeysPayloadSs } from '../../sync/submitters/types';
4
3
  import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
5
4
 
6
5
  /**
7
6
  * Converts `uniqueKeys` data from cache into request payload for SS.
8
7
  */
9
- export function fromUniqueKeysCollector(uniqueKeys: { [featureName: string]: ISet<string> }): UniqueKeysPayloadSs {
8
+ export function fromUniqueKeysCollector(uniqueKeys: { [featureName: string]: Set<string> }): UniqueKeysPayloadSs {
10
9
  const payload = [];
11
10
  const featureNames = Object.keys(uniqueKeys);
12
11
  for (let i = 0; i < featureNames.length; i++) {
13
12
  const featureName = featureNames[i];
14
- const userKeys = setToArray(uniqueKeys[featureName]);
13
+ const userKeys = Array.from(uniqueKeys[featureName]);
15
14
  const uniqueKeysPayload = {
16
15
  f: featureName,
17
16
  ks: userKeys
@@ -27,7 +26,7 @@ export class UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
27
26
  protected onFullQueue?: () => void;
28
27
  private readonly maxStorage: number;
29
28
  private uniqueTrackerSize = 0;
30
- protected uniqueKeysTracker: { [featureName: string]: ISet<string> } = {};
29
+ protected uniqueKeysTracker: { [featureName: string]: Set<string> } = {};
31
30
 
32
31
  constructor(uniqueKeysQueueSize = DEFAULT_CACHE_SIZE) {
33
32
  this.maxStorage = uniqueKeysQueueSize;
@@ -41,7 +40,7 @@ export class UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
41
40
  * Store unique keys per feature.
42
41
  */
43
42
  track(userKey: string, featureName: string) {
44
- if (!this.uniqueKeysTracker[featureName]) this.uniqueKeysTracker[featureName] = new _Set();
43
+ if (!this.uniqueKeysTracker[featureName]) this.uniqueKeysTracker[featureName] = new Set();
45
44
  const tracker = this.uniqueKeysTracker[featureName];
46
45
  if (!tracker.has(userKey)) {
47
46
  tracker.add(userKey);
@@ -1,5 +1,4 @@
1
1
  import { IUniqueKeysCacheBase } from '../types';
2
- import { ISet, setToArray, _Set } from '../../utils/lang/sets';
3
2
  import { UniqueKeysPayloadCs } from '../../sync/submitters/types';
4
3
  import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
5
4
 
@@ -8,7 +7,7 @@ export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
8
7
  private onFullQueue?: () => void;
9
8
  private readonly maxStorage: number;
10
9
  private uniqueTrackerSize = 0;
11
- private uniqueKeysTracker: { [userKey: string]: ISet<string> } = {};
10
+ private uniqueKeysTracker: { [userKey: string]: Set<string> } = {};
12
11
 
13
12
  /**
14
13
  *
@@ -28,7 +27,7 @@ export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
28
27
  */
29
28
  track(userKey: string, featureName: string) {
30
29
 
31
- if (!this.uniqueKeysTracker[userKey]) this.uniqueKeysTracker[userKey] = new _Set();
30
+ if (!this.uniqueKeysTracker[userKey]) this.uniqueKeysTracker[userKey] = new Set();
32
31
  const tracker = this.uniqueKeysTracker[userKey];
33
32
  if (!tracker.has(featureName)) {
34
33
  tracker.add(featureName);
@@ -66,12 +65,12 @@ export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
66
65
  /**
67
66
  * Converts `uniqueKeys` data from cache into request payload.
68
67
  */
69
- private fromUniqueKeysCollector(uniqueKeys: { [userKey: string]: ISet<string> }): UniqueKeysPayloadCs {
68
+ private fromUniqueKeysCollector(uniqueKeys: { [userKey: string]: Set<string> }): UniqueKeysPayloadCs {
70
69
  const payload = [];
71
70
  const userKeys = Object.keys(uniqueKeys);
72
71
  for (let k = 0; k < userKeys.length; k++) {
73
72
  const userKey = userKeys[k];
74
- const featureNames = setToArray(uniqueKeys[userKey]);
73
+ const featureNames = Array.from(uniqueKeys[userKey]);
75
74
  const uniqueKeysPayload = {
76
75
  k: userKey,
77
76
  fs: featureNames
@@ -1,7 +1,6 @@
1
1
  import ioredis, { Pipeline } from 'ioredis';
2
2
  import { ILogger } from '../../logger/types';
3
3
  import { merge, isString } from '../../utils/lang';
4
- import { _Set, setToArray, ISet } from '../../utils/lang/sets';
5
4
  import { thenable } from '../../utils/promise/thenable';
6
5
  import { timeout } from '../../utils/promise/timeout';
7
6
 
@@ -20,7 +19,7 @@ const DEFAULT_OPTIONS = {
20
19
  const DEFAULT_LIBRARY_OPTIONS = {
21
20
  enableOfflineQueue: false,
22
21
  connectTimeout: DEFAULT_OPTIONS.connectionTimeout,
23
- lazyConnect: false // @TODO true to avoid side-effects on instantiation.
22
+ lazyConnect: false
24
23
  };
25
24
 
26
25
  interface IRedisCommand {
@@ -37,7 +36,7 @@ export class RedisAdapter extends ioredis {
37
36
  private readonly log: ILogger;
38
37
  private _options: object;
39
38
  private _notReadyCommandsQueue?: IRedisCommand[];
40
- private _runningCommands: ISet<Promise<any>>;
39
+ private _runningCommands: Set<Promise<any>>;
41
40
 
42
41
  constructor(log: ILogger, storageSettings: Record<string, any> = {}) {
43
42
  const options = RedisAdapter._defineOptions(storageSettings);
@@ -47,7 +46,7 @@ export class RedisAdapter extends ioredis {
47
46
  this.log = log;
48
47
  this._options = options;
49
48
  this._notReadyCommandsQueue = [];
50
- this._runningCommands = new _Set();
49
+ this._runningCommands = new Set();
51
50
  this._listenToEvents();
52
51
  this._setTimeoutWrappers();
53
52
  this._setDisconnectWrapper();
@@ -150,7 +149,7 @@ export class RedisAdapter extends ioredis {
150
149
  if (instance._runningCommands.size > 0) {
151
150
  instance.log.info(LOG_PREFIX + `Attempting to disconnect but there are ${instance._runningCommands.size} commands still waiting for resolution. Defering disconnection until those finish.`);
152
151
 
153
- Promise.all(setToArray(instance._runningCommands))
152
+ Promise.all(Array.from(instance._runningCommands))
154
153
  .then(() => {
155
154
  instance.log.debug(LOG_PREFIX + 'Pending commands finished successfully, disconnecting.');
156
155
  originalMethod.apply(instance, params);