@splitsoftware/splitio-commons 1.17.1-rc.2 → 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 (195) 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/sdkClient/clientCS.js +5 -8
  12. package/cjs/sdkClient/sdkClientMethodCS.js +1 -1
  13. package/cjs/sdkFactory/index.js +1 -3
  14. package/cjs/services/decorateHeaders.js +1 -2
  15. package/cjs/storages/AbstractSplitsCacheAsync.js +7 -0
  16. package/cjs/storages/AbstractSplitsCacheSync.js +7 -0
  17. package/cjs/storages/KeyBuilderCS.js +0 -9
  18. package/cjs/storages/dataLoader.js +32 -65
  19. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -21
  20. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +14 -7
  21. package/cjs/storages/inLocalStorage/index.js +1 -4
  22. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -16
  23. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +3 -4
  24. package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -3
  25. package/cjs/storages/inMemory/UniqueKeysCacheInMemory.js +2 -3
  26. package/cjs/storages/inMemory/UniqueKeysCacheInMemoryCS.js +2 -3
  27. package/cjs/storages/inRedis/RedisAdapter.js +2 -3
  28. package/cjs/storages/inRedis/SplitsCacheInRedis.js +1 -1
  29. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +3 -4
  30. package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +1 -2
  31. package/cjs/storages/pluggable/SplitsCachePluggable.js +1 -1
  32. package/cjs/storages/pluggable/TelemetryCachePluggable.js +6 -7
  33. package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +1 -2
  34. package/cjs/storages/pluggable/inMemoryWrapper.js +7 -8
  35. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +7 -2
  36. package/cjs/sync/polling/pollingManagerSS.js +3 -3
  37. package/cjs/sync/polling/updaters/splitChangesUpdater.js +13 -5
  38. package/cjs/sync/streaming/parseUtils.js +0 -1
  39. package/cjs/sync/streaming/pushManager.js +2 -3
  40. package/cjs/utils/LRUCache/index.js +1 -2
  41. package/cjs/utils/constants/browser.js +1 -4
  42. package/cjs/utils/lang/index.js +6 -9
  43. package/cjs/utils/lang/objectAssign.js +12 -77
  44. package/cjs/utils/lang/sets.js +3 -110
  45. package/cjs/utils/settingsValidation/index.js +0 -9
  46. package/cjs/utils/settingsValidation/logger/builtinLogger.js +1 -2
  47. package/cjs/utils/settingsValidation/storage/storageCS.js +12 -1
  48. package/esm/evaluator/index.js +3 -3
  49. package/esm/evaluator/matchers/semver_inlist.js +1 -2
  50. package/esm/evaluator/matchers/whitelist.js +1 -2
  51. package/esm/listeners/browser.js +1 -2
  52. package/esm/logger/browser/DebugLogger.js +1 -2
  53. package/esm/logger/browser/ErrorLogger.js +1 -2
  54. package/esm/logger/browser/InfoLogger.js +1 -2
  55. package/esm/logger/browser/WarnLogger.js +1 -2
  56. package/esm/logger/index.js +1 -2
  57. package/esm/sdkClient/clientCS.js +5 -8
  58. package/esm/sdkClient/sdkClientMethodCS.js +1 -1
  59. package/esm/sdkFactory/index.js +2 -4
  60. package/esm/services/decorateHeaders.js +1 -2
  61. package/esm/storages/AbstractSplitsCacheAsync.js +7 -0
  62. package/esm/storages/AbstractSplitsCacheSync.js +7 -0
  63. package/esm/storages/KeyBuilderCS.js +0 -9
  64. package/esm/storages/dataLoader.js +30 -62
  65. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -21
  66. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +14 -7
  67. package/esm/storages/inLocalStorage/index.js +2 -5
  68. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -16
  69. package/esm/storages/inMemory/SegmentsCacheInMemory.js +3 -4
  70. package/esm/storages/inMemory/SplitsCacheInMemory.js +2 -3
  71. package/esm/storages/inMemory/UniqueKeysCacheInMemory.js +2 -3
  72. package/esm/storages/inMemory/UniqueKeysCacheInMemoryCS.js +2 -3
  73. package/esm/storages/inRedis/RedisAdapter.js +2 -3
  74. package/esm/storages/inRedis/SplitsCacheInRedis.js +2 -2
  75. package/esm/storages/inRedis/TelemetryCacheInRedis.js +3 -4
  76. package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -2
  77. package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
  78. package/esm/storages/pluggable/TelemetryCachePluggable.js +6 -7
  79. package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -2
  80. package/esm/storages/pluggable/inMemoryWrapper.js +7 -8
  81. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +8 -3
  82. package/esm/sync/polling/pollingManagerSS.js +3 -3
  83. package/esm/sync/polling/updaters/splitChangesUpdater.js +14 -6
  84. package/esm/sync/streaming/parseUtils.js +0 -1
  85. package/esm/sync/streaming/pushManager.js +2 -3
  86. package/esm/utils/LRUCache/index.js +1 -2
  87. package/esm/utils/constants/browser.js +0 -3
  88. package/esm/utils/lang/index.js +6 -9
  89. package/esm/utils/lang/objectAssign.js +12 -77
  90. package/esm/utils/lang/sets.js +2 -107
  91. package/esm/utils/settingsValidation/index.js +0 -9
  92. package/esm/utils/settingsValidation/logger/builtinLogger.js +1 -2
  93. package/esm/utils/settingsValidation/storage/storageCS.js +10 -0
  94. package/package.json +2 -2
  95. package/src/evaluator/index.ts +5 -5
  96. package/src/evaluator/matchers/semver_inlist.ts +1 -2
  97. package/src/evaluator/matchers/whitelist.ts +1 -3
  98. package/src/listeners/browser.ts +1 -2
  99. package/src/logger/browser/DebugLogger.ts +1 -2
  100. package/src/logger/browser/ErrorLogger.ts +1 -2
  101. package/src/logger/browser/InfoLogger.ts +1 -2
  102. package/src/logger/browser/WarnLogger.ts +1 -2
  103. package/src/logger/index.ts +3 -4
  104. package/src/sdkClient/clientCS.ts +5 -8
  105. package/src/sdkClient/sdkClientMethodCS.ts +1 -1
  106. package/src/sdkFactory/index.ts +2 -5
  107. package/src/sdkFactory/types.ts +1 -1
  108. package/src/services/decorateHeaders.ts +1 -2
  109. package/src/storages/AbstractSplitsCacheAsync.ts +9 -2
  110. package/src/storages/AbstractSplitsCacheSync.ts +9 -2
  111. package/src/storages/KeyBuilderCS.ts +0 -13
  112. package/src/storages/dataLoader.ts +32 -63
  113. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +1 -21
  114. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +16 -8
  115. package/src/storages/inLocalStorage/index.ts +2 -6
  116. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -19
  117. package/src/storages/inMemory/SegmentsCacheInMemory.ts +4 -5
  118. package/src/storages/inMemory/SplitsCacheInMemory.ts +4 -5
  119. package/src/storages/inMemory/UniqueKeysCacheInMemory.ts +4 -5
  120. package/src/storages/inMemory/UniqueKeysCacheInMemoryCS.ts +4 -5
  121. package/src/storages/inRedis/RedisAdapter.ts +3 -4
  122. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -3
  123. package/src/storages/inRedis/TelemetryCacheInRedis.ts +3 -4
  124. package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +1 -2
  125. package/src/storages/pluggable/SegmentsCachePluggable.ts +0 -1
  126. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -3
  127. package/src/storages/pluggable/TelemetryCachePluggable.ts +6 -7
  128. package/src/storages/pluggable/UniqueKeysCachePluggable.ts +1 -2
  129. package/src/storages/pluggable/inMemoryWrapper.ts +8 -9
  130. package/src/storages/types.ts +9 -5
  131. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +7 -3
  132. package/src/sync/polling/pollingManagerSS.ts +2 -3
  133. package/src/sync/polling/updaters/splitChangesUpdater.ts +15 -8
  134. package/src/sync/streaming/parseUtils.ts +0 -1
  135. package/src/sync/streaming/pushManager.ts +3 -4
  136. package/src/sync/submitters/types.ts +3 -4
  137. package/src/types.ts +9 -18
  138. package/src/utils/LRUCache/index.ts +2 -3
  139. package/src/utils/constants/browser.ts +0 -4
  140. package/src/utils/lang/index.ts +6 -7
  141. package/src/utils/lang/objectAssign.ts +13 -92
  142. package/src/utils/lang/sets.ts +3 -125
  143. package/src/utils/settingsValidation/index.ts +0 -10
  144. package/src/utils/settingsValidation/logger/builtinLogger.ts +1 -2
  145. package/src/utils/settingsValidation/storage/storageCS.ts +13 -0
  146. package/src/utils/settingsValidation/types.ts +0 -2
  147. package/types/logger/index.d.ts +1 -2
  148. package/types/sdkClient/clientCS.d.ts +2 -3
  149. package/types/sdkFactory/types.d.ts +1 -1
  150. package/types/storages/AbstractSplitsCacheAsync.d.ts +6 -2
  151. package/types/storages/AbstractSplitsCacheSync.d.ts +6 -2
  152. package/types/storages/KeyBuilderCS.d.ts +0 -2
  153. package/types/storages/dataLoader.d.ts +6 -17
  154. package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +7 -2
  155. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -2
  156. package/types/storages/inMemory/UniqueKeysCacheInMemory.d.ts +2 -3
  157. package/types/storages/inRedis/SplitsCacheInRedis.d.ts +1 -2
  158. package/types/storages/pluggable/SplitsCachePluggable.d.ts +1 -2
  159. package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -2
  160. package/types/storages/types.d.ts +7 -5
  161. package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -2
  162. package/types/sync/submitters/types.d.ts +3 -4
  163. package/types/types.d.ts +9 -17
  164. package/types/utils/LRUCache/index.d.ts +1 -2
  165. package/types/utils/constants/browser.d.ts +0 -2
  166. package/types/utils/lang/objectAssign.d.ts +3 -0
  167. package/types/utils/lang/sets.d.ts +1 -61
  168. package/types/utils/settingsValidation/index.d.ts +0 -1
  169. package/types/utils/settingsValidation/storage/storageCS.d.ts +5 -0
  170. package/types/utils/settingsValidation/types.d.ts +0 -2
  171. package/cjs/integrations/browser.js +0 -31
  172. package/cjs/integrations/ga/GaToSplit.js +0 -257
  173. package/cjs/integrations/ga/GoogleAnalyticsToSplit.js +0 -14
  174. package/cjs/integrations/ga/SplitToGa.js +0 -123
  175. package/cjs/integrations/ga/SplitToGoogleAnalytics.js +0 -14
  176. package/cjs/integrations/ga/types.js +0 -2
  177. package/cjs/sdkClient/sdkClientMethodCSWithTT.js +0 -76
  178. package/cjs/utils/lang/maps.js +0 -96
  179. package/esm/integrations/browser.js +0 -27
  180. package/esm/integrations/ga/GaToSplit.js +0 -250
  181. package/esm/integrations/ga/GoogleAnalyticsToSplit.js +0 -10
  182. package/esm/integrations/ga/SplitToGa.js +0 -120
  183. package/esm/integrations/ga/SplitToGoogleAnalytics.js +0 -10
  184. package/esm/integrations/ga/types.js +0 -1
  185. package/esm/sdkClient/sdkClientMethodCSWithTT.js +0 -72
  186. package/esm/utils/lang/maps.js +0 -92
  187. package/src/integrations/browser.ts +0 -35
  188. package/src/integrations/ga/GaToSplit.ts +0 -299
  189. package/src/integrations/ga/GoogleAnalyticsToSplit.ts +0 -14
  190. package/src/integrations/ga/SplitToGa.ts +0 -135
  191. package/src/integrations/ga/SplitToGoogleAnalytics.ts +0 -14
  192. package/src/integrations/ga/autoRequire.js +0 -33
  193. package/src/integrations/ga/types.ts +0 -153
  194. package/src/sdkClient/sdkClientMethodCSWithTT.ts +0 -98
  195. package/src/utils/lang/maps.ts +0 -108
