@splitsoftware/splitio-commons 2.1.0-rc.0 → 2.1.0-rc.1
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 +7 -0
- package/cjs/evaluator/matchers/large_segment.js +0 -6
- package/cjs/evaluator/matchers/segment.js +0 -6
- package/cjs/readiness/readinessManager.js +6 -0
- package/cjs/storages/inLocalStorage/validateCache.js +1 -2
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +1 -1
- package/esm/evaluator/matchers/large_segment.js +0 -6
- package/esm/evaluator/matchers/segment.js +0 -6
- package/esm/readiness/readinessManager.js +6 -0
- package/esm/storages/inLocalStorage/validateCache.js +1 -2
- package/esm/storages/inRedis/SplitsCacheInRedis.js +1 -1
- package/package.json +1 -1
- package/src/evaluator/matchers/large_segment.ts +0 -7
- package/src/evaluator/matchers/segment.ts +0 -7
- package/src/readiness/readinessManager.ts +5 -0
- package/src/storages/inLocalStorage/validateCache.ts +1 -2
- package/src/storages/inRedis/SplitsCacheInRedis.ts +1 -1
package/CHANGES.txt
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
2.1.0 (January XX, 2025)
|
|
2
|
+
- Added two new configuration options for the SDK storage in browsers when using storage type `LOCALSTORAGE`:
|
|
3
|
+
- `storage.expirationDays` to specify the validity period of the rollout cache.
|
|
4
|
+
- `storage.clearOnInit` to clear the rollout cache on SDK initialization.
|
|
5
|
+
- Updated SDK_READY_FROM_CACHE event when using `LOCALSTORAGE` storage type to be emitted alongside SDK_READY event in case it has not been emitted.
|
|
6
|
+
- Bugfixing - Properly handle rejected promises when using targeting rules with segment matchers in consumer modes (e.g., Redis and Pluggable storages).
|
|
7
|
+
|
|
1
8
|
2.0.2 (December 3, 2024)
|
|
2
9
|
- Updated the factory `init` and `destroy` methods to support re-initialization after destruction. This update ensures compatibility of the React SDK with React Strict Mode, where the factory's `init` and `destroy` effects are executed an extra time to validate proper resource cleanup.
|
|
3
10
|
- Bugfixing - Sanitize the `SplitSDKMachineName` header value to avoid exceptions on HTTP/S requests when it contains non ISO-8859-1 characters (Related to issue https://github.com/splitio/javascript-client/issues/847).
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.largeSegmentMatcherContext = void 0;
|
|
4
|
-
var thenable_1 = require("../../utils/promise/thenable");
|
|
5
4
|
function largeSegmentMatcherContext(largeSegmentName, storage) {
|
|
6
5
|
return function largeSegmentMatcher(key) {
|
|
7
6
|
var isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false;
|
|
8
|
-
if ((0, thenable_1.thenable)(isInLargeSegment)) {
|
|
9
|
-
isInLargeSegment.then(function (result) {
|
|
10
|
-
return result;
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
7
|
return isInLargeSegment;
|
|
14
8
|
};
|
|
15
9
|
}
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.segmentMatcherContext = void 0;
|
|
4
|
-
var thenable_1 = require("../../utils/promise/thenable");
|
|
5
4
|
function segmentMatcherContext(segmentName, storage) {
|
|
6
5
|
return function segmentMatcher(key) {
|
|
7
6
|
var isInSegment = storage.segments.isInSegment(segmentName, key);
|
|
8
|
-
if ((0, thenable_1.thenable)(isInSegment)) {
|
|
9
|
-
isInSegment.then(function (result) {
|
|
10
|
-
return result;
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
7
|
return isInSegment;
|
|
14
8
|
};
|
|
15
9
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.readinessManagerFactory = void 0;
|
|
4
4
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
5
|
var constants_1 = require("./constants");
|
|
6
|
+
var constants_2 = require("../utils/constants");
|
|
6
7
|
function splitsEventEmitterFactory(EventEmitter) {
|
|
7
8
|
var splitsEventEmitter = (0, objectAssign_1.objectAssign)(new EventEmitter(), {
|
|
8
9
|
splitsArrived: false,
|
|
@@ -83,6 +84,7 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
function checkIsReadyOrUpdate(diff) {
|
|
87
|
+
var _a;
|
|
86
88
|
if (isDestroyed)
|
|
87
89
|
return;
|
|
88
90
|
if (isReady) {
|
|
@@ -101,6 +103,10 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
101
103
|
isReady = true;
|
|
102
104
|
try {
|
|
103
105
|
syncLastUpdate();
|
|
106
|
+
if (!isReadyFromCache && ((_a = settings.storage) === null || _a === void 0 ? void 0 : _a.type) === constants_2.STORAGE_LOCALSTORAGE) {
|
|
107
|
+
isReadyFromCache = true;
|
|
108
|
+
gate.emit(constants_1.SDK_READY_FROM_CACHE);
|
|
109
|
+
}
|
|
104
110
|
gate.emit(constants_1.SDK_READY);
|
|
105
111
|
}
|
|
106
112
|
catch (e) {
|
|
@@ -4,7 +4,6 @@ exports.validateCache = void 0;
|
|
|
4
4
|
var lang_1 = require("../../utils/lang");
|
|
5
5
|
var KeyBuilder_1 = require("../KeyBuilder");
|
|
6
6
|
var constants_1 = require("./constants");
|
|
7
|
-
// milliseconds in a day
|
|
8
7
|
var DEFAULT_CACHE_EXPIRATION_IN_DAYS = 10;
|
|
9
8
|
var MILLIS_IN_A_DAY = 86400000;
|
|
10
9
|
/**
|
|
@@ -36,7 +35,7 @@ function validateExpiration(options, settings, keys, currentTimestamp, isThereCa
|
|
|
36
35
|
log.error(constants_1.LOG_PREFIX + e);
|
|
37
36
|
}
|
|
38
37
|
if (isThereCache) {
|
|
39
|
-
log.info(constants_1.LOG_PREFIX + 'SDK key, flags filter criteria or flags spec version has changed. Cleaning up cache');
|
|
38
|
+
log.info(constants_1.LOG_PREFIX + 'SDK key, flags filter criteria, or flags spec version has changed. Cleaning up cache');
|
|
40
39
|
return true;
|
|
41
40
|
}
|
|
42
41
|
return false; // No cache to clear
|
|
@@ -241,9 +241,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
241
241
|
this.log.error(constants_1.LOG_PREFIX + this.redisError);
|
|
242
242
|
return Promise.reject(this.redisError);
|
|
243
243
|
}
|
|
244
|
-
var splits = {};
|
|
245
244
|
var keys = names.map(function (name) { return _this.keys.buildSplitKey(name); });
|
|
246
245
|
return (_a = this.redis).mget.apply(_a, keys).then(function (splitDefinitions) {
|
|
246
|
+
var splits = {};
|
|
247
247
|
names.forEach(function (name, idx) {
|
|
248
248
|
var split = splitDefinitions[idx];
|
|
249
249
|
splits[name] = split && JSON.parse(split);
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { thenable } from '../../utils/promise/thenable';
|
|
2
1
|
export function largeSegmentMatcherContext(largeSegmentName, storage) {
|
|
3
2
|
return function largeSegmentMatcher(key) {
|
|
4
3
|
var isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false;
|
|
5
|
-
if (thenable(isInLargeSegment)) {
|
|
6
|
-
isInLargeSegment.then(function (result) {
|
|
7
|
-
return result;
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
4
|
return isInLargeSegment;
|
|
11
5
|
};
|
|
12
6
|
}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { thenable } from '../../utils/promise/thenable';
|
|
2
1
|
export function segmentMatcherContext(segmentName, storage) {
|
|
3
2
|
return function segmentMatcher(key) {
|
|
4
3
|
var isInSegment = storage.segments.isInSegment(segmentName, key);
|
|
5
|
-
if (thenable(isInSegment)) {
|
|
6
|
-
isInSegment.then(function (result) {
|
|
7
|
-
return result;
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
4
|
return isInSegment;
|
|
11
5
|
};
|
|
12
6
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
|
|
3
|
+
import { STORAGE_LOCALSTORAGE } from '../utils/constants';
|
|
3
4
|
function splitsEventEmitterFactory(EventEmitter) {
|
|
4
5
|
var splitsEventEmitter = objectAssign(new EventEmitter(), {
|
|
5
6
|
splitsArrived: false,
|
|
@@ -80,6 +81,7 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
function checkIsReadyOrUpdate(diff) {
|
|
84
|
+
var _a;
|
|
83
85
|
if (isDestroyed)
|
|
84
86
|
return;
|
|
85
87
|
if (isReady) {
|
|
@@ -98,6 +100,10 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
|
|
|
98
100
|
isReady = true;
|
|
99
101
|
try {
|
|
100
102
|
syncLastUpdate();
|
|
103
|
+
if (!isReadyFromCache && ((_a = settings.storage) === null || _a === void 0 ? void 0 : _a.type) === STORAGE_LOCALSTORAGE) {
|
|
104
|
+
isReadyFromCache = true;
|
|
105
|
+
gate.emit(SDK_READY_FROM_CACHE);
|
|
106
|
+
}
|
|
101
107
|
gate.emit(SDK_READY);
|
|
102
108
|
}
|
|
103
109
|
catch (e) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { isFiniteNumber, isNaNNumber } from '../../utils/lang';
|
|
2
2
|
import { getStorageHash } from '../KeyBuilder';
|
|
3
3
|
import { LOG_PREFIX } from './constants';
|
|
4
|
-
// milliseconds in a day
|
|
5
4
|
var DEFAULT_CACHE_EXPIRATION_IN_DAYS = 10;
|
|
6
5
|
var MILLIS_IN_A_DAY = 86400000;
|
|
7
6
|
/**
|
|
@@ -33,7 +32,7 @@ function validateExpiration(options, settings, keys, currentTimestamp, isThereCa
|
|
|
33
32
|
log.error(LOG_PREFIX + e);
|
|
34
33
|
}
|
|
35
34
|
if (isThereCache) {
|
|
36
|
-
log.info(LOG_PREFIX + 'SDK key, flags filter criteria or flags spec version has changed. Cleaning up cache');
|
|
35
|
+
log.info(LOG_PREFIX + 'SDK key, flags filter criteria, or flags spec version has changed. Cleaning up cache');
|
|
37
36
|
return true;
|
|
38
37
|
}
|
|
39
38
|
return false; // No cache to clear
|
|
@@ -238,9 +238,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
238
238
|
this.log.error(LOG_PREFIX + this.redisError);
|
|
239
239
|
return Promise.reject(this.redisError);
|
|
240
240
|
}
|
|
241
|
-
var splits = {};
|
|
242
241
|
var keys = names.map(function (name) { return _this.keys.buildSplitKey(name); });
|
|
243
242
|
return (_a = this.redis).mget.apply(_a, keys).then(function (splitDefinitions) {
|
|
243
|
+
var splits = {};
|
|
244
244
|
names.forEach(function (name, idx) {
|
|
245
245
|
var split = splitDefinitions[idx];
|
|
246
246
|
splits[name] = split && JSON.parse(split);
|
package/package.json
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { MaybeThenable } from '../../dtos/types';
|
|
2
2
|
import { ISegmentsCacheBase } from '../../storages/types';
|
|
3
|
-
import { thenable } from '../../utils/promise/thenable';
|
|
4
3
|
|
|
5
4
|
export function largeSegmentMatcherContext(largeSegmentName: string, storage: { largeSegments?: ISegmentsCacheBase }) {
|
|
6
5
|
|
|
7
6
|
return function largeSegmentMatcher(key: string): MaybeThenable<boolean> {
|
|
8
7
|
const isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false;
|
|
9
8
|
|
|
10
|
-
if (thenable(isInLargeSegment)) {
|
|
11
|
-
isInLargeSegment.then(result => {
|
|
12
|
-
return result;
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
9
|
return isInLargeSegment;
|
|
17
10
|
};
|
|
18
11
|
}
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { MaybeThenable } from '../../dtos/types';
|
|
2
2
|
import { ISegmentsCacheBase } from '../../storages/types';
|
|
3
|
-
import { thenable } from '../../utils/promise/thenable';
|
|
4
3
|
|
|
5
4
|
export function segmentMatcherContext(segmentName: string, storage: { segments: ISegmentsCacheBase }) {
|
|
6
5
|
|
|
7
6
|
return function segmentMatcher(key: string): MaybeThenable<boolean> {
|
|
8
7
|
const isInSegment = storage.segments.isInSegment(segmentName, key);
|
|
9
8
|
|
|
10
|
-
if (thenable(isInSegment)) {
|
|
11
|
-
isInSegment.then(result => {
|
|
12
|
-
return result;
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
9
|
return isInSegment;
|
|
17
10
|
};
|
|
18
11
|
}
|
|
@@ -3,6 +3,7 @@ import { ISettings } from '../types';
|
|
|
3
3
|
import SplitIO from '../../types/splitio';
|
|
4
4
|
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
|
|
5
5
|
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
|
|
6
|
+
import { STORAGE_LOCALSTORAGE } from '../utils/constants';
|
|
6
7
|
|
|
7
8
|
function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): ISplitsEventEmitter {
|
|
8
9
|
const splitsEventEmitter = objectAssign(new EventEmitter(), {
|
|
@@ -114,6 +115,10 @@ export function readinessManagerFactory(
|
|
|
114
115
|
isReady = true;
|
|
115
116
|
try {
|
|
116
117
|
syncLastUpdate();
|
|
118
|
+
if (!isReadyFromCache && settings.storage?.type === STORAGE_LOCALSTORAGE) {
|
|
119
|
+
isReadyFromCache = true;
|
|
120
|
+
gate.emit(SDK_READY_FROM_CACHE);
|
|
121
|
+
}
|
|
117
122
|
gate.emit(SDK_READY);
|
|
118
123
|
} catch (e) {
|
|
119
124
|
// throws user callback exceptions in next tick
|
|
@@ -7,7 +7,6 @@ import type { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
|
|
|
7
7
|
import { KeyBuilderCS } from '../KeyBuilderCS';
|
|
8
8
|
import SplitIO from '../../../types/splitio';
|
|
9
9
|
|
|
10
|
-
// milliseconds in a day
|
|
11
10
|
const DEFAULT_CACHE_EXPIRATION_IN_DAYS = 10;
|
|
12
11
|
const MILLIS_IN_A_DAY = 86400000;
|
|
13
12
|
|
|
@@ -42,7 +41,7 @@ function validateExpiration(options: SplitIO.InLocalStorageOptions, settings: IS
|
|
|
42
41
|
log.error(LOG_PREFIX + e);
|
|
43
42
|
}
|
|
44
43
|
if (isThereCache) {
|
|
45
|
-
log.info(LOG_PREFIX + 'SDK key, flags filter criteria or flags spec version has changed. Cleaning up cache');
|
|
44
|
+
log.info(LOG_PREFIX + 'SDK key, flags filter criteria, or flags spec version has changed. Cleaning up cache');
|
|
46
45
|
return true;
|
|
47
46
|
}
|
|
48
47
|
return false; // No cache to clear
|
|
@@ -266,10 +266,10 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
266
266
|
return Promise.reject(this.redisError);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
const splits: Record<string, ISplit | null> = {};
|
|
270
269
|
const keys = names.map(name => this.keys.buildSplitKey(name));
|
|
271
270
|
return this.redis.mget(...keys)
|
|
272
271
|
.then(splitDefinitions => {
|
|
272
|
+
const splits: Record<string, ISplit | null> = {};
|
|
273
273
|
names.forEach((name, idx) => {
|
|
274
274
|
const split = splitDefinitions[idx];
|
|
275
275
|
splits[name] = split && JSON.parse(split);
|