@splitsoftware/splitio-commons 2.13.1 → 2.14.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGES.txt CHANGED
@@ -1,5 +1,8 @@
1
+ 2.14.0 (October XX, 2026)
2
+ - Added `storage.disableFlagSetCache` option (default `false`) for storage type `LOCALSTORAGE`. When set to `true`, the SDK skips building the internal flag set index, which speeds up initialization for large numbers of feature flags. The `getTreatments(WithConfig)ByFlagSet(s)` methods then return empty results and log an error.
3
+
1
4
  2.13.1 (October 7, 2026)
2
- - Updated the 'LOCALSTORAGE' storage to batch the writes of flag sets and traffic type/segment counters when storing feature flags, reducing the time of cold initializations.
5
+ - Updated the 'LOCALSTORAGE' storage to batch the writes of flag sets and traffic type/segment counters when storing feature flags, reducing storage update times and the time to SDK_READY event.
3
6
 
4
7
  2.13.0 (September 24, 2026)
5
8
  - Added support for ioredis v6 (Related to issue https://github.com/splitio/javascript-client/issues/951). Note that ioredis v6 requires Node.js 20 or above; stay on ioredis v4 or v5 for older Node.js versions.
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ENGINE_VALUE_INVALID = exports.SUBMITTERS_PUSH_PAGE_HIDDEN = exports.USER_CONSENT_INITIAL = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = exports.SYNC_SPLITS_FETCH_RETRY = exports.POLLING_STOP = exports.POLLING_START = exports.POLLING_SMART_PAUSING = exports.NEW_FACTORY = exports.NEW_SHARED_CLIENT = exports.IMPRESSION_QUEUEING = exports.CLIENT_READY = exports.CLIENT_READY_FROM_CACHE = exports.ENGINE_DEFAULT = exports.ENGINE_MATCHER_RESULT = exports.SETTINGS_SPLITS_FILTER = exports.SYNC_TASK_STOP = exports.SYNC_TASK_EXECUTE = exports.SYNC_TASK_START = exports.STREAMING_NEW_MESSAGE = exports.SYNC_RBS_UPDATE = exports.SYNC_SPLITS_UPDATE = exports.SYNC_SPLITS_FETCH = exports.SYNC_OFFLINE_DATA = exports.RETRIEVE_MANAGER = exports.RETRIEVE_CLIENT_EXISTING = exports.RETRIEVE_CLIENT_DEFAULT = exports.CLEANUP_DEREGISTERING = exports.CLEANUP_REGISTERING = exports.ENGINE_SANITIZE = exports.ENGINE_VALUE = exports.ENGINE_MATCHER_DEPENDENCY_PRE = exports.ENGINE_MATCHER_DEPENDENCY = exports.ENGINE_BUCKET = exports.ENGINE_COMBINER_IFELSEIF_NO_TREATMENT = exports.ENGINE_COMBINER_IFELSEIF = exports.ENGINE_COMBINER_AND = void 0;
4
4
  exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = exports.ERROR_EVENT_TYPE_FORMAT = exports.ERROR_EVENTS_TRACKER = exports.ERROR_IMPRESSIONS_LISTENER = exports.ERROR_IMPRESSIONS_TRACKER = exports.ERROR_STREAMING_AUTH = exports.ERROR_STREAMING_SSE = exports.ERROR_SYNC_OFFLINE_LOADING = exports.ERROR_CLIENT_CANNOT_GET_READY = exports.ERROR_CLIENT_LISTENER = exports.ERROR_LOGLEVEL_INVALID = exports.ERROR_ENGINE_COMBINER_IFELSEIF = exports.WARN_FLAGSET_WITHOUT_FLAGS = exports.WARN_FLAGSET_NOT_CONFIGURED = exports.WARN_LOWERCASE_FLAGSET = exports.WARN_INVALID_FLAGSET = exports.STREAMING_PARSING_SPLIT_UPDATE = exports.STREAMING_PARSING_MEMBERSHIPS_UPDATE = exports.WARN_SDK_KEY = exports.WARN_SPLITS_FILTER_EMPTY = exports.WARN_SPLITS_FILTER_INVALID = exports.WARN_SPLITS_FILTER_IGNORED = exports.WARN_INTEGRATION_INVALID = exports.WARN_NOT_EXISTENT_TT = exports.WARN_LOWERCASE_TRAFFIC_TYPE = exports.WARN_NOT_EXISTENT_SPLIT = exports.WARN_TRIMMING = exports.WARN_CONVERTING = exports.WARN_TRIMMING_PROPERTIES = exports.WARN_SETTING_NULL = exports.SUBMITTERS_PUSH_RETRY = exports.SUBMITTERS_PUSH_FAILS = exports.STREAMING_FALLBACK = exports.STREAMING_PARSING_MESSAGE_FAILS = exports.STREAMING_PARSING_ERROR_FAILS = exports.SYNC_SPLITS_FETCH_FAILS = exports.SYNC_MYSEGMENTS_FETCH_RETRY = exports.CLIENT_NOT_READY_FROM_CACHE = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = void 0;
5
- exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_CLIENT_INSTANTIATION = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ENGINE_MATCHER_ERROR = exports.ERROR_SETS_FILTER_EXCLUSIVE = exports.ERROR_TOO_MANY_SETS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_HTTP = void 0;
5
+ exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_CLIENT_INSTANTIATION = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_FLAGSET_CACHE_DISABLED = exports.ENGINE_MATCHER_ERROR = exports.ERROR_SETS_FILTER_EXCLUSIVE = exports.ERROR_TOO_MANY_SETS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_HTTP = void 0;
6
6
  /**
7
7
  * Message codes used to trim string log messages from commons and client-side API modules,
8
8
  * in order to reduce the minimal SDK size for Browser and eventually other client-side environments.
@@ -117,6 +117,7 @@ exports.ERROR_MIN_CONFIG_PARAM = 326;
117
117
  exports.ERROR_TOO_MANY_SETS = 327;
118
118
  exports.ERROR_SETS_FILTER_EXCLUSIVE = 328;
119
119
  exports.ENGINE_MATCHER_ERROR = 329;
120
+ exports.ERROR_FLAGSET_CACHE_DISABLED = 330;
120
121
  // Log prefixes (a.k.a. tags or categories)
121
122
  exports.LOG_PREFIX_SETTINGS = 'settings';
122
123
  exports.LOG_PREFIX_INSTANTIATION = 'Factory instantiation';
@@ -33,6 +33,7 @@ exports.codesError = [
33
33
  [c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
34
34
  [c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
35
35
  [c.ERROR_NOT_BOOLEAN, '%s: provided param must be a boolean value.'],
36
+ [c.ERROR_FLAGSET_CACHE_DISABLED, 'The flag set cache is disabled via the `disableFlagSetCache` setting, so `getTreatments(WithConfig)ByFlagSet(s)` methods always return empty objects. Remove the setting to use them.'],
36
37
  // initialization / settings validation
37
38
  [c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
38
39
  [c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS + ': the provided storage is invalid.%s Falling back into default MEMORY storage'],
@@ -5,18 +5,20 @@ var tslib_1 = require("tslib");
5
5
  var AbstractSplitsCacheSync_1 = require("../AbstractSplitsCacheSync");
6
6
  var lang_1 = require("../../utils/lang");
7
7
  var constants_1 = require("./constants");
8
+ var constants_2 = require("../../logger/constants");
8
9
  var sets_1 = require("../../utils/lang/sets");
9
10
  function newBatch() {
10
11
  return { flagSets: new Map(), counts: new Map() };
11
12
  }
12
13
  var SplitsCacheInLocal = /** @class */ (function (_super) {
13
14
  tslib_1.__extends(SplitsCacheInLocal, _super);
14
- function SplitsCacheInLocal(settings, keys, storage) {
15
+ function SplitsCacheInLocal(settings, keys, storage, disableFlagSetCache) {
15
16
  var _this = _super.call(this) || this;
16
17
  _this.keys = keys;
17
18
  _this.log = settings.log;
18
19
  _this.flagSetsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
19
20
  _this.storage = storage;
21
+ _this.disableFlagSetCache = disableFlagSetCache;
20
22
  return _this;
21
23
  }
22
24
  SplitsCacheInLocal.prototype.updateCount = function (batch, key, diff) {
@@ -161,6 +163,10 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
161
163
  };
162
164
  SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
163
165
  var _this = this;
166
+ if (this.disableFlagSetCache) {
167
+ this.log.error(constants_2.ERROR_FLAGSET_CACHE_DISABLED);
168
+ return flagSets.map(function () { return new Set(); });
169
+ }
164
170
  return flagSets.map(function (flagSet) {
165
171
  var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
166
172
  var flagSetFromStorage = _this.storage.getItem(flagSetKey);
@@ -169,7 +175,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
169
175
  };
170
176
  SplitsCacheInLocal.prototype.addToFlagSets = function (featureFlag, batch) {
171
177
  var _this = this;
172
- if (!featureFlag.sets)
178
+ if (this.disableFlagSetCache || !featureFlag.sets)
173
179
  return;
174
180
  featureFlag.sets.forEach(function (featureFlagSet) {
175
181
  if (_this.flagSetsFilter.length > 0 && !_this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === featureFlagSet; }))
@@ -180,7 +186,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
180
186
  };
181
187
  SplitsCacheInLocal.prototype.removeFromFlagSets = function (featureFlagName, flagSets, batch) {
182
188
  var _this = this;
183
- if (!flagSets)
189
+ if (this.disableFlagSetCache || !flagSets)
184
190
  return;
185
191
  flagSets.forEach(function (flagSet) {
186
192
  _this.removeNames(flagSet, featureFlagName, batch);
@@ -18,6 +18,8 @@ var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS
18
18
  var key_1 = require("../../utils/key");
19
19
  var validateCache_1 = require("./validateCache");
20
20
  var storageAdapter_1 = require("./storageAdapter");
21
+ var lang_1 = require("../../utils/lang");
22
+ var constants_3 = require("../../logger/constants");
21
23
  function validateStorage(log, prefix, wrapper) {
22
24
  if (wrapper) {
23
25
  if ((0, isLocalStorageAvailable_1.isValidStorageWrapper)(wrapper)) {
@@ -44,7 +46,10 @@ function InLocalStorage(options) {
44
46
  return (0, InMemoryStorageCS_1.InMemoryStorageCSFactory)(params);
45
47
  var matchingKey = (0, key_1.getMatching)(settings.core.key);
46
48
  var keys = new KeyBuilderCS_1.KeyBuilderCS(prefix, matchingKey);
47
- var splits = new SplitsCacheInLocal_1.SplitsCacheInLocal(settings, keys, storage);
49
+ if (options.disableFlagSetCache !== undefined && !(0, lang_1.isBoolean)(options.disableFlagSetCache)) {
50
+ log.error(constants_3.ERROR_INVALID_CONFIG_PARAM, ['disableFlagSetCache', 'true, false', 'false']);
51
+ }
52
+ var splits = new SplitsCacheInLocal_1.SplitsCacheInLocal(settings, keys, storage, options.disableFlagSetCache === true);
48
53
  var rbSegments = new RBSegmentsCacheInLocal_1.RBSegmentsCacheInLocal(settings, keys, storage);
49
54
  var segments = new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys, storage);
50
55
  var largeSegments = new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, (0, KeyBuilderCS_1.myLargeSegmentsKeyBuilder)(prefix, matchingKey), storage);
@@ -112,6 +112,7 @@ export var ERROR_MIN_CONFIG_PARAM = 326;
112
112
  export var ERROR_TOO_MANY_SETS = 327;
113
113
  export var ERROR_SETS_FILTER_EXCLUSIVE = 328;
114
114
  export var ENGINE_MATCHER_ERROR = 329;
115
+ export var ERROR_FLAGSET_CACHE_DISABLED = 330;
115
116
  // Log prefixes (a.k.a. tags or categories)
116
117
  export var LOG_PREFIX_SETTINGS = 'settings';
117
118
  export var LOG_PREFIX_INSTANTIATION = 'Factory instantiation';
@@ -29,6 +29,7 @@ export var codesError = [
29
29
  [c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
30
30
  [c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
31
31
  [c.ERROR_NOT_BOOLEAN, '%s: provided param must be a boolean value.'],
32
+ [c.ERROR_FLAGSET_CACHE_DISABLED, 'The flag set cache is disabled via the `disableFlagSetCache` setting, so `getTreatments(WithConfig)ByFlagSet(s)` methods always return empty objects. Remove the setting to use them.'],
32
33
  // initialization / settings validation
33
34
  [c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
34
35
  [c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS + ': the provided storage is invalid.%s Falling back into default MEMORY storage'],
@@ -2,18 +2,20 @@ import { __extends } from "tslib";
2
2
  import { AbstractSplitsCacheSync, usesSegments } from '../AbstractSplitsCacheSync';
3
3
  import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
4
4
  import { LOG_PREFIX } from './constants';
5
+ import { ERROR_FLAGSET_CACHE_DISABLED } from '../../logger/constants';
5
6
  import { setToArray } from '../../utils/lang/sets';
6
7
  function newBatch() {
7
8
  return { flagSets: new Map(), counts: new Map() };
8
9
  }
9
10
  var SplitsCacheInLocal = /** @class */ (function (_super) {
10
11
  __extends(SplitsCacheInLocal, _super);
11
- function SplitsCacheInLocal(settings, keys, storage) {
12
+ function SplitsCacheInLocal(settings, keys, storage, disableFlagSetCache) {
12
13
  var _this = _super.call(this) || this;
13
14
  _this.keys = keys;
14
15
  _this.log = settings.log;
15
16
  _this.flagSetsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
16
17
  _this.storage = storage;
18
+ _this.disableFlagSetCache = disableFlagSetCache;
17
19
  return _this;
18
20
  }
19
21
  SplitsCacheInLocal.prototype.updateCount = function (batch, key, diff) {
@@ -158,6 +160,10 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
158
160
  };
159
161
  SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
160
162
  var _this = this;
163
+ if (this.disableFlagSetCache) {
164
+ this.log.error(ERROR_FLAGSET_CACHE_DISABLED);
165
+ return flagSets.map(function () { return new Set(); });
166
+ }
161
167
  return flagSets.map(function (flagSet) {
162
168
  var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
163
169
  var flagSetFromStorage = _this.storage.getItem(flagSetKey);
@@ -166,7 +172,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
166
172
  };
167
173
  SplitsCacheInLocal.prototype.addToFlagSets = function (featureFlag, batch) {
168
174
  var _this = this;
169
- if (!featureFlag.sets)
175
+ if (this.disableFlagSetCache || !featureFlag.sets)
170
176
  return;
171
177
  featureFlag.sets.forEach(function (featureFlagSet) {
172
178
  if (_this.flagSetsFilter.length > 0 && !_this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === featureFlagSet; }))
@@ -177,7 +183,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
177
183
  };
178
184
  SplitsCacheInLocal.prototype.removeFromFlagSets = function (featureFlagName, flagSets, batch) {
179
185
  var _this = this;
180
- if (!flagSets)
186
+ if (this.disableFlagSetCache || !flagSets)
181
187
  return;
182
188
  flagSets.forEach(function (flagSet) {
183
189
  _this.removeNames(flagSet, featureFlagName, batch);
@@ -15,6 +15,8 @@ import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS
15
15
  import { getMatching } from '../../utils/key';
16
16
  import { validateCache } from './validateCache';
17
17
  import { storageAdapter } from './storageAdapter';
18
+ import { isBoolean } from '../../utils/lang';
19
+ import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
18
20
  function validateStorage(log, prefix, wrapper) {
19
21
  if (wrapper) {
20
22
  if (isValidStorageWrapper(wrapper)) {
@@ -41,7 +43,10 @@ export function InLocalStorage(options) {
41
43
  return InMemoryStorageCSFactory(params);
42
44
  var matchingKey = getMatching(settings.core.key);
43
45
  var keys = new KeyBuilderCS(prefix, matchingKey);
44
- var splits = new SplitsCacheInLocal(settings, keys, storage);
46
+ if (options.disableFlagSetCache !== undefined && !isBoolean(options.disableFlagSetCache)) {
47
+ log.error(ERROR_INVALID_CONFIG_PARAM, ['disableFlagSetCache', 'true, false', 'false']);
48
+ }
49
+ var splits = new SplitsCacheInLocal(settings, keys, storage, options.disableFlagSetCache === true);
45
50
  var rbSegments = new RBSegmentsCacheInLocal(settings, keys, storage);
46
51
  var segments = new MySegmentsCacheInLocal(log, keys, storage);
47
52
  var largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey), storage);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "2.13.1",
3
+ "version": "2.14.0-rc.0",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -115,6 +115,7 @@ export const ERROR_MIN_CONFIG_PARAM = 326;
115
115
  export const ERROR_TOO_MANY_SETS = 327;
116
116
  export const ERROR_SETS_FILTER_EXCLUSIVE = 328;
117
117
  export const ENGINE_MATCHER_ERROR = 329;
118
+ export const ERROR_FLAGSET_CACHE_DISABLED = 330;
118
119
 
119
120
  // Log prefixes (a.k.a. tags or categories)
120
121
  export const LOG_PREFIX_SETTINGS = 'settings';
@@ -30,6 +30,7 @@ export const codesError: [number, string][] = [
30
30
  [c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
31
31
  [c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
32
32
  [c.ERROR_NOT_BOOLEAN, '%s: provided param must be a boolean value.'],
33
+ [c.ERROR_FLAGSET_CACHE_DISABLED, 'The flag set cache is disabled via the `disableFlagSetCache` setting, so `getTreatments(WithConfig)ByFlagSet(s)` methods always return empty objects. Remove the setting to use them.'],
33
34
  // initialization / settings validation
34
35
  [c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
35
36
  [c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS+': the provided storage is invalid.%s Falling back into default MEMORY storage'],
@@ -4,6 +4,7 @@ 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 { ERROR_FLAGSET_CACHE_DISABLED } from '../../logger/constants';
7
8
  import { ISettings } from '../../types';
8
9
  import { setToArray } from '../../utils/lang/sets';
9
10
  import { StorageAdapter } from '../types';
@@ -25,15 +26,17 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
25
26
  private readonly keys: KeyBuilderCS;
26
27
  private readonly log: ILogger;
27
28
  private readonly flagSetsFilter: string[];
29
+ private readonly disableFlagSetCache?: boolean;
28
30
  private hasSync?: boolean;
29
31
  private readonly storage: StorageAdapter;
30
32
 
31
- constructor(settings: ISettings, keys: KeyBuilderCS, storage: StorageAdapter) {
33
+ constructor(settings: ISettings, keys: KeyBuilderCS, storage: StorageAdapter, disableFlagSetCache?: boolean) {
32
34
  super();
33
35
  this.keys = keys;
34
36
  this.log = settings.log;
35
37
  this.flagSetsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
36
38
  this.storage = storage;
39
+ this.disableFlagSetCache = disableFlagSetCache;
37
40
  }
38
41
 
39
42
  private updateCount(batch: UpdateBatch, key: string, diff: number) {
@@ -198,6 +201,11 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
198
201
  }
199
202
 
200
203
  getNamesByFlagSets(flagSets: string[]): Set<string>[] {
204
+ if (this.disableFlagSetCache) {
205
+ this.log.error(ERROR_FLAGSET_CACHE_DISABLED);
206
+ return flagSets.map(() => new Set<string>());
207
+ }
208
+
201
209
  return flagSets.map(flagSet => {
202
210
  const flagSetKey = this.keys.buildFlagSetKey(flagSet);
203
211
  const flagSetFromStorage = this.storage.getItem(flagSetKey);
@@ -207,7 +215,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
207
215
  }
208
216
 
209
217
  private addToFlagSets(featureFlag: ISplit, batch: UpdateBatch) {
210
- if (!featureFlag.sets) return;
218
+ if (this.disableFlagSetCache || !featureFlag.sets) return;
211
219
 
212
220
  featureFlag.sets.forEach(featureFlagSet => {
213
221
 
@@ -220,7 +228,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
220
228
  }
221
229
 
222
230
  private removeFromFlagSets(featureFlagName: string, flagSets: string[] | null | undefined, batch: UpdateBatch) {
223
- if (!flagSets) return;
231
+ if (this.disableFlagSetCache || !flagSets) return;
224
232
 
225
233
  flagSets.forEach(flagSet => {
226
234
  this.removeNames(flagSet, featureFlagName, batch);
@@ -18,6 +18,8 @@ import { validateCache } from './validateCache';
18
18
  import { ILogger } from '../../logger/types';
19
19
  import SplitIO from '../../../types/splitio';
20
20
  import { storageAdapter } from './storageAdapter';
21
+ import { isBoolean } from '../../utils/lang';
22
+ import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
21
23
 
22
24
  function validateStorage(log: ILogger, prefix: string, wrapper?: SplitIO.StorageWrapper): StorageAdapter | undefined {
23
25
  if (wrapper) {
@@ -50,7 +52,11 @@ export function InLocalStorage(options: SplitIO.InLocalStorageOptions = {}): ISt
50
52
  const matchingKey = getMatching(settings.core.key);
51
53
  const keys = new KeyBuilderCS(prefix, matchingKey);
52
54
 
53
- const splits = new SplitsCacheInLocal(settings, keys, storage);
55
+ if (options.disableFlagSetCache !== undefined && !isBoolean(options.disableFlagSetCache)) {
56
+ log.error(ERROR_INVALID_CONFIG_PARAM, ['disableFlagSetCache', 'true, false', 'false']);
57
+ }
58
+
59
+ const splits = new SplitsCacheInLocal(settings, keys, storage, options.disableFlagSetCache === true);
54
60
  const rbSegments = new RBSegmentsCacheInLocal(settings, keys, storage);
55
61
  const segments = new MySegmentsCacheInLocal(log, keys, storage);
56
62
  const largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey), storage);
@@ -1162,6 +1162,15 @@ declare namespace SplitIO {
1162
1162
  * @defaultValue `window.localStorage`
1163
1163
  */
1164
1164
  wrapper?: StorageWrapper;
1165
+ /**
1166
+ * If set to `true`, the SDK does not build the flag set index when it stores feature flag definitions, which speeds up the SDK initialization (SDK_READY event) and updates (SDK_UPDATE event).
1167
+ *
1168
+ * NOTE: when enabled, the `getTreatments(WithConfig)ByFlagSet(s)` methods return empty results.
1169
+ * If you disable it afterwards, clear the cached data (e.g., with `storage.clearOnInit`) so the index is rebuilt.
1170
+ *
1171
+ * @defaultValue `false`
1172
+ */
1173
+ disableFlagSetCache?: boolean;
1165
1174
  }
1166
1175
  /**
1167
1176
  * Storage for asynchronous (consumer) SDK.
@@ -1542,6 +1551,15 @@ declare namespace SplitIO {
1542
1551
  * @defaultValue `window.localStorage`
1543
1552
  */
1544
1553
  wrapper?: StorageWrapper;
1554
+ /**
1555
+ * Optional settings for the 'LOCALSTORAGE' storage type. If set to `true`, the SDK does not build the flag set index when it stores feature flag definitions, which speeds up the SDK initialization (SDK_READY event) and updates (SDK_UPDATE event).
1556
+ *
1557
+ * NOTE: when enabled, the `getTreatments(WithConfig)ByFlagSet(s)` methods return empty results.
1558
+ * If you disable it afterwards, clear the cached data (e.g., with `storage.clearOnInit`) so the index is rebuilt.
1559
+ *
1560
+ * @defaultValue `false`
1561
+ */
1562
+ disableFlagSetCache?: boolean;
1545
1563
  };
1546
1564
  }
1547
1565
  /**