@@ -6,7 +6,6 @@ import { findLatencyIndex } from '../findLatencyIndex';
6
6
  import { getTelemetryConfigStats } from '../../sync/submitters/telemetrySubmitter';
7
7
  import { CONSUMER_MODE, STORAGE_PLUGGABLE } from '../../utils/constants';
8
8
  import { isString, isNaNNumber } from '../../utils/lang';
9
- import { _Map } from '../../utils/lang/maps';
10
9
  import { MAX_LATENCY_BUCKET_COUNT, newBuckets } from '../inMemory/TelemetryCacheInMemory';
11
10
  import { parseLatencyField, parseExceptionField, parseMetadata } from '../utils';
12
11
 
@@ -43,7 +42,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
43
42
  return latencyKeys.length ?
44
43
  this.wrapper.getMany(latencyKeys).then(latencies => {
45
44
 
46
- const result: MultiMethodLatencies = new _Map();
45
+ const result: MultiMethodLatencies = new Map();
47
46
 
48
47
  for (let i = 0; i < latencyKeys.length; i++) {
49
48
  const field = latencyKeys[i].split('::')[1];
@@ -77,7 +76,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
77
76
  return Promise.all(latencyKeys.map((latencyKey) => this.wrapper.del(latencyKey))).then(() => result);
78
77
  }) :
79
78
  // If latencyKeys is empty, return an empty map.
80
- new _Map();
79
+ new Map();
81
80
  });
