@splitsoftware/splitio-commons 1.17.1-rc.4 → 2.0.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 +4 -0
- package/cjs/evaluator/Engine.js +1 -1
- package/cjs/evaluator/index.js +1 -1
- package/cjs/evaluator/matchers/semver_inlist.js +1 -2
- package/cjs/evaluator/matchers/whitelist.js +1 -2
- package/cjs/listeners/browser.js +1 -2
- package/cjs/logger/browser/DebugLogger.js +1 -2
- package/cjs/logger/browser/ErrorLogger.js +1 -2
- package/cjs/logger/browser/InfoLogger.js +1 -2
- package/cjs/logger/browser/WarnLogger.js +1 -2
- package/cjs/logger/index.js +1 -2
- package/cjs/sdkClient/clientCS.js +5 -8
- package/cjs/sdkClient/sdkClientMethodCS.js +1 -1
- package/cjs/services/decorateHeaders.js +1 -2
- package/cjs/storages/KeyBuilderCS.js +0 -9
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -21
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +4 -4
- package/cjs/storages/inLocalStorage/index.js +1 -1
- package/cjs/storages/inMemory/InMemoryStorageCS.js +1 -1
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +2 -3
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -3
- package/cjs/storages/inMemory/UniqueKeysCacheInMemory.js +2 -2
- package/cjs/storages/inMemory/UniqueKeysCacheInMemoryCS.js +2 -2
- package/cjs/storages/inRedis/RedisAdapter.js +2 -2
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +3 -4
- package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +6 -7
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/cjs/storages/pluggable/inMemoryWrapper.js +6 -6
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +0 -1
- package/cjs/sync/streaming/pushManager.js +2 -3
- package/cjs/utils/LRUCache/index.js +1 -2
- package/cjs/utils/constants/browser.js +1 -4
- package/cjs/utils/lang/index.js +6 -9
- package/cjs/utils/lang/objectAssign.js +12 -77
- package/cjs/utils/lang/sets.js +10 -107
- package/cjs/utils/settingsValidation/index.js +0 -9
- package/cjs/utils/settingsValidation/logger/builtinLogger.js +1 -2
- package/esm/evaluator/Engine.js +1 -1
- package/esm/evaluator/index.js +2 -2
- package/esm/evaluator/matchers/semver_inlist.js +1 -2
- package/esm/evaluator/matchers/whitelist.js +1 -2
- package/esm/listeners/browser.js +1 -2
- package/esm/logger/browser/DebugLogger.js +1 -2
- package/esm/logger/browser/ErrorLogger.js +1 -2
- package/esm/logger/browser/InfoLogger.js +1 -2
- package/esm/logger/browser/WarnLogger.js +1 -2
- package/esm/logger/index.js +1 -2
- package/esm/sdkClient/clientCS.js +5 -8
- package/esm/sdkClient/sdkClientMethodCS.js +1 -1
- package/esm/services/decorateHeaders.js +1 -2
- package/esm/storages/KeyBuilderCS.js +0 -9
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -21
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +4 -4
- package/esm/storages/inLocalStorage/index.js +1 -1
- package/esm/storages/inMemory/InMemoryStorageCS.js +1 -1
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +2 -3
- package/esm/storages/inMemory/SplitsCacheInMemory.js +2 -3
- package/esm/storages/inMemory/UniqueKeysCacheInMemory.js +2 -2
- package/esm/storages/inMemory/UniqueKeysCacheInMemoryCS.js +2 -2
- package/esm/storages/inRedis/RedisAdapter.js +2 -2
- package/esm/storages/inRedis/SplitsCacheInRedis.js +2 -2
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +3 -4
- package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
- package/esm/storages/pluggable/TelemetryCachePluggable.js +6 -7
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/esm/storages/pluggable/inMemoryWrapper.js +7 -7
- package/esm/sync/polling/updaters/splitChangesUpdater.js +3 -3
- package/esm/sync/streaming/parseUtils.js +0 -1
- package/esm/sync/streaming/pushManager.js +2 -3
- package/esm/utils/LRUCache/index.js +1 -2
- package/esm/utils/constants/browser.js +0 -3
- package/esm/utils/lang/index.js +6 -9
- package/esm/utils/lang/objectAssign.js +12 -77
- package/esm/utils/lang/sets.js +9 -105
- package/esm/utils/settingsValidation/index.js +0 -9
- package/esm/utils/settingsValidation/logger/builtinLogger.js +1 -2
- package/package.json +2 -2
- package/src/evaluator/Engine.ts +1 -1
- package/src/evaluator/index.ts +4 -4
- package/src/evaluator/matchers/semver_inlist.ts +1 -2
- package/src/evaluator/matchers/whitelist.ts +1 -3
- package/src/listeners/browser.ts +1 -2
- package/src/logger/browser/DebugLogger.ts +1 -2
- package/src/logger/browser/ErrorLogger.ts +1 -2
- package/src/logger/browser/InfoLogger.ts +1 -2
- package/src/logger/browser/WarnLogger.ts +1 -2
- package/src/logger/index.ts +3 -4
- package/src/sdkClient/clientCS.ts +5 -8
- package/src/sdkClient/sdkClientMethodCS.ts +1 -1
- package/src/sdkFactory/types.ts +1 -1
- package/src/services/decorateHeaders.ts +1 -2
- package/src/storages/AbstractSplitsCacheAsync.ts +1 -2
- package/src/storages/AbstractSplitsCacheSync.ts +1 -2
- package/src/storages/KeyBuilderCS.ts +0 -13
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +1 -21
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +5 -5
- package/src/storages/inLocalStorage/index.ts +1 -1
- package/src/storages/inMemory/InMemoryStorageCS.ts +1 -1
- package/src/storages/inMemory/SegmentsCacheInMemory.ts +3 -4
- package/src/storages/inMemory/SplitsCacheInMemory.ts +4 -5
- package/src/storages/inMemory/UniqueKeysCacheInMemory.ts +4 -4
- package/src/storages/inMemory/UniqueKeysCacheInMemoryCS.ts +4 -4
- package/src/storages/inRedis/RedisAdapter.ts +3 -3
- package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -3
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +3 -4
- package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +1 -1
- package/src/storages/pluggable/SegmentsCachePluggable.ts +0 -1
- package/src/storages/pluggable/SplitsCachePluggable.ts +3 -3
- package/src/storages/pluggable/TelemetryCachePluggable.ts +6 -7
- package/src/storages/pluggable/UniqueKeysCachePluggable.ts +1 -1
- package/src/storages/pluggable/inMemoryWrapper.ts +9 -9
- package/src/storages/types.ts +3 -4
- package/src/sync/polling/updaters/splitChangesUpdater.ts +4 -4
- package/src/sync/streaming/parseUtils.ts +0 -1
- package/src/sync/streaming/pushManager.ts +3 -4
- package/src/sync/submitters/types.ts +3 -4
- package/src/types.ts +1 -9
- package/src/utils/LRUCache/index.ts +2 -3
- package/src/utils/constants/browser.ts +0 -4
- package/src/utils/lang/index.ts +6 -7
- package/src/utils/lang/objectAssign.ts +13 -92
- package/src/utils/lang/sets.ts +10 -122
- package/src/utils/settingsValidation/index.ts +0 -10
- package/src/utils/settingsValidation/logger/builtinLogger.ts +1 -2
- package/src/utils/settingsValidation/types.ts +0 -2
- package/types/logger/index.d.ts +1 -2
- package/types/sdkClient/clientCS.d.ts +2 -3
- package/types/sdkFactory/types.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -2
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -2
- package/types/storages/KeyBuilderCS.d.ts +0 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -2
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -2
- package/types/storages/inMemory/UniqueKeysCacheInMemory.d.ts +2 -3
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +1 -2
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +1 -2
- package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -2
- package/types/storages/types.d.ts +3 -4
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -2
- package/types/sync/submitters/types.d.ts +3 -4
- package/types/types.d.ts +1 -9
- package/types/utils/LRUCache/index.d.ts +1 -2
- package/types/utils/constants/browser.d.ts +0 -2
- package/types/utils/lang/objectAssign.d.ts +3 -0
- package/types/utils/lang/sets.d.ts +2 -61
- package/types/utils/settingsValidation/index.d.ts +0 -1
- package/types/utils/settingsValidation/types.d.ts +0 -2
- package/cjs/integrations/browser.js +0 -31
- package/cjs/integrations/ga/GaToSplit.js +0 -257
- package/cjs/integrations/ga/GoogleAnalyticsToSplit.js +0 -14
- package/cjs/integrations/ga/SplitToGa.js +0 -123
- package/cjs/integrations/ga/SplitToGoogleAnalytics.js +0 -14
- package/cjs/integrations/ga/types.js +0 -2
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +0 -75
- package/cjs/utils/lang/maps.js +0 -96
- package/esm/integrations/browser.js +0 -27
- package/esm/integrations/ga/GaToSplit.js +0 -250
- package/esm/integrations/ga/GoogleAnalyticsToSplit.js +0 -10
- package/esm/integrations/ga/SplitToGa.js +0 -120
- package/esm/integrations/ga/SplitToGoogleAnalytics.js +0 -10
- package/esm/integrations/ga/types.js +0 -1
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +0 -71
- package/esm/utils/lang/maps.js +0 -92
- package/src/integrations/browser.ts +0 -35
- package/src/integrations/ga/GaToSplit.ts +0 -299
- package/src/integrations/ga/GoogleAnalyticsToSplit.ts +0 -14
- package/src/integrations/ga/SplitToGa.ts +0 -135
- package/src/integrations/ga/SplitToGoogleAnalytics.ts +0 -14
- package/src/integrations/ga/autoRequire.js +0 -33
- package/src/integrations/ga/types.ts +0 -153
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +0 -96
- package/src/utils/lang/maps.ts +0 -108
|
@@ -1,12 +1,12 @@
|
|
|
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';
|
|
4
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Converts `uniqueKeys` data from cache into request payload for SS.
|
|
8
8
|
*/
|
|
9
|
-
export function fromUniqueKeysCollector(uniqueKeys: { [featureName: string]:
|
|
9
|
+
export function fromUniqueKeysCollector(uniqueKeys: { [featureName: string]: Set<string> }): UniqueKeysPayloadSs {
|
|
10
10
|
const payload = [];
|
|
11
11
|
const featureNames = Object.keys(uniqueKeys);
|
|
12
12
|
for (let i = 0; i < featureNames.length; i++) {
|
|
@@ -27,7 +27,7 @@ export class UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
|
27
27
|
protected onFullQueue?: () => void;
|
|
28
28
|
private readonly maxStorage: number;
|
|
29
29
|
private uniqueTrackerSize = 0;
|
|
30
|
-
protected uniqueKeysTracker: { [featureName: string]:
|
|
30
|
+
protected uniqueKeysTracker: { [featureName: string]: Set<string> } = {};
|
|
31
31
|
|
|
32
32
|
constructor(uniqueKeysQueueSize = DEFAULT_CACHE_SIZE) {
|
|
33
33
|
this.maxStorage = uniqueKeysQueueSize;
|
|
@@ -41,7 +41,7 @@ export class UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
|
41
41
|
* Store unique keys per feature.
|
|
42
42
|
*/
|
|
43
43
|
track(userKey: string, featureName: string) {
|
|
44
|
-
if (!this.uniqueKeysTracker[featureName]) this.uniqueKeysTracker[featureName] = new
|
|
44
|
+
if (!this.uniqueKeysTracker[featureName]) this.uniqueKeysTracker[featureName] = new Set();
|
|
45
45
|
const tracker = this.uniqueKeysTracker[featureName];
|
|
46
46
|
if (!tracker.has(userKey)) {
|
|
47
47
|
tracker.add(userKey);
|
|
@@ -1,14 +1,14 @@
|
|
|
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';
|
|
4
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
5
5
|
|
|
6
6
|
export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
|
|
7
7
|
|
|
8
8
|
private onFullQueue?: () => void;
|
|
9
9
|
private readonly maxStorage: number;
|
|
10
10
|
private uniqueTrackerSize = 0;
|
|
11
|
-
private uniqueKeysTracker: { [userKey: string]:
|
|
11
|
+
private uniqueKeysTracker: { [userKey: string]: Set<string> } = {};
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
@@ -28,7 +28,7 @@ export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
|
|
|
28
28
|
*/
|
|
29
29
|
track(userKey: string, featureName: string) {
|
|
30
30
|
|
|
31
|
-
if (!this.uniqueKeysTracker[userKey]) this.uniqueKeysTracker[userKey] = new
|
|
31
|
+
if (!this.uniqueKeysTracker[userKey]) this.uniqueKeysTracker[userKey] = new Set();
|
|
32
32
|
const tracker = this.uniqueKeysTracker[userKey];
|
|
33
33
|
if (!tracker.has(featureName)) {
|
|
34
34
|
tracker.add(featureName);
|
|
@@ -66,7 +66,7 @@ export class UniqueKeysCacheInMemoryCS implements IUniqueKeysCacheBase {
|
|
|
66
66
|
/**
|
|
67
67
|
* Converts `uniqueKeys` data from cache into request payload.
|
|
68
68
|
*/
|
|
69
|
-
private fromUniqueKeysCollector(uniqueKeys: { [userKey: string]:
|
|
69
|
+
private fromUniqueKeysCollector(uniqueKeys: { [userKey: string]: Set<string> }): UniqueKeysPayloadCs {
|
|
70
70
|
const payload = [];
|
|
71
71
|
const userKeys = Object.keys(uniqueKeys);
|
|
72
72
|
for (let k = 0; k < userKeys.length; k++) {
|
|
@@ -1,9 +1,9 @@
|
|
|
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';
|
|
6
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
7
7
|
|
|
8
8
|
const LOG_PREFIX = 'storage:redis-adapter: ';
|
|
9
9
|
|
|
@@ -37,7 +37,7 @@ export class RedisAdapter extends ioredis {
|
|
|
37
37
|
private readonly log: ILogger;
|
|
38
38
|
private _options: object;
|
|
39
39
|
private _notReadyCommandsQueue?: IRedisCommand[];
|
|
40
|
-
private _runningCommands:
|
|
40
|
+
private _runningCommands: Set<Promise<any>>;
|
|
41
41
|
|
|
42
42
|
constructor(log: ILogger, storageSettings: Record<string, any> = {}) {
|
|
43
43
|
const options = RedisAdapter._defineOptions(storageSettings);
|
|
@@ -47,7 +47,7 @@ export class RedisAdapter extends ioredis {
|
|
|
47
47
|
this.log = log;
|
|
48
48
|
this._options = options;
|
|
49
49
|
this._notReadyCommandsQueue = [];
|
|
50
|
-
this._runningCommands = new
|
|
50
|
+
this._runningCommands = new Set();
|
|
51
51
|
this._listenToEvents();
|
|
52
52
|
this._setTimeoutWrappers();
|
|
53
53
|
this._setDisconnectWrapper();
|
|
@@ -4,7 +4,7 @@ import { ILogger } from '../../logger/types';
|
|
|
4
4
|
import { LOG_PREFIX } from './constants';
|
|
5
5
|
import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
|
|
6
6
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
7
|
-
import {
|
|
7
|
+
import { returnDifference } from '../../utils/lang/sets';
|
|
8
8
|
import type { RedisAdapter } from './RedisAdapter';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -215,14 +215,14 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
215
215
|
* The returned promise is resolved with the list of feature flag names per flag set,
|
|
216
216
|
* or rejected if the pipelined redis operation fails (e.g., timeout).
|
|
217
217
|
*/
|
|
218
|
-
getNamesByFlagSets(flagSets: string[]): Promise<
|
|
218
|
+
getNamesByFlagSets(flagSets: string[]): Promise<Set<string>[]> {
|
|
219
219
|
return this.redis.pipeline(flagSets.map(flagSet => ['smembers', this.keys.buildFlagSetKey(flagSet)])).exec()
|
|
220
220
|
.then((results) => results.map(([e, value], index) => {
|
|
221
221
|
if (e === null) return value;
|
|
222
222
|
|
|
223
223
|
this.log.error(LOG_PREFIX + `Could not read result from get members of flag set ${flagSets[index]} due to an error: ${e}`);
|
|
224
224
|
}))
|
|
225
|
-
.then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new
|
|
225
|
+
.then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new Set(namesByFlagSet)));
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
/**
|
|
@@ -6,7 +6,6 @@ import { findLatencyIndex } from '../findLatencyIndex';
|
|
|
6
6
|
import { getTelemetryConfigStats } from '../../sync/submitters/telemetrySubmitter';
|
|
7
7
|
import { CONSUMER_MODE, STORAGE_REDIS } from '../../utils/constants';
|
|
8
8
|
import { isNaNNumber, isString } 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
|
import type { RedisAdapter } from './RedisAdapter';
|
|
@@ -46,7 +45,7 @@ export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
|
|
|
46
45
|
popLatencies(): Promise<MultiMethodLatencies> {
|
|
47
46
|
return this.redis.hgetall(this.keys.latencyPrefix).then(latencies => {
|
|
48
47
|
|
|
49
|
-
const result: MultiMethodLatencies = new
|
|
48
|
+
const result: MultiMethodLatencies = new Map();
|
|
50
49
|
|
|
51
50
|
Object.keys(latencies).forEach(field => {
|
|
52
51
|
|
|
@@ -86,7 +85,7 @@ export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
|
|
|
86
85
|
popExceptions(): Promise<MultiMethodExceptions> {
|
|
87
86
|
return this.redis.hgetall(this.keys.exceptionPrefix).then(exceptions => {
|
|
88
87
|
|
|
89
|
-
const result: MultiMethodExceptions = new
|
|
88
|
+
const result: MultiMethodExceptions = new Map();
|
|
90
89
|
|
|
91
90
|
Object.keys(exceptions).forEach(field => {
|
|
92
91
|
|
|
@@ -119,7 +118,7 @@ export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
|
|
|
119
118
|
popConfigs(): Promise<MultiConfigs> {
|
|
120
119
|
return this.redis.hgetall(this.keys.initPrefix).then(configs => {
|
|
121
120
|
|
|
122
|
-
const result: MultiConfigs = new
|
|
121
|
+
const result: MultiConfigs = new Map();
|
|
123
122
|
|
|
124
123
|
Object.keys(configs).forEach(field => {
|
|
125
124
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { 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, TTL_REFRESH } from './constants';
|
|
5
4
|
import { LOG_PREFIX } from './constants';
|
|
6
5
|
import { ILogger } from '../../logger/types';
|
|
7
6
|
import { UniqueKeysItemSs } from '../../sync/submitters/types';
|
|
8
7
|
import type { RedisAdapter } from './RedisAdapter';
|
|
8
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
9
9
|
|
|
10
10
|
export class UniqueKeysCacheInRedis extends UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
11
11
|
|
|
@@ -5,7 +5,6 @@ import { KeyBuilderSS } from '../KeyBuilderSS';
|
|
|
5
5
|
import { IPluggableStorageWrapper, ISegmentsCacheAsync } from '../types';
|
|
6
6
|
import { ILogger } from '../../logger/types';
|
|
7
7
|
import { LOG_PREFIX } from './constants';
|
|
8
|
-
import { _Set } from '../../utils/lang/sets';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* ISegmentsCacheAsync implementation for pluggable storages.
|
|
@@ -5,7 +5,7 @@ import { ILogger } from '../../logger/types';
|
|
|
5
5
|
import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
|
|
6
6
|
import { LOG_PREFIX } from './constants';
|
|
7
7
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
8
|
-
import {
|
|
8
|
+
import { returnDifference } from '../../utils/lang/sets';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* ISplitsCacheAsync implementation for pluggable storages.
|
|
@@ -181,11 +181,11 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
181
181
|
* The returned promise is resolved with the list of feature flag names per flag set.
|
|
182
182
|
* It never rejects (If there is a wrapper error for some flag set, an empty set is returned for it).
|
|
183
183
|
*/
|
|
184
|
-
getNamesByFlagSets(flagSets: string[]): Promise<
|
|
184
|
+
getNamesByFlagSets(flagSets: string[]): Promise<Set<string>[]> {
|
|
185
185
|
return Promise.all(flagSets.map(flagSet => {
|
|
186
186
|
const flagSetKey = this.keys.buildFlagSetKey(flagSet);
|
|
187
187
|
return this.wrapper.getItems(flagSetKey).catch(() => []);
|
|
188
|
-
})).then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new
|
|
188
|
+
})).then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new Set(namesByFlagSet)));
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/**
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
156
|
+
new Map();
|
|
158
157
|
});
|
|
159
158
|
}
|
|
160
159
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
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';
|
|
7
6
|
import { UniqueKeysItemSs } from '../../sync/submitters/types';
|
|
7
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
8
8
|
|
|
9
9
|
export class UniqueKeysCachePluggable extends UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IPluggableStorageWrapper } from '../types';
|
|
2
2
|
import { startsWith, toNumber } from '../../utils/lang';
|
|
3
|
-
import {
|
|
3
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates a IPluggableStorageWrapper implementation that stores items in memory.
|
|
@@ -9,9 +9,9 @@ import { ISet, setToArray, _Set } from '../../utils/lang/sets';
|
|
|
9
9
|
*
|
|
10
10
|
* @param connDelay delay in millis for `connect` resolve. If not provided, `connect` resolves immediately.
|
|
11
11
|
*/
|
|
12
|
-
export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWrapper & { _cache: Record<string, string | string[] |
|
|
12
|
+
export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWrapper & { _cache: Record<string, string | string[] | Set<string>>, _setConnDelay(connDelay: number): void } {
|
|
13
13
|
|
|
14
|
-
let _cache: Record<string, string | string[] |
|
|
14
|
+
let _cache: Record<string, string | string[] | Set<string>> = {};
|
|
15
15
|
let _connDelay = connDelay;
|
|
16
16
|
|
|
17
17
|
return {
|
|
@@ -84,22 +84,22 @@ export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWra
|
|
|
84
84
|
itemContains(key: string, item: string) {
|
|
85
85
|
const set = _cache[key];
|
|
86
86
|
if (!set) return Promise.resolve(false);
|
|
87
|
-
if (set instanceof
|
|
87
|
+
if (set instanceof Set) return Promise.resolve(set.has(item));
|
|
88
88
|
return Promise.reject('key is not a set');
|
|
89
89
|
},
|
|
90
90
|
addItems(key: string, items: string[]) {
|
|
91
|
-
if (!(key in _cache)) _cache[key] = new
|
|
91
|
+
if (!(key in _cache)) _cache[key] = new Set();
|
|
92
92
|
const set = _cache[key];
|
|
93
|
-
if (set instanceof
|
|
93
|
+
if (set instanceof Set) {
|
|
94
94
|
items.forEach(item => set.add(item));
|
|
95
95
|
return Promise.resolve();
|
|
96
96
|
}
|
|
97
97
|
return Promise.reject('key is not a set');
|
|
98
98
|
},
|
|
99
99
|
removeItems(key: string, items: string[]) {
|
|
100
|
-
if (!(key in _cache)) _cache[key] = new
|
|
100
|
+
if (!(key in _cache)) _cache[key] = new Set();
|
|
101
101
|
const set = _cache[key];
|
|
102
|
-
if (set instanceof
|
|
102
|
+
if (set instanceof Set) {
|
|
103
103
|
items.forEach(item => set.delete(item));
|
|
104
104
|
return Promise.resolve();
|
|
105
105
|
}
|
|
@@ -108,7 +108,7 @@ export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWra
|
|
|
108
108
|
getItems(key: string) {
|
|
109
109
|
const set = _cache[key];
|
|
110
110
|
if (!set) return Promise.resolve([]);
|
|
111
|
-
if (set instanceof
|
|
111
|
+
if (set instanceof Set) return Promise.resolve(setToArray(set));
|
|
112
112
|
return Promise.reject('key is not a set');
|
|
113
113
|
},
|
|
114
114
|
|
package/src/storages/types.ts
CHANGED
|
@@ -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.
|
|
@@ -211,7 +210,7 @@ export interface ISplitsCacheBase {
|
|
|
211
210
|
// should never reject or throw an exception. Instead return false by default, to avoid emitting SDK_READY_FROM_CACHE.
|
|
212
211
|
checkCache(): MaybeThenable<boolean>,
|
|
213
212
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): MaybeThenable<boolean>,
|
|
214
|
-
getNamesByFlagSets(flagSets: string[]): MaybeThenable<
|
|
213
|
+
getNamesByFlagSets(flagSets: string[]): MaybeThenable<Set<string>[]>
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
@@ -228,7 +227,7 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
228
227
|
clear(): void,
|
|
229
228
|
checkCache(): boolean,
|
|
230
229
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean,
|
|
231
|
-
getNamesByFlagSets(flagSets: string[]):
|
|
230
|
+
getNamesByFlagSets(flagSets: string[]): Set<string>[]
|
|
232
231
|
}
|
|
233
232
|
|
|
234
233
|
export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
@@ -245,7 +244,7 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
|
245
244
|
clear(): Promise<boolean | void>,
|
|
246
245
|
checkCache(): Promise<boolean>,
|
|
247
246
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean>,
|
|
248
|
-
getNamesByFlagSets(flagSets: string[]): Promise<
|
|
247
|
+
getNamesByFlagSets(flagSets: string[]): Promise<Set<string>[]>
|
|
249
248
|
}
|
|
250
249
|
|
|
251
250
|
/** Segments cache */
|
|
@@ -1,4 +1,3 @@
|
|
|
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';
|
|
@@ -9,6 +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';
|
|
11
10
|
import { IN_SEGMENT } from '../../../utils/constants';
|
|
11
|
+
import { setToArray } from '../../../utils/lang/sets';
|
|
12
12
|
|
|
13
13
|
type ISplitChangesUpdater = (noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }) => Promise<boolean>
|
|
14
14
|
|
|
@@ -27,8 +27,8 @@ function checkAllSegmentsExist(segments: ISegmentsCacheBase): Promise<boolean> {
|
|
|
27
27
|
* Collect segments from a raw split definition.
|
|
28
28
|
* Exported for testing purposes.
|
|
29
29
|
*/
|
|
30
|
-
export function parseSegments({ conditions }: ISplit):
|
|
31
|
-
let segments = new
|
|
30
|
+
export function parseSegments({ conditions }: ISplit): Set<string> {
|
|
31
|
+
let segments = new Set<string>();
|
|
32
32
|
|
|
33
33
|
for (let i = 0; i < conditions.length; i++) {
|
|
34
34
|
const matchers = conditions[i].matcherGroup.matchers;
|
|
@@ -74,7 +74,7 @@ function matchFilters(featureFlag: ISplit, filters: ISplitFiltersValidation) {
|
|
|
74
74
|
* Exported for testing purposes.
|
|
75
75
|
*/
|
|
76
76
|
export function computeSplitsMutation(entries: ISplit[], filters: ISplitFiltersValidation): ISplitMutations {
|
|
77
|
-
const segments = new
|
|
77
|
+
const segments = new Set<string>();
|
|
78
78
|
const computed = entries.reduce((accum, split) => {
|
|
79
79
|
if (split.status === 'ACTIVE' && matchFilters(split, filters)) {
|
|
80
80
|
accum.added.push([split.name, split]);
|
|
@@ -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:
|
|
256
|
+
let keyList: KeyList, added: Set<string>, removed: Set<string>;
|
|
258
257
|
try {
|
|
259
258
|
keyList = parseKeyList(parsedData.d!, parsedData.c!);
|
|
260
|
-
added = new
|
|
261
|
-
removed = new
|
|
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 =
|
|
90
|
+
export type MultiMethodLatencies = Map<string, MethodLatencies>
|
|
92
91
|
|
|
93
|
-
export type MultiMethodExceptions =
|
|
92
|
+
export type MultiMethodExceptions = Map<string, MethodExceptions>
|
|
94
93
|
|
|
95
|
-
export type MultiConfigs =
|
|
94
|
+
export type MultiConfigs = Map<string, TelemetryConfigStats>
|
|
96
95
|
|
|
97
96
|
/**
|
|
98
97
|
* Telemetry usage stats
|
package/src/types.ts
CHANGED
|
@@ -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
|
},
|
|
@@ -923,12 +922,6 @@ export namespace SplitIO {
|
|
|
923
922
|
* @property {SplitKey} key
|
|
924
923
|
*/
|
|
925
924
|
key: SplitKey,
|
|
926
|
-
/**
|
|
927
|
-
* Traffic type associated with the customer identifier. @see {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type}
|
|
928
|
-
* If no provided as a setting it will be required on the client.track() calls.
|
|
929
|
-
* @property {string} trafficType
|
|
930
|
-
*/
|
|
931
|
-
trafficType?: string,
|
|
932
925
|
/**
|
|
933
926
|
* Disable labels from being sent to Split backend. Labels may contain sensitive information.
|
|
934
927
|
* @property {boolean} labelsEnabled
|
|
@@ -1037,10 +1030,9 @@ export namespace SplitIO {
|
|
|
1037
1030
|
* Returns a shared client of the SDK, with the given key and optional traffic type.
|
|
1038
1031
|
* @function client
|
|
1039
1032
|
* @param {SplitKey} key The key for the new client instance.
|
|
1040
|
-
* @param {string=} trafficType The traffic type of the provided key.
|
|
1041
1033
|
* @returns {ICsClient} The client instance.
|
|
1042
1034
|
*/
|
|
1043
|
-
client(key: SplitKey
|
|
1035
|
+
client(key: SplitKey): ICsClient,
|
|
1044
1036
|
/**
|
|
1045
1037
|
* Returns a manager instance of the SDK to explore available information.
|
|
1046
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:
|
|
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
|
|
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
|
package/src/utils/lang/index.ts
CHANGED
|
@@ -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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
/**
|