82
81
  }
83
82
 
@@ -90,7 +89,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
90
89
  return exceptionKeys.length ?
91
90
  this.wrapper.getMany(exceptionKeys).then(exceptions => {
92
91
 
93
- const result: MultiMethodExceptions = new _Map();
92
+ const result: MultiMethodExceptions = new Map();
94
93
 
95
94
  for (let i = 0; i < exceptionKeys.length; i++) {
96
95
  const field = exceptionKeys[i].split('::')[1];
@@ -117,7 +116,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
117
116
  return Promise.all(exceptionKeys.map((exceptionKey) => this.wrapper.del(exceptionKey))).then(() => result);
118
117
  }) :
119
118
  // If exceptionKeys is empty, return an empty map.
120
- new _Map();
119
+ new Map();
121
120
  });
122
121
  }
123
122
 
@@ -130,7 +129,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
130
129
  return configKeys.length ?
131
130
  this.wrapper.getMany(configKeys).then(configs => {
132
131
 
133
- const result: MultiConfigs = new _Map();
132
+ const result: MultiConfigs = new Map();
134
133
 
135
134
  for (let i = 0; i < configKeys.length; i++) {
136
135
  const field = configKeys[i].split('::')[1];
@@ -154,7 +153,7 @@ export class TelemetryCachePluggable implements ITelemetryCacheAsync {
154
153
  return Promise.all(configKeys.map((configKey) => this.wrapper.del(configKey))).then(() => result);
155
154
  }) :
156
155
  // If configKeys is empty, return an empty map.
157
- new _Map();
156
+ new Map();
158
157
  });
159
158
  }
160
159
  }
@@ -1,6 +1,5 @@
1
1
  import { IPluggableStorageWrapper, IUniqueKeysCacheBase } from '../types';
2
2
  import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
3
- import { setToArray } from '../../utils/lang/sets';
4
3
  import { DEFAULT_CACHE_SIZE, REFRESH_RATE } from '../inRedis/constants';
5
4
  import { LOG_PREFIX } from './constants';
6
5
  import { ILogger } from '../../logger/types';
@@ -28,7 +27,7 @@ export class UniqueKeysCachePluggable extends UniqueKeysCacheInMemory implements
28
27
  if (!featureNames.length) return Promise.resolve(false);
29
28
 
30
29
  const uniqueKeysArray = featureNames.map((featureName) => {
31
- const featureKeys = setToArray(this.uniqueKeysTracker[featureName]);
30
+ const featureKeys = Array.from(this.uniqueKeysTracker[featureName]);
32
31
  const uniqueKeysPayload = {
33
32
  f: featureName,
34
33
  ks: featureKeys
@@ -1,6 +1,5 @@
1
1
  import { IPluggableStorageWrapper } from '../types';
2
2
  import { startsWith, toNumber } from '../../utils/lang';
3
- import { ISet, setToArray, _Set } from '../../utils/lang/sets';
4
3
 
5
4
  /**
6
5
  * Creates a IPluggableStorageWrapper implementation that stores items in memory.
@@ -9,9 +8,9 @@ import { ISet, setToArray, _Set } from '../../utils/lang/sets';
9
8
  *
10
9
  * @param connDelay delay in millis for `connect` resolve. If not provided, `connect` resolves immediately.
11
10
  */
12
- export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWrapper & { _cache: Record<string, string | string[] | ISet<string>>, _setConnDelay(connDelay: number): void } {
11
+ export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWrapper & { _cache: Record<string, string | string[] | Set<string>>, _setConnDelay(connDelay: number): void } {
13
12
 
14
- let _cache: Record<string, string | string[] | ISet<string>> = {};
13
+ let _cache: Record<string, string | string[] | Set<string>> = {};
15
14
  let _connDelay = connDelay;
16
15
 
17
16
  return {
@@ -84,22 +83,22 @@ export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWra
84
83
  itemContains(key: string, item: string) {
85
84
  const set = _cache[key];
86
85
  if (!set) return Promise.resolve(false);
87
- if (set instanceof _Set) return Promise.resolve(set.has(item));
86
+ if (set instanceof Set) return Promise.resolve(set.has(item));
88
87
  return Promise.reject('key is not a set');
89
88
  },
90
89
  addItems(key: string, items: string[]) {
91
- if (!(key in _cache)) _cache[key] = new _Set();
90
+ if (!(key in _cache)) _cache[key] = new Set();
92
91
  const set = _cache[key];
93
- if (set instanceof _Set) {
92
+ if (set instanceof Set) {
94
93
  items.forEach(item => set.add(item));
95
94
  return Promise.resolve();
96
95
  }
97
96
  return Promise.reject('key is not a set');
98
97
  },
99
98
  removeItems(key: string, items: string[]) {
100
- if (!(key in _cache)) _cache[key] = new _Set();
99
+ if (!(key in _cache)) _cache[key] = new Set();
101
100
  const set = _cache[key];
102
- if (set instanceof _Set) {
101
+ if (set instanceof Set) {
103
102
  items.forEach(item => set.delete(item));
104
103
  return Promise.resolve();
105
104
  }
@@ -108,7 +107,7 @@ export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWra
108
107
  getItems(key: string) {
109
108
  const set = _cache[key];
110
109
  if (!set) return Promise.resolve([]);
111
- if (set instanceof _Set) return Promise.resolve(setToArray(set));
110
+ if (set instanceof Set) return Promise.resolve(Array.from(set));
112
111
  return Promise.reject('key is not a set');
113
112
  },
114
113
 
@@ -2,7 +2,6 @@ import { MaybeThenable, ISplit, IMySegmentsResponse } from '../dtos/types';
2
2
  import { MySegmentsData } from '../sync/polling/types';
3
3
  import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
4
4
  import { SplitIO, ImpressionDTO, ISettings } from '../types';
5
- import { ISet } from '../utils/lang/sets';
6
5
 
7
6
  /**
8
7
  * Interface of a pluggable storage wrapper.
@@ -208,8 +207,10 @@ export interface ISplitsCacheBase {
208
207
  // only for Client-Side. Returns true if the storage is not synchronized yet (getChangeNumber() === -1) or contains a FF using segments or large segments
209
208
  usesSegments(): MaybeThenable<boolean>,
210
209
  clear(): MaybeThenable<boolean | void>,
210
+ // should never reject or throw an exception. Instead return false by default, to avoid emitting SDK_READY_FROM_CACHE.
211
+ checkCache(): MaybeThenable<boolean>,
211
212
  killLocally(name: string, defaultTreatment: string, changeNumber: number): MaybeThenable<boolean>,
212
- getNamesByFlagSets(flagSets: string[]): MaybeThenable<ISet<string>[]>
213
+ getNamesByFlagSets(flagSets: string[]): MaybeThenable<Set<string>[]>
213
214
  }
214
215
 
215
216
  export interface ISplitsCacheSync extends ISplitsCacheBase {
@@ -224,8 +225,9 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
224
225
  trafficTypeExists(trafficType: string): boolean,
225
226
  usesSegments(): boolean,
226
227
  clear(): void,
228
+ checkCache(): boolean,
227
229
  killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean,
228
- getNamesByFlagSets(flagSets: string[]): ISet<string>[]
230
+ getNamesByFlagSets(flagSets: string[]): Set<string>[]
229
231
  }
230
232
 
231
233
  export interface ISplitsCacheAsync extends ISplitsCacheBase {
@@ -240,8 +242,9 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
240
242
  trafficTypeExists(trafficType: string): Promise<boolean>,
241
243
  usesSegments(): Promise<boolean>,
242
244
  clear(): Promise<boolean | void>,
245
+ checkCache(): Promise<boolean>,
243
246
  killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean>,
244
- getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>
247
+ getNamesByFlagSets(flagSets: string[]): Promise<Set<string>[]>
245
248
  }
246
249
 
247
250
  /** Segments cache */
@@ -491,6 +494,8 @@ export interface IStorageAsync extends IStorageBase<
491
494
 
492
495
  /** StorageFactory */
493
496
 
497
+ export type DataLoader = (storage: IStorageSync, matchingKey: string) => void
498
+
494
499
  export interface IStorageFactoryParams {
495
500
  settings: ISettings,
496
501
  /**
@@ -498,7 +503,6 @@ export interface IStorageFactoryParams {
498
503
  * It is meant for emitting SDK_READY event in consumer mode, and waiting before using the storage in the synchronizer.
499
504
  */
500
505
  onReadyCb: (error?: any) => void,
501
- onReadyFromCacheCb: (error?: any) => void,
502
506
  }
503
507
 
504
508
  export type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS' | 'PLUGGABLE';
@@ -7,7 +7,7 @@ import { syncTaskFactory } from '../../syncTask';
7
7
  import { ISyncTask } from '../../types';
8
8
  import { ISettings } from '../../../types';
9
9
  import { CONTROL } from '../../../utils/constants';
10
- import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
10
+ import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
11
11
  import { SYNC_OFFLINE_DATA, ERROR_SYNC_OFFLINE_LOADING } from '../../../logger/constants';
12
12
 
13
13
  /**
@@ -60,8 +60,12 @@ export function fromObjectUpdaterFactory(
60
60
 
61
61
  if (startingUp) {
62
62
  startingUp = false;
63
- // Emits SDK_READY
64
- readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
63
+ Promise.resolve(splitsCache.checkCache()).then(cacheReady => {
64
+ // Emits SDK_READY_FROM_CACHE
65
+ if (cacheReady) readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
66
+ // Emits SDK_READY
67
+ readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
68
+ });
65
69
  }
66
70
  return true;
67
71
  });
@@ -1,7 +1,6 @@
1
1
  import { splitsSyncTaskFactory } from './syncTasks/splitsSyncTask';
2
2
  import { segmentsSyncTaskFactory } from './syncTasks/segmentsSyncTask';
3
3
  import { IPollingManager, ISegmentsSyncTask, ISplitsSyncTask } from './types';
4
- import { thenable } from '../../utils/promise/thenable';
5
4
  import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logger/constants';
6
5
  import { ISdkFactoryContextSync } from '../../sdkFactory/types';
7
6
 
@@ -29,9 +28,9 @@ export function pollingManagerSSFactory(
29
28
  log.debug(LOG_PREFIX_SYNC_POLLING + `Segments will be refreshed each ${settings.scheduler.segmentsRefreshRate} millis`);
30
29
 
31
30
  const startingUp = splitsSyncTask.start();
32
- if (thenable(startingUp)) {
31
+ if (startingUp) {
33
32
  startingUp.then(() => {
34
- segmentsSyncTask.start();
33
+ if (splitsSyncTask.isRunning()) segmentsSyncTask.start();
35
34
  });
36
35
  }
37
36
  },
@@ -1,10 +1,9 @@
1
- import { _Set, setToArray, ISet } from '../../../utils/lang/sets';
2
1
  import { ISegmentsCacheBase, ISplitsCacheBase } from '../../../storages/types';
3
2
  import { ISplitChangesFetcher } from '../fetchers/types';
4
3
  import { ISplit, ISplitChangesResponse, ISplitFiltersValidation } from '../../../dtos/types';
5
4
  import { ISplitsEventEmitter } from '../../../readiness/types';
6
5
  import { timeout } from '../../../utils/promise/timeout';
7
- import { SDK_SPLITS_ARRIVED } from '../../../readiness/constants';
6
+ import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
8
7
  import { ILogger } from '../../../logger/types';
9
8
  import { SYNC_SPLITS_FETCH, SYNC_SPLITS_NEW, SYNC_SPLITS_REMOVED, SYNC_SPLITS_SEGMENTS, SYNC_SPLITS_FETCH_FAILS, SYNC_SPLITS_FETCH_RETRY } from '../../../logger/constants';
10
9
  import { startsWith } from '../../../utils/lang';
@@ -27,8 +26,8 @@ function checkAllSegmentsExist(segments: ISegmentsCacheBase): Promise<boolean> {
27
26
  * Collect segments from a raw split definition.
28
27
  * Exported for testing purposes.
29
28
  */
30
- export function parseSegments({ conditions }: ISplit): ISet<string> {
31
- let segments = new _Set<string>();
29
+ export function parseSegments({ conditions }: ISplit): Set<string> {
30
+ let segments = new Set<string>();
32
31
 
33
32
  for (let i = 0; i < conditions.length; i++) {
34
33
  const matchers = conditions[i].matcherGroup.matchers;
@@ -74,7 +73,7 @@ function matchFilters(featureFlag: ISplit, filters: ISplitFiltersValidation) {
74
73
  * Exported for testing purposes.
75
74
  */
76
75
  export function computeSplitsMutation(entries: ISplit[], filters: ISplitFiltersValidation): ISplitMutations {
77
- const segments = new _Set<string>();
76
+ const segments = new Set<string>();
78
77
  const computed = entries.reduce((accum, split) => {
79
78
  if (split.status === 'ACTIVE' && matchFilters(split, filters)) {
80
79
  accum.added.push([split.name, split]);
@@ -89,7 +88,7 @@ export function computeSplitsMutation(entries: ISplit[], filters: ISplitFiltersV
89
88
  return accum;
90
89
  }, { added: [], removed: [], segments: [] } as ISplitMutations);
91
90
 
92
- computed.segments = setToArray(segments);
91
+ computed.segments = Array.from(segments);
93
92
 
94
93
  return computed;
95
94
  }
@@ -153,8 +152,7 @@ export function splitChangesUpdaterFactory(
153
152
  */
154
153
  function _splitChangesUpdater(since: number, retry = 0): Promise<boolean> {
155
154
  log.debug(SYNC_SPLITS_FETCH, [since]);
156
-
157
- return Promise.resolve(splitUpdateNotification ?
155
+ const fetcherPromise = Promise.resolve(splitUpdateNotification ?
158
156
  { splits: [splitUpdateNotification.payload], till: splitUpdateNotification.changeNumber } :
159
157
  splitChangesFetcher(since, noCache, till, _promiseDecorator)
160
158
  )
@@ -201,6 +199,15 @@ export function splitChangesUpdaterFactory(
201
199
  }
202
200
  return false;
203
201
  });
202
+
203
+ // After triggering the requests, if we have cached splits information let's notify that to emit SDK_READY_FROM_CACHE.
204
+ // Wrapping in a promise since checkCache can be async.
205
+ if (splitsEventEmitter && startingUp) {
206
+ Promise.resolve(splits.checkCache()).then(isCacheReady => {
207
+ if (isCacheReady) splitsEventEmitter.emit(SDK_SPLITS_CACHE_LOADED);
208
+ });
209
+ }
210
+ return fetcherPromise;
204
211
  }
205
212
 
206
213
  let sincePromise = Promise.resolve(splits.getChangeNumber()); // `getChangeNumber` never rejects or throws error
@@ -13,7 +13,6 @@ function Uint8ArrayToString(myUint8Arr: Uint8Array) { // @ts-ignore
13
13
 
14
14
  function StringToUint8Array(myString: string) {
15
15
  const charCodes = myString.split('').map((e) => e.charCodeAt(0));
16
- // eslint-disable-next-line compat/compat
17
16
  return new Uint8Array(charCodes);
18
17
  }
19
18
 
@@ -15,7 +15,6 @@ import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR,
15
15
  import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
16
16
  import { IMembershipMSUpdateData, IMembershipLSUpdateData, KeyList, UpdateStrategy } from './SSEHandler/types';
17
17
  import { getDelay, isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
18
- import { ISet, _Set } from '../../utils/lang/sets';
19
18
  import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
20
19
  import { IAuthTokenPushEnabled } from './AuthClient/types';
21
20
  import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
@@ -254,11 +253,11 @@ export function pushManagerFactory(
254
253
  return;
255
254
  }
256
255
  case UpdateStrategy.KeyList: {
257
- let keyList: KeyList, added: ISet<string>, removed: ISet<string>;
256
+ let keyList: KeyList, added: Set<string>, removed: Set<string>;
258
257
  try {
259
258
  keyList = parseKeyList(parsedData.d!, parsedData.c!);
260
- added = new _Set(keyList.a);
261
- removed = new _Set(keyList.r);
259
+ added = new Set(keyList.a);
260
+ removed = new Set(keyList.r);
262
261
  } catch (e) {
263
262
  log.warn(STREAMING_PARSING_MEMBERSHIPS_UPDATE, ['KeyList', e]);
264
263
  break;
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable no-use-before-define */
2
2
  import { IMetadata } from '../../dtos/types';
3
3
  import { SplitIO } from '../../types';
4
- import { IMap } from '../../utils/lang/maps';
5
4
  import { ISyncTask } from '../types';
6
5
 
7
6
  export type ImpressionsPayload = {
@@ -88,11 +87,11 @@ export type StoredEventWithMetadata = {
88
87
  e: SplitIO.EventData
89
88
  }
90
89
 
91
- export type MultiMethodLatencies = IMap<string, MethodLatencies>
90
+ export type MultiMethodLatencies = Map<string, MethodLatencies>
92
91
 
93
- export type MultiMethodExceptions = IMap<string, MethodExceptions>
92
+ export type MultiMethodExceptions = Map<string, MethodExceptions>
94
93
 
95
- export type MultiConfigs = IMap<string, TelemetryConfigStats>
94
+ export type MultiConfigs = Map<string, TelemetryConfigStats>
96
95
 
97
96
  /**
98
97
  * Telemetry usage stats
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ISplit, ISplitFiltersValidation } from './dtos/types';
1
+ import { ISplitFiltersValidation } from './dtos/types';
2
2
  import { IIntegration, IIntegrationFactoryParams } from './integrations/types';
3
3
  import { ILogger } from './logger/types';
4
4
  import { ISdkFactoryContext } from './sdkFactory/types';
@@ -71,7 +71,6 @@ export interface ISettings {
71
71
  readonly core: {
72
72
  authorizationKey: string,
73
73
  key: SplitIO.SplitKey,
74
- trafficType?: string,
75
74
  labelsEnabled: boolean,
76
75
  IPAddressesEnabled: boolean
77
76
  },
@@ -98,7 +97,6 @@ export interface ISettings {
98
97
  eventsFirstPushWindow: number
99
98
  },
100
99
  readonly storage: IStorageSyncFactory | IStorageAsyncFactory,
101
- readonly preloadedData?: SplitIO.PreloadedData,
102
100
  readonly integrations: Array<{
103
101
  readonly type: string,
104
102
  (params: IIntegrationFactoryParams): IIntegration | void
@@ -772,20 +770,21 @@ export namespace SplitIO {
772
770
  * If this value is older than 10 days ago (expiration time policy), the data is not used to update the storage content.
773
771
  * @TODO configurable expiration time policy?
774
772
  */
775
- // lastUpdated: number,
773
+ lastUpdated: number,
776
774
  /**
777
775
  * Change number of the preloaded data.
778
776
  * If this value is older than the current changeNumber at the storage, the data is not used to update the storage content.
779
777
  */
780
778
  since: number,
781
779
  /**
782
- * List of feature flag definitions.
783
- * @TODO rename to flags
780
+ * Map of feature flags to their stringified definitions.
784
781
  */
785
- splitsData: ISplit[],
782
+ splitsData: {
783
+ [splitName: string]: string
784
+ },
786
785
  /**
787
786
  * Optional map of user keys to their list of segments.
788
- * @TODO rename to memberships
787
+ * @TODO remove when releasing first version
789
788
  */
790
789
  mySegmentsData?: {
791
790
  [key: string]: string[]
@@ -793,10 +792,9 @@ export namespace SplitIO {
793
792
  /**
794
793
  * Optional map of segments to their stringified definitions.
795
794
  * This property is ignored if `mySegmentsData` was provided.
796
- * @TODO rename to segments
797
795
  */
798
796
  segmentsData?: {
799
- [segmentName: string]: string[]
797
+ [segmentName: string]: string
800
798
  },
801
799
  }
802
800
  /**
@@ -924,12 +922,6 @@ export namespace SplitIO {
924
922
  * @property {SplitKey} key
925
923
  */
926
924
  key: SplitKey,
927
- /**
928
- * Traffic type associated with the customer identifier. @see {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type}
929
- * If no provided as a setting it will be required on the client.track() calls.
930
- * @property {string} trafficType
931
- */
932
- trafficType?: string,
933
925
  /**
934
926
  * Disable labels from being sent to Split backend. Labels may contain sensitive information.
935
927
  * @property {boolean} labelsEnabled
@@ -1038,10 +1030,9 @@ export namespace SplitIO {
1038
1030
  * Returns a shared client of the SDK, with the given key and optional traffic type.
1039
1031
  * @function client
1040
1032
  * @param {SplitKey} key The key for the new client instance.
1041
- * @param {string=} trafficType The traffic type of the provided key.
1042
1033
  * @returns {ICsClient} The client instance.
1043
1034
  */
1044
- client(key: SplitKey, trafficType?: string): ICsClient,
1035
+ client(key: SplitKey): ICsClient,
1045
1036
  /**
1046
1037
  * Returns a manager instance of the SDK to explore available information.
1047
1038
  * @function manager
@@ -1,14 +1,13 @@
1
- import { IMap, _Map } from '../lang/maps';
2
1
  import { LinkedList, Node } from './LinkedList';
3
2
 
4
3
  export class LRUCache<K, V> {
5
4
  maxLen: number;
6
- items: IMap<K, Node<{ key: K, value: V }>>;
5
+ items: Map<K, Node<{ key: K, value: V }>>;
7
6
  lru: LinkedList<{ key: K, value: V }>;
8
7
 
9
8
  constructor(maxSize?: number) {
10
9
  this.maxLen = maxSize || 1;
11
- this.items = new _Map();
10
+ this.items = new Map();
12
11
  this.lru = new LinkedList();
13
12
  }
14
13
 
@@ -1,6 +1,2 @@
1
- // Integration types
2
- export const GOOGLE_ANALYTICS_TO_SPLIT = 'GOOGLE_ANALYTICS_TO_SPLIT';
3
- export const SPLIT_TO_GOOGLE_ANALYTICS = 'SPLIT_TO_GOOGLE_ANALYTICS';
4
-
5
1
  // This value might be eventually set via a config parameter
6
2
  export const DEFAULT_CACHE_EXPIRATION_IN_MILLIS = 864000000; // 10 days
@@ -122,10 +122,9 @@ export function isBoolean(val: any): boolean {
122
122
  */
123
123
  export function isFiniteNumber(val: any): boolean {
124
124
  if (val instanceof Number) val = val.valueOf();
125
- // @TODO remove `isFinite` once `Number.isFinite` is fully supported by targets
126
- // eslint-disable-next-line compat/compat
127
- if (typeof val === 'number') return Number.isFinite ? Number.isFinite(val) : isFinite(val);
128
- return false;
125
+ return typeof val === 'number' ?
126
+ Number.isFinite ? Number.isFinite(val) : isFinite(val) :
127
+ false;
129
128
  }
130
129
 
131
130
  /**
@@ -134,9 +133,9 @@ export function isFiniteNumber(val: any): boolean {
134
133
  */
135
134
  export function isIntegerNumber(val: any): boolean {
136
135
  if (val instanceof Number) val = val.valueOf();
137
- // eslint-disable-next-line compat/compat
138
- if (typeof val === 'number') return Number.isInteger ? Number.isInteger(val) : isFinite(val) && Math.floor(val) === val;
139
- return false;
136
+ return typeof val === 'number' ?
137
+ Number.isInteger ? Number.isInteger(val) : isFinite(val) && Math.floor(val) === val :
138
+ false;
140
139
  }
141
140
 
142
141
  /**
@@ -1,71 +1,6 @@
1
- /*
2
- Adaptation of "object-assign" library (https://www.npmjs.com/package/object-assign)
3
- exported as an ES module instead of CommonJS, to avoid extra configuration steps when using
4
- the ESM build of the SDK with tools that doesn't support CommonJS by default (e.g. Rollup).
5
-
6
- object-assign
7
- (c) Sindre Sorhus
8
- @license MIT
9
- */
10
-
11
- /* eslint-disable */
12
- // @ts-nocheck
13
-
14
- var getOwnPropertySymbols = Object.getOwnPropertySymbols;
15
- var hasOwnProperty = Object.prototype.hasOwnProperty;
16
- var propIsEnumerable = Object.prototype.propertyIsEnumerable;
17
-
18
- function toObject(val) {
19
- if (val === null || val === undefined) {
20
- throw new TypeError('Object.assign cannot be called with null or undefined');
21
- }
22
-
23
- return Object(val);
24
- }
25
-
26
- function shouldUseNative() {
27
- try {
28
- if (!Object.assign) {
29
- return false;
30
- }
31
-
32
- // Detect buggy property enumeration order in older V8 versions.
33
-
34
- // https://bugs.chromium.org/p/v8/issues/detail?id=4118
35
- var test1 = new String('abc');
36
- test1[5] = 'de';
37
- if (Object.getOwnPropertyNames(test1)[0] === '5') {
38
- return false;
39
- }
40
-
41
- // https://bugs.chromium.org/p/v8/issues/detail?id=3056
42
- var test2 = {};
43
- for (var i = 0; i < 10; i++) {
44
- test2['_' + String.fromCharCode(i)] = i;
45
- }
46
- var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
47
- return test2[n];
48
- });
49
- if (order2.join('') !== '0123456789') {
50
- return false;
51
- }
52
-
53
- // https://bugs.chromium.org/p/v8/issues/detail?id=3056
54
- var test3 = {};
55
- 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
56
- test3[letter] = letter;
57
- });
58
- if (Object.keys(Object.assign({}, test3)).join('') !==
59
- 'abcdefghijklmnopqrst') {
60
- return false;
61
- }
62
-
63
- return true;
64
- } catch (err) {
65
- // We don't expect any of the above to throw, but better to be safe.
66
- return false;
67
- }
68
- }
1
+ /**
2
+ * A tiny polyfill for Object.assign
3
+ */
69
4
 
70
5
  // https://www.npmjs.com/package/@types/object-assign
71
6
  type ObjectAssign = (<T, U>(target: T, source: U) => T & U) &
@@ -74,31 +9,17 @@ type ObjectAssign = (<T, U>(target: T, source: U) => T & U) &
74
9
  (<T, U, V, W, Q>(target: T, source1: U, source2: V, source3: W, source4: Q) => T & U & V & W & Q) &
75
10
  (<T, U, V, W, Q, R>(target: T, source1: U, source2: V, source3: W, source4: Q, source5: R) => T & U & V & W & Q & R) &
76
11
  ((target: any, ...sources: any[]) => any);
77
-
78
- export const objectAssign: ObjectAssign = shouldUseNative() ? Object.assign : function (target, source) {
79
- var from;
80
- var to = toObject(target);
81
- var symbols;
82
-
83
- for (var s = 1; s < arguments.length; s++) {
84
- from = Object(arguments[s]);
85
-
86
- // eslint-disable-next-line no-restricted-syntax
87
- for (var key in from) {
88
- if (hasOwnProperty.call(from, key)) {
89
- to[key] = from[key];
90
- }
91
- }
92
-
93
- if (getOwnPropertySymbols) {
94
- symbols = getOwnPropertySymbols(from);
95
- for (var i = 0; i < symbols.length; i++) {
96
- if (propIsEnumerable.call(from, symbols[i])) {
97
- to[symbols[i]] = from[symbols[i]];
98
- }
12
+ export const objectAssign: ObjectAssign = Object.assign || function (target: any) {
13
+ if (target === null || target === undefined) throw new TypeError('Object.assign cannot be called with null or undefined');
14
+ target = Object(target);
15
+
16
+ for (let i = 1; i < arguments.length; i++) {
17
+ const source = Object(arguments[i]); // eslint-disable-next-line no-restricted-syntax
18
+ for (const key in source) {
19
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
20
+ target[key] = source[key];
99
21
  }
100
22
  }
101
23
  }
102
-
103
- return to;
24
+ return target;
104
25
  };