@splitsoftware/splitio-commons 1.17.1-rc.3 → 1.17.1-rc.5
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 +28 -28
- package/LICENSE +1 -1
- package/README.md +4 -3
- package/cjs/consent/sdkUserConsent.js +4 -2
- package/cjs/evaluator/matchers/index.js +1 -3
- package/cjs/evaluator/matchers/matcherTypes.js +0 -1
- package/cjs/evaluator/matchers/segment.js +0 -6
- package/cjs/evaluator/matchersTransform/index.js +1 -4
- package/cjs/evaluator/matchersTransform/segment.js +1 -3
- package/cjs/logger/constants.js +2 -2
- package/cjs/logger/messages/info.js +1 -1
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/readiness/readinessManager.js +11 -12
- package/cjs/readiness/sdkReadinessManager.js +6 -5
- package/cjs/sdkClient/sdkClient.js +5 -5
- package/cjs/sdkClient/sdkClientMethod.js +1 -3
- package/cjs/sdkClient/sdkClientMethodCS.js +17 -15
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +17 -15
- package/cjs/sdkFactory/index.js +11 -38
- package/cjs/services/decorateHeaders.js +6 -1
- package/cjs/services/splitApi.js +5 -5
- package/cjs/services/splitHttpClient.js +5 -2
- package/cjs/storages/AbstractSegmentsCacheSync.js +12 -41
- package/cjs/storages/AbstractSplitsCacheAsync.js +7 -0
- package/cjs/storages/AbstractSplitsCacheSync.js +8 -2
- package/cjs/storages/KeyBuilderCS.js +5 -23
- package/cjs/storages/dataLoader.js +33 -65
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +52 -29
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +9 -1
- package/cjs/storages/inLocalStorage/index.js +3 -12
- package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -20
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +40 -9
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +8 -8
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +10 -7
- package/cjs/storages/inRedis/RedisAdapter.js +1 -1
- package/cjs/storages/inRedis/SegmentsCacheInRedis.js +2 -2
- package/cjs/storages/inRedis/index.js +11 -5
- package/cjs/storages/pluggable/SegmentsCachePluggable.js +2 -2
- package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
- package/cjs/storages/pluggable/index.js +32 -37
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +7 -2
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +8 -5
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/pollingManagerCS.js +1 -1
- package/cjs/sync/polling/pollingManagerSS.js +3 -3
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +21 -15
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +2 -2
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +11 -2
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +5 -3
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +48 -107
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +3 -3
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +9 -14
- package/cjs/sync/streaming/pushManager.js +67 -69
- package/cjs/sync/syncTask.js +2 -2
- package/cjs/trackers/eventTracker.js +9 -11
- package/cjs/trackers/impressionsTracker.js +13 -15
- package/cjs/trackers/uniqueKeysTracker.js +3 -5
- package/cjs/utils/constants/index.js +4 -5
- package/cjs/utils/settingsValidation/index.js +1 -2
- package/cjs/utils/settingsValidation/storage/storageCS.js +12 -1
- package/esm/consent/sdkUserConsent.js +4 -2
- package/esm/evaluator/matchers/index.js +1 -3
- package/esm/evaluator/matchers/matcherTypes.js +0 -1
- package/esm/evaluator/matchers/segment.js +0 -6
- package/esm/evaluator/matchersTransform/index.js +1 -4
- package/esm/evaluator/matchersTransform/segment.js +1 -3
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/info.js +1 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/readiness/readinessManager.js +11 -12
- package/esm/readiness/sdkReadinessManager.js +6 -5
- package/esm/sdkClient/sdkClient.js +5 -5
- package/esm/sdkClient/sdkClientMethod.js +1 -3
- package/esm/sdkClient/sdkClientMethodCS.js +15 -13
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +15 -13
- package/esm/sdkFactory/index.js +12 -39
- package/esm/services/decorateHeaders.js +4 -0
- package/esm/services/splitApi.js +6 -6
- package/esm/services/splitHttpClient.js +6 -3
- package/esm/storages/AbstractSegmentsCacheSync.js +12 -41
- package/esm/storages/AbstractSplitsCacheAsync.js +7 -0
- package/esm/storages/AbstractSplitsCacheSync.js +9 -3
- package/esm/storages/KeyBuilderCS.js +4 -21
- package/esm/storages/dataLoader.js +31 -62
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +52 -29
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +9 -1
- package/esm/storages/inLocalStorage/index.js +5 -14
- package/esm/storages/inMemory/InMemoryStorageCS.js +3 -20
- package/esm/storages/inMemory/MySegmentsCacheInMemory.js +40 -9
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/SplitsCacheInMemory.js +8 -8
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +10 -7
- package/esm/storages/inRedis/RedisAdapter.js +1 -1
- package/esm/storages/inRedis/SegmentsCacheInRedis.js +2 -2
- package/esm/storages/inRedis/index.js +11 -5
- package/esm/storages/pluggable/SegmentsCachePluggable.js +2 -2
- package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
- package/esm/storages/pluggable/index.js +32 -37
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +8 -3
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +8 -5
- package/esm/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/esm/sync/polling/pollingManagerCS.js +1 -1
- package/esm/sync/polling/pollingManagerSS.js +3 -3
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +21 -15
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +2 -2
- package/esm/sync/polling/updaters/splitChangesUpdater.js +12 -3
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEHandler/index.js +6 -4
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +49 -108
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +3 -3
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/parseUtils.js +8 -12
- package/esm/sync/streaming/pushManager.js +70 -72
- package/esm/sync/syncTask.js +2 -2
- package/esm/trackers/eventTracker.js +9 -11
- package/esm/trackers/impressionsTracker.js +13 -15
- package/esm/trackers/uniqueKeysTracker.js +3 -5
- package/esm/utils/constants/index.js +2 -3
- package/esm/utils/settingsValidation/index.js +1 -2
- package/esm/utils/settingsValidation/storage/storageCS.js +10 -0
- package/package.json +1 -1
- package/src/consent/sdkUserConsent.ts +3 -2
- package/src/dtos/types.ts +7 -21
- package/src/evaluator/matchers/index.ts +0 -2
- package/src/evaluator/matchers/matcherTypes.ts +0 -1
- package/src/evaluator/matchers/segment.ts +0 -7
- package/src/evaluator/matchersTransform/index.ts +1 -4
- package/src/evaluator/matchersTransform/segment.ts +3 -5
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/info.ts +1 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/readiness/readinessManager.ts +12 -16
- package/src/readiness/sdkReadinessManager.ts +7 -7
- package/src/readiness/types.ts +2 -3
- package/src/sdkClient/sdkClient.ts +5 -5
- package/src/sdkClient/sdkClientMethod.ts +1 -4
- package/src/sdkClient/sdkClientMethodCS.ts +14 -11
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +14 -11
- package/src/sdkFactory/index.ts +13 -42
- package/src/sdkFactory/types.ts +1 -5
- package/src/services/decorateHeaders.ts +5 -0
- package/src/services/splitApi.ts +7 -7
- package/src/services/splitHttpClient.ts +7 -4
- package/src/services/types.ts +2 -2
- package/src/storages/AbstractSegmentsCacheSync.ts +12 -53
- package/src/storages/AbstractSplitsCacheAsync.ts +8 -0
- package/src/storages/AbstractSplitsCacheSync.ts +11 -4
- package/src/storages/KeyBuilderCS.ts +5 -34
- package/src/storages/dataLoader.ts +33 -63
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +59 -29
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +10 -1
- package/src/storages/inLocalStorage/index.ts +6 -16
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -23
- package/src/storages/inMemory/MySegmentsCacheInMemory.ts +44 -10
- package/src/storages/inMemory/SegmentsCacheInMemory.ts +1 -1
- package/src/storages/inMemory/SplitsCacheInMemory.ts +8 -7
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +11 -7
- package/src/storages/inRedis/RedisAdapter.ts +1 -1
- package/src/storages/inRedis/SegmentsCacheInRedis.ts +2 -2
- package/src/storages/inRedis/index.ts +12 -6
- package/src/storages/pluggable/SegmentsCachePluggable.ts +2 -2
- package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
- package/src/storages/pluggable/index.ts +33 -38
- package/src/storages/types.ts +15 -15
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +7 -3
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +10 -8
- package/src/sync/polling/fetchers/segmentChangesFetcher.ts +1 -1
- package/src/sync/polling/fetchers/types.ts +2 -3
- package/src/sync/polling/pollingManagerCS.ts +4 -4
- package/src/sync/polling/pollingManagerSS.ts +2 -3
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +5 -4
- package/src/sync/polling/types.ts +6 -7
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +22 -19
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -2
- package/src/sync/polling/updaters/splitChangesUpdater.ts +12 -4
- package/src/sync/streaming/AuthClient/index.ts +1 -1
- package/src/sync/streaming/SSEClient/index.ts +6 -4
- package/src/sync/streaming/SSEHandler/index.ts +8 -5
- package/src/sync/streaming/SSEHandler/types.ts +15 -15
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +49 -116
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +4 -4
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/types.ts +2 -2
- package/src/sync/streaming/constants.ts +2 -2
- package/src/sync/streaming/parseUtils.ts +11 -19
- package/src/sync/streaming/pushManager.ts +72 -73
- package/src/sync/streaming/types.ts +10 -10
- package/src/sync/submitters/types.ts +5 -8
- package/src/sync/syncTask.ts +2 -2
- package/src/trackers/eventTracker.ts +7 -10
- package/src/trackers/impressionsTracker.ts +9 -12
- package/src/trackers/types.ts +0 -1
- package/src/trackers/uniqueKeysTracker.ts +4 -6
- package/src/types.ts +9 -16
- package/src/utils/constants/index.ts +2 -3
- package/src/utils/settingsValidation/index.ts +2 -3
- package/src/utils/settingsValidation/storage/storageCS.ts +13 -0
- package/src/utils/settingsValidation/types.ts +1 -1
- package/types/dtos/types.d.ts +7 -18
- package/types/evaluator/matchersTransform/segment.d.ts +2 -2
- package/types/logger/constants.d.ts +1 -1
- package/types/readiness/readinessManager.d.ts +2 -2
- package/types/readiness/sdkReadinessManager.d.ts +3 -2
- package/types/readiness/types.d.ts +2 -3
- package/types/sdkClient/sdkClientMethod.d.ts +1 -1
- package/types/sdkFactory/types.d.ts +1 -4
- package/types/services/decorateHeaders.d.ts +1 -0
- package/types/services/splitApi.d.ts +1 -1
- package/types/services/splitHttpClient.d.ts +1 -1
- package/types/services/types.d.ts +2 -2
- package/types/storages/AbstractSegmentsCacheSync.d.ts +11 -9
- package/types/storages/AbstractSplitsCacheAsync.d.ts +5 -0
- package/types/storages/AbstractSplitsCacheSync.d.ts +6 -1
- package/types/storages/KeyBuilderCS.d.ts +2 -9
- package/types/storages/dataLoader.d.ts +6 -17
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +14 -4
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +6 -0
- package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +9 -3
- package/types/storages/inMemory/SegmentsCacheInMemory.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -4
- package/types/storages/inRedis/SegmentsCacheInRedis.d.ts +1 -1
- package/types/storages/inRedis/index.d.ts +1 -1
- package/types/storages/pluggable/SegmentsCachePluggable.d.ts +1 -1
- package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
- package/types/storages/types.d.ts +11 -11
- package/types/sync/polling/fetchers/mySegmentsFetcher.d.ts +2 -2
- package/types/sync/polling/fetchers/types.d.ts +2 -2
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -2
- package/types/sync/polling/types.d.ts +4 -7
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +3 -4
- package/types/sync/streaming/SSEHandler/types.d.ts +14 -16
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -4
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +1 -2
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +2 -3
- package/types/sync/streaming/UpdateWorkers/types.d.ts +2 -2
- package/types/sync/streaming/constants.d.ts +2 -2
- package/types/sync/streaming/parseUtils.d.ts +5 -4
- package/types/sync/streaming/types.d.ts +8 -8
- package/types/sync/submitters/types.d.ts +4 -7
- package/types/trackers/eventTracker.d.ts +1 -1
- package/types/trackers/impressionsTracker.d.ts +1 -1
- package/types/trackers/types.d.ts +0 -1
- package/types/types.d.ts +9 -15
- package/types/utils/constants/index.d.ts +2 -3
- package/types/utils/settingsValidation/storage/storageCS.d.ts +5 -0
- package/types/utils/settingsValidation/types.d.ts +1 -1
- package/cjs/evaluator/matchers/large_segment.js +0 -16
- package/cjs/sdkClient/identity.js +0 -7
- package/esm/evaluator/matchers/large_segment.js +0 -12
- package/esm/sdkClient/identity.js +0 -3
- package/src/evaluator/matchers/large_segment.ts +0 -18
- package/src/sdkClient/identity.ts +0 -5
- package/types/evaluator/matchers/large_segment.d.ts +0 -5
- package/types/evaluator/matchers/sember_inlist.d.ts +0 -3
- package/types/evaluator/matchersTransform/set.d.ts +0 -5
- package/types/evaluator/matchersTransform/string.d.ts +0 -7
- package/types/sdkClient/identity.d.ts +0 -2
- package/types/storages/AbstractMySegmentsCacheSync.d.ts +0 -39
- package/types/storages/AbstractSplitsCache.d.ts +0 -46
- package/types/sync/streaming/mySegmentsV2utils.d.ts +0 -27
- package/types/sync/streaming/pushManagerCS_Spec1_3.d.ts +0 -9
- package/types/sync/streaming/pushManager_Spec1_3.d.ts +0 -9
- package/types/trackers/impressionObserver/utils.d.ts +0 -5
- package/types/utils/inputValidation/sdkKey.d.ts +0 -7
- package/types/utils/inputValidation/splitExistance.d.ts +0 -7
- package/types/utils/inputValidation/trafficTypeExistance.d.ts +0 -9
- package/types/utils/redis/RedisMock.d.ts +0 -4
- package/types/utils/settingsValidation/logger/globalLogLevel.d.ts +0 -8
- /package/types/utils/{semVer.d.ts → Semver.d.ts} +0 -0
package/src/dtos/types.ts
CHANGED
|
@@ -30,10 +30,6 @@ export interface IInSegmentMatcherData {
|
|
|
30
30
|
segmentName: string
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export interface IInLargeSegmentMatcherData {
|
|
34
|
-
largeSegmentName: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
export interface IDependencyMatcherData {
|
|
38
34
|
split: string,
|
|
39
35
|
treatments: string[]
|
|
@@ -47,7 +43,6 @@ interface ISplitMatcherBase {
|
|
|
47
43
|
attribute: string | null
|
|
48
44
|
}
|
|
49
45
|
userDefinedSegmentMatcherData?: null | IInSegmentMatcherData
|
|
50
|
-
userDefinedLargeSegmentMatcherData?: null | IInLargeSegmentMatcherData
|
|
51
46
|
whitelistMatcherData?: null | IWhitelistMatcherData
|
|
52
47
|
unaryNumericMatcherData?: null | IUnaryNumericMatcherData
|
|
53
48
|
betweenMatcherData?: null | IBetweenMatcherData
|
|
@@ -66,11 +61,6 @@ interface IInSegmentMatcher extends ISplitMatcherBase {
|
|
|
66
61
|
userDefinedSegmentMatcherData: IInSegmentMatcherData
|
|
67
62
|
}
|
|
68
63
|
|
|
69
|
-
interface IInLargeSegmentMatcher extends ISplitMatcherBase {
|
|
70
|
-
matcherType: 'IN_LARGE_SEGMENT',
|
|
71
|
-
userDefinedLargeSegmentMatcherData: IInLargeSegmentMatcherData
|
|
72
|
-
}
|
|
73
|
-
|
|
74
64
|
interface IWhitelistMatcher extends ISplitMatcherBase {
|
|
75
65
|
matcherType: 'WHITELIST',
|
|
76
66
|
whitelistMatcherData: IWhitelistMatcherData
|
|
@@ -175,8 +165,7 @@ interface IInListSemverMatcher extends ISplitMatcherBase {
|
|
|
175
165
|
export type ISplitMatcher = IAllKeysMatcher | IInSegmentMatcher | IWhitelistMatcher | IEqualToMatcher | IGreaterThanOrEqualToMatcher |
|
|
176
166
|
ILessThanOrEqualToMatcher | IBetweenMatcher | IEqualToSetMatcher | IContainsAnyOfSetMatcher | IContainsAllOfSetMatcher | IPartOfSetMatcher |
|
|
177
167
|
IStartsWithMatcher | IEndsWithMatcher | IContainsStringMatcher | IInSplitTreatmentMatcher | IEqualToBooleanMatcher | IMatchesStringMatcher |
|
|
178
|
-
IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher
|
|
179
|
-
IInLargeSegmentMatcher
|
|
168
|
+
IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher
|
|
180
169
|
|
|
181
170
|
/** Split object */
|
|
182
171
|
export interface ISplitPartition {
|
|
@@ -229,17 +218,14 @@ export interface ISegmentChangesResponse {
|
|
|
229
218
|
till: number
|
|
230
219
|
}
|
|
231
220
|
|
|
232
|
-
export interface
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
n: string
|
|
236
|
-
}[]
|
|
221
|
+
export interface IMySegmentsResponseItem {
|
|
222
|
+
id: string,
|
|
223
|
+
name: string
|
|
237
224
|
}
|
|
238
225
|
|
|
239
|
-
/** Interface of the parsed JSON response of `/
|
|
240
|
-
export interface
|
|
241
|
-
|
|
242
|
-
ls?: IMySegmentsResponse
|
|
226
|
+
/** Interface of the parsed JSON response of `/mySegments/{userKey}` */
|
|
227
|
+
export interface IMySegmentsResponse {
|
|
228
|
+
mySegments: IMySegmentsResponseItem[]
|
|
243
229
|
}
|
|
244
230
|
|
|
245
231
|
/** Metadata internal type for storages */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { allMatcherContext } from './all';
|
|
2
2
|
import { segmentMatcherContext } from './segment';
|
|
3
|
-
import { largeSegmentMatcherContext } from './large_segment';
|
|
4
3
|
import { whitelistMatcherContext } from './whitelist';
|
|
5
4
|
import { equalToMatcherContext } from './eq';
|
|
6
5
|
import { greaterThanEqualMatcherContext } from './gte';
|
|
@@ -49,7 +48,6 @@ const matchers = [
|
|
|
49
48
|
lessThanEqualToSemverMatcherContext, // LESS_THAN_OR_EQUAL_TO_SEMVER: 20
|
|
50
49
|
betweenSemverMatcherContext, // BETWEEN_SEMVER: 21
|
|
51
50
|
inListSemverMatcherContext, // IN_LIST_SEMVER: 22
|
|
52
|
-
largeSegmentMatcherContext, // IN_LARGE_SEGMENT: 23
|
|
53
51
|
];
|
|
54
52
|
|
|
55
53
|
/**
|
|
@@ -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
|
}
|
|
@@ -4,7 +4,7 @@ import { segmentTransform } from './segment';
|
|
|
4
4
|
import { whitelistTransform } from './whitelist';
|
|
5
5
|
import { numericTransform } from './unaryNumeric';
|
|
6
6
|
import { zeroSinceHH, zeroSinceSS } from '../convertions';
|
|
7
|
-
import { IBetweenMatcherData,
|
|
7
|
+
import { IBetweenMatcherData, IInSegmentMatcherData, ISplitMatcher, IUnaryNumericMatcherData } from '../../dtos/types';
|
|
8
8
|
import { IMatcherDto } from '../types';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -18,7 +18,6 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
|
|
|
18
18
|
negate,
|
|
19
19
|
keySelector,
|
|
20
20
|
userDefinedSegmentMatcherData,
|
|
21
|
-
userDefinedLargeSegmentMatcherData,
|
|
22
21
|
whitelistMatcherData, /* whitelistObject, provided by 'WHITELIST', 'IN_LIST_SEMVER', set and string matchers */
|
|
23
22
|
unaryNumericMatcherData,
|
|
24
23
|
betweenMatcherData,
|
|
@@ -36,8 +35,6 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
|
|
|
36
35
|
|
|
37
36
|
if (type === matcherTypes.IN_SEGMENT) {
|
|
38
37
|
value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData);
|
|
39
|
-
} else if (type === matcherTypes.IN_LARGE_SEGMENT) {
|
|
40
|
-
value = segmentTransform(userDefinedLargeSegmentMatcherData as IInLargeSegmentMatcherData);
|
|
41
38
|
} else if (type === matcherTypes.EQUAL_TO) {
|
|
42
39
|
value = numericTransform(unaryNumericMatcherData as IUnaryNumericMatcherData);
|
|
43
40
|
dataType = matcherDataTypes.NUMBER;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { IInSegmentMatcherData
|
|
1
|
+
import { IInSegmentMatcherData } from '../../dtos/types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Extract segment name as a plain string.
|
|
5
5
|
*/
|
|
6
|
-
export function segmentTransform(segment?: IInSegmentMatcherData
|
|
7
|
-
return segment ?
|
|
8
|
-
(segment as IInSegmentMatcherData).segmentName || (segment as IInLargeSegmentMatcherData).largeSegmentName :
|
|
9
|
-
undefined;
|
|
6
|
+
export function segmentTransform(segment?: IInSegmentMatcherData) {
|
|
7
|
+
return segment ? segment.segmentName : undefined;
|
|
10
8
|
}
|
package/src/logger/constants.ts
CHANGED
|
@@ -79,7 +79,7 @@ export const WARN_SPLITS_FILTER_IGNORED = 219;
|
|
|
79
79
|
export const WARN_SPLITS_FILTER_INVALID = 220;
|
|
80
80
|
export const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
81
81
|
export const WARN_SDK_KEY = 222;
|
|
82
|
-
export const
|
|
82
|
+
export const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
|
|
83
83
|
export const STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
84
84
|
export const WARN_INVALID_FLAGSET = 225;
|
|
85
85
|
export const WARN_LOWERCASE_FLAGSET = 226;
|
|
@@ -23,7 +23,7 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
23
23
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
24
24
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
25
25
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
26
|
-
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and
|
|
26
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and reseting timer.'],
|
|
27
27
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
28
28
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
29
29
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -32,7 +32,7 @@ export const codesWarn: [number, string][] = codesError.concat([
|
|
|
32
32
|
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
|
|
33
33
|
[c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
|
|
34
34
|
|
|
35
|
-
[c.
|
|
35
|
+
[c.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching MySegments due to an error processing %s notification: %s'],
|
|
36
36
|
[c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing SPLIT_UPDATE notification: %s'],
|
|
37
37
|
[c.WARN_INVALID_FLAGSET, '%s: you passed %s, flag set must adhere to the regular expressions %s. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.'],
|
|
38
38
|
[c.WARN_LOWERCASE_FLAGSET, '%s: flag set %s should be all lowercase - converting string to lowercase.'],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
|
-
import { IEventEmitter
|
|
2
|
+
import { IEventEmitter } from '../types';
|
|
3
3
|
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';
|
|
4
4
|
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ function splitsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISpli
|
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
13
|
-
// - `/
|
|
13
|
+
// - `/mySegments` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
14
14
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
15
15
|
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
|
|
16
16
|
splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, () => { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
@@ -33,11 +33,9 @@ function segmentsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISe
|
|
|
33
33
|
*/
|
|
34
34
|
export function readinessManagerFactory(
|
|
35
35
|
EventEmitter: new () => IEventEmitter,
|
|
36
|
-
|
|
36
|
+
readyTimeout = 0,
|
|
37
37
|
splits: ISplitsEventEmitter = splitsEventEmitterFactory(EventEmitter)): IReadinessManager {
|
|
38
38
|
|
|
39
|
-
const readyTimeout = settings.startup.readyTimeout;
|
|
40
|
-
|
|
41
39
|
const segments: ISegmentsEventEmitter = segmentsEventEmitterFactory(EventEmitter);
|
|
42
40
|
const gate: IReadinessEventEmitter = new EventEmitter();
|
|
43
41
|
|
|
@@ -55,15 +53,19 @@ export function readinessManagerFactory(
|
|
|
55
53
|
|
|
56
54
|
// emit SDK_READY_TIMED_OUT
|
|
57
55
|
let hasTimedout = false;
|
|
58
|
-
let readyTimeoutId: ReturnType<typeof setTimeout>;
|
|
59
56
|
|
|
60
|
-
function timeout() {
|
|
61
|
-
if (hasTimedout
|
|
57
|
+
function timeout() {
|
|
58
|
+
if (hasTimedout) return;
|
|
62
59
|
hasTimedout = true;
|
|
63
60
|
syncLastUpdate();
|
|
64
61
|
gate.emit(SDK_READY_TIMED_OUT, 'Split SDK emitted SDK_READY_TIMED_OUT event.');
|
|
65
62
|
}
|
|
66
63
|
|
|
64
|
+
let readyTimeoutId: ReturnType<typeof setTimeout>;
|
|
65
|
+
if (readyTimeout > 0) {
|
|
66
|
+
readyTimeoutId = setTimeout(timeout, readyTimeout);
|
|
67
|
+
}
|
|
68
|
+
|
|
67
69
|
// emit SDK_READY and SDK_UPDATE
|
|
68
70
|
let isReady = false;
|
|
69
71
|
splits.on(SDK_SPLITS_ARRIVED, checkIsReadyOrUpdate);
|
|
@@ -116,9 +118,9 @@ export function readinessManagerFactory(
|
|
|
116
118
|
segments,
|
|
117
119
|
gate,
|
|
118
120
|
|
|
119
|
-
shared() {
|
|
121
|
+
shared(readyTimeout = 0) {
|
|
120
122
|
refCount++;
|
|
121
|
-
return readinessManagerFactory(EventEmitter,
|
|
123
|
+
return readinessManagerFactory(EventEmitter, readyTimeout, splits);
|
|
122
124
|
},
|
|
123
125
|
|
|
124
126
|
// @TODO review/remove next methods when non-recoverable errors are reworked
|
|
@@ -128,12 +130,6 @@ export function readinessManagerFactory(
|
|
|
128
130
|
// tracking and evaluations, while keeping event listeners to emit SDK_READY_TIMED_OUT event
|
|
129
131
|
setDestroyed() { isDestroyed = true; },
|
|
130
132
|
|
|
131
|
-
init() {
|
|
132
|
-
if (readyTimeout > 0) {
|
|
133
|
-
readyTimeoutId = setTimeout(timeout, readyTimeout);
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
|
|
137
133
|
destroy() {
|
|
138
134
|
isDestroyed = true;
|
|
139
135
|
syncLastUpdate();
|
|
@@ -2,8 +2,9 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
2
2
|
import { promiseWrapper } from '../utils/promise/wrapper';
|
|
3
3
|
import { readinessManagerFactory } from './readinessManager';
|
|
4
4
|
import { ISdkReadinessManager } from './types';
|
|
5
|
-
import { IEventEmitter
|
|
5
|
+
import { IEventEmitter } from '../types';
|
|
6
6
|
import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants';
|
|
7
|
+
import { ILogger } from '../logger/types';
|
|
7
8
|
import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY, CLIENT_NO_LISTENER } from '../logger/constants';
|
|
8
9
|
|
|
9
10
|
const NEW_LISTENER_EVENT = 'newListener';
|
|
@@ -17,11 +18,10 @@ const REMOVE_LISTENER_EVENT = 'removeListener';
|
|
|
17
18
|
* @param readinessManager optional readinessManager to use. only used internally for `shared` method
|
|
18
19
|
*/
|
|
19
20
|
export function sdkReadinessManagerFactory(
|
|
21
|
+
log: ILogger,
|
|
20
22
|
EventEmitter: new () => IEventEmitter,
|
|
21
|
-
|
|
22
|
-
readinessManager = readinessManagerFactory(EventEmitter,
|
|
23
|
-
|
|
24
|
-
const log = settings.log;
|
|
23
|
+
readyTimeout = 0,
|
|
24
|
+
readinessManager = readinessManagerFactory(EventEmitter, readyTimeout)): ISdkReadinessManager {
|
|
25
25
|
|
|
26
26
|
/** Ready callback warning */
|
|
27
27
|
let internalReadyCbCount = 0;
|
|
@@ -72,8 +72,8 @@ export function sdkReadinessManagerFactory(
|
|
|
72
72
|
return {
|
|
73
73
|
readinessManager,
|
|
74
74
|
|
|
75
|
-
shared() {
|
|
76
|
-
return sdkReadinessManagerFactory(EventEmitter,
|
|
75
|
+
shared(readyTimeout = 0) {
|
|
76
|
+
return sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, readinessManager.shared(readyTimeout));
|
|
77
77
|
},
|
|
78
78
|
|
|
79
79
|
incInternalReadyCbCount() {
|
package/src/readiness/types.ts
CHANGED
|
@@ -59,10 +59,9 @@ export interface IReadinessManager {
|
|
|
59
59
|
timeout(): void,
|
|
60
60
|
setDestroyed(): void,
|
|
61
61
|
destroy(): void,
|
|
62
|
-
init(): void,
|
|
63
62
|
|
|
64
63
|
/** for client-side */
|
|
65
|
-
shared(): IReadinessManager,
|
|
64
|
+
shared(readyTimeout?: number): IReadinessManager,
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
/** SDK readiness manager */
|
|
@@ -78,5 +77,5 @@ export interface ISdkReadinessManager {
|
|
|
78
77
|
incInternalReadyCbCount(): void
|
|
79
78
|
|
|
80
79
|
/** for client-side */
|
|
81
|
-
shared(): ISdkReadinessManager
|
|
80
|
+
shared(readyTimeout?: number): ISdkReadinessManager
|
|
82
81
|
}
|
|
@@ -66,11 +66,11 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
|
|
|
66
66
|
syncManager && syncManager.stop();
|
|
67
67
|
|
|
68
68
|
return __flush().then(() => {
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
// Cleanup event listeners
|
|
70
|
+
signalListener && signalListener.stop();
|
|
71
|
+
|
|
72
|
+
// @TODO stop only if last client is destroyed
|
|
73
|
+
if (uniqueKeysTracker) uniqueKeysTracker.stop();
|
|
74
74
|
|
|
75
75
|
// Cleanup storage
|
|
76
76
|
return storage.destroy();
|
|
@@ -4,15 +4,12 @@ import { RETRIEVE_CLIENT_DEFAULT } from '../logger/constants';
|
|
|
4
4
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Factory of client method for server-side SDKs
|
|
7
|
+
* Factory of client method for server-side SDKs (ISDK and IAsyncSDK)
|
|
8
8
|
*/
|
|
9
9
|
export function sdkClientMethodFactory(params: ISdkFactoryContext): () => SplitIO.IClient | SplitIO.IAsyncClient {
|
|
10
10
|
const log = params.settings.log;
|
|
11
11
|
const clientInstance = sdkClientFactory(params);
|
|
12
12
|
|
|
13
|
-
// Only one client in server-side without bound key
|
|
14
|
-
params.clients[''] = clientInstance;
|
|
15
|
-
|
|
16
13
|
return function client() {
|
|
17
14
|
if (arguments.length > 0) {
|
|
18
15
|
throw new Error('Shared Client not supported by the storage mechanism. Create isolated instances instead.');
|
|
@@ -8,14 +8,18 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
8
8
|
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
|
|
9
9
|
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
10
10
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
function buildInstanceId(key: SplitIO.SplitKey) {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
return `${key.matchingKey ? key.matchingKey : key}-${key.bucketingKey ? key.bucketingKey : key}-`;
|
|
15
|
+
}
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* Factory of client method for the client-side API variant where TT is ignored.
|
|
15
19
|
* Therefore, clients don't have a bound TT for the track method.
|
|
16
20
|
*/
|
|
17
21
|
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
|
|
18
|
-
const {
|
|
22
|
+
const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, startup: { readyTimeout }, log } } = params;
|
|
19
23
|
|
|
20
24
|
const mainClientInstance = clientCSDecorator(
|
|
21
25
|
log,
|
|
@@ -27,7 +31,8 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
27
31
|
const defaultInstanceId = buildInstanceId(parsedDefaultKey);
|
|
28
32
|
|
|
29
33
|
// Cache instances created per factory.
|
|
30
|
-
|
|
34
|
+
const clientInstances: Record<string, SplitIO.ICsClient> = {};
|
|
35
|
+
clientInstances[defaultInstanceId] = mainClientInstance;
|
|
31
36
|
|
|
32
37
|
return function client(key?: SplitIO.SplitKey) {
|
|
33
38
|
if (key === undefined) {
|
|
@@ -43,10 +48,10 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
43
48
|
|
|
44
49
|
const instanceId = buildInstanceId(validKey);
|
|
45
50
|
|
|
46
|
-
if (!
|
|
51
|
+
if (!clientInstances[instanceId]) {
|
|
47
52
|
const matchingKey = getMatching(validKey);
|
|
48
53
|
|
|
49
|
-
const sharedSdkReadiness = sdkReadinessManager.shared();
|
|
54
|
+
const sharedSdkReadiness = sdkReadinessManager.shared(readyTimeout);
|
|
50
55
|
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
|
|
51
56
|
if (err) {
|
|
52
57
|
sharedSdkReadiness.readinessManager.timeout();
|
|
@@ -65,26 +70,24 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
65
70
|
|
|
66
71
|
// As shared clients reuse all the storage information, we don't need to check here if we
|
|
67
72
|
// will use offline or online mode. We should stick with the original decision.
|
|
68
|
-
|
|
73
|
+
clientInstances[instanceId] = clientCSDecorator(
|
|
69
74
|
log,
|
|
70
75
|
sdkClientFactory(objectAssign({}, params, {
|
|
71
76
|
sdkReadinessManager: sharedSdkReadiness,
|
|
72
77
|
storage: sharedStorage || storage,
|
|
73
78
|
syncManager: sharedSyncManager,
|
|
79
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
74
80
|
}), true) as SplitIO.IClient,
|
|
75
81
|
validKey
|
|
76
82
|
);
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
sharedSdkReadiness.readinessManager.init();
|
|
80
|
-
sharedSyncManager && sharedSyncManager.start();
|
|
81
|
-
});
|
|
84
|
+
sharedSyncManager && sharedSyncManager.start();
|
|
82
85
|
|
|
83
86
|
log.info(NEW_SHARED_CLIENT);
|
|
84
87
|
} else {
|
|
85
88
|
log.debug(RETRIEVE_CLIENT_EXISTING);
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
return
|
|
91
|
+
return clientInstances[instanceId];
|
|
89
92
|
};
|
|
90
93
|
}
|
|
@@ -9,7 +9,11 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
9
9
|
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
|
|
10
10
|
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
11
11
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
function buildInstanceId(key: SplitIO.SplitKey, trafficType?: string) {
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
return `${key.matchingKey ? key.matchingKey : key}-${key.bucketingKey ? key.bucketingKey : key}-${trafficType !== undefined ? trafficType : ''}`;
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
/**
|
|
15
19
|
* Factory of client method for the client-side (browser) variant of the Isomorphic JS SDK,
|
|
@@ -17,7 +21,7 @@ import { buildInstanceId } from './identity';
|
|
|
17
21
|
* (default client) or the client method (shared clients).
|
|
18
22
|
*/
|
|
19
23
|
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
|
|
20
|
-
const {
|
|
24
|
+
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, startup: { readyTimeout }, log } } = params;
|
|
21
25
|
|
|
22
26
|
const mainClientInstance = clientCSDecorator(
|
|
23
27
|
log,
|
|
@@ -30,7 +34,8 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
30
34
|
const defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
|
|
31
35
|
|
|
32
36
|
// Cache instances created per factory.
|
|
33
|
-
|
|
37
|
+
const clientInstances: Record<string, SplitIO.ICsClient> = {};
|
|
38
|
+
clientInstances[defaultInstanceId] = mainClientInstance;
|
|
34
39
|
|
|
35
40
|
return function client(key?: SplitIO.SplitKey, trafficType?: string) {
|
|
36
41
|
if (key === undefined) {
|
|
@@ -53,10 +58,10 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
53
58
|
}
|
|
54
59
|
const instanceId = buildInstanceId(validKey, validTrafficType);
|
|
55
60
|
|
|
56
|
-
if (!
|
|
61
|
+
if (!clientInstances[instanceId]) {
|
|
57
62
|
const matchingKey = getMatching(validKey);
|
|
58
63
|
|
|
59
|
-
const sharedSdkReadiness = sdkReadinessManager.shared();
|
|
64
|
+
const sharedSdkReadiness = sdkReadinessManager.shared(readyTimeout);
|
|
60
65
|
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
|
|
61
66
|
if (err) {
|
|
62
67
|
sharedSdkReadiness.readinessManager.timeout();
|
|
@@ -75,27 +80,25 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
75
80
|
|
|
76
81
|
// As shared clients reuse all the storage information, we don't need to check here if we
|
|
77
82
|
// will use offline or online mode. We should stick with the original decision.
|
|
78
|
-
|
|
83
|
+
clientInstances[instanceId] = clientCSDecorator(
|
|
79
84
|
log,
|
|
80
85
|
sdkClientFactory(objectAssign({}, params, {
|
|
81
86
|
sdkReadinessManager: sharedSdkReadiness,
|
|
82
87
|
storage: sharedStorage || storage,
|
|
83
88
|
syncManager: sharedSyncManager,
|
|
89
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
84
90
|
}), true) as SplitIO.IClient,
|
|
85
91
|
validKey,
|
|
86
92
|
validTrafficType
|
|
87
93
|
);
|
|
88
94
|
|
|
89
|
-
|
|
90
|
-
sharedSdkReadiness.readinessManager.init();
|
|
91
|
-
sharedSyncManager && sharedSyncManager.start();
|
|
92
|
-
});
|
|
95
|
+
sharedSyncManager && sharedSyncManager.start();
|
|
93
96
|
|
|
94
97
|
log.info(NEW_SHARED_CLIENT);
|
|
95
98
|
} else {
|
|
96
99
|
log.debug(RETRIEVE_CLIENT_EXISTING);
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
return
|
|
102
|
+
return clientInstances[instanceId];
|
|
100
103
|
};
|
|
101
104
|
}
|
package/src/sdkFactory/index.ts
CHANGED
|
@@ -3,11 +3,11 @@ import { sdkReadinessManagerFactory } from '../readiness/sdkReadinessManager';
|
|
|
3
3
|
import { impressionsTrackerFactory } from '../trackers/impressionsTracker';
|
|
4
4
|
import { eventTrackerFactory } from '../trackers/eventTracker';
|
|
5
5
|
import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
|
|
6
|
-
import {
|
|
6
|
+
import { SplitIO } from '../types';
|
|
7
7
|
import { validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
|
|
8
8
|
import { createLoggerAPI } from '../logger/sdkLogger';
|
|
9
9
|
import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
|
|
10
|
-
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED
|
|
10
|
+
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
11
11
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
12
12
|
import { strategyDebugFactory } from '../trackers/strategy/strategyDebug';
|
|
13
13
|
import { strategyOptimizedFactory } from '../trackers/strategy/strategyOptimized';
|
|
@@ -23,22 +23,16 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
23
23
|
const { settings, platform, storageFactory, splitApiFactory, extraProps,
|
|
24
24
|
syncManagerFactory, SignalListener, impressionsObserverFactory,
|
|
25
25
|
integrationsManagerFactory, sdkManagerFactory, sdkClientMethodFactory,
|
|
26
|
-
filterAdapterFactory
|
|
26
|
+
filterAdapterFactory } = params;
|
|
27
27
|
const { log, sync: { impressionsMode } } = settings;
|
|
28
28
|
|
|
29
29
|
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
|
|
30
30
|
// On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
|
|
31
31
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
const initCallbacks: (() => void)[] = [];
|
|
32
|
+
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
33
|
+
validateAndTrackApiKey(log, settings.core.authorizationKey);
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
if (isInit) cb();
|
|
38
|
-
else initCallbacks.push(cb);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const sdkReadinessManager = sdkReadinessManagerFactory(platform.EventEmitter, settings);
|
|
35
|
+
const sdkReadinessManager = sdkReadinessManagerFactory(log, platform.EventEmitter, settings.startup.readyTimeout);
|
|
42
36
|
const readiness = sdkReadinessManager.readinessManager;
|
|
43
37
|
|
|
44
38
|
const storage = storageFactory({
|
|
@@ -52,12 +46,9 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
52
46
|
readiness.splits.emit(SDK_SPLITS_ARRIVED);
|
|
53
47
|
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
54
48
|
},
|
|
55
|
-
onReadyFromCacheCb: () => {
|
|
56
|
-
readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
|
|
57
|
-
}
|
|
58
49
|
});
|
|
50
|
+
// @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
|
|
59
51
|
|
|
60
|
-
const clients: Record<string, IBasicClient> = {};
|
|
61
52
|
const telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
|
|
62
53
|
const integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings, storage, telemetryTracker });
|
|
63
54
|
|
|
@@ -76,13 +67,13 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
76
67
|
strategy = strategyDebugFactory(observer);
|
|
77
68
|
}
|
|
78
69
|
|
|
79
|
-
const impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, strategy,
|
|
80
|
-
const eventTracker = eventTrackerFactory(settings, storage.events,
|
|
70
|
+
const impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, strategy, integrationsManager, storage.telemetry);
|
|
71
|
+
const eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
|
|
81
72
|
|
|
82
73
|
// splitApi is used by SyncManager and Browser signal listener
|
|
83
74
|
const splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
|
|
84
75
|
|
|
85
|
-
const ctx: ISdkFactoryContext = {
|
|
76
|
+
const ctx: ISdkFactoryContext = { splitApi, eventTracker, impressionsTracker, telemetryTracker, uniqueKeysTracker, sdkReadinessManager, readiness, settings, storage, platform };
|
|
86
77
|
|
|
87
78
|
const syncManager = syncManagerFactory && syncManagerFactory(ctx as ISdkFactoryContextSync);
|
|
88
79
|
ctx.syncManager = syncManager;
|
|
@@ -94,24 +85,8 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
94
85
|
const clientMethod = sdkClientMethodFactory(ctx);
|
|
95
86
|
const managerInstance = sdkManagerFactory(settings, storage.splits, sdkReadinessManager);
|
|
96
87
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (isInit) return;
|
|
100
|
-
isInit = true;
|
|
101
|
-
|
|
102
|
-
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
103
|
-
validateAndTrackApiKey(log, settings.core.authorizationKey);
|
|
104
|
-
readiness.init();
|
|
105
|
-
storage.init && storage.init();
|
|
106
|
-
uniqueKeysTracker && uniqueKeysTracker.start();
|
|
107
|
-
syncManager && syncManager.start();
|
|
108
|
-
signalListener && signalListener.start();
|
|
109
|
-
|
|
110
|
-
initCallbacks.forEach((cb) => cb());
|
|
111
|
-
initCallbacks.length = 0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!isPure) init();
|
|
88
|
+
syncManager && syncManager.start();
|
|
89
|
+
signalListener && signalListener.start();
|
|
115
90
|
|
|
116
91
|
log.info(NEW_FACTORY);
|
|
117
92
|
|
|
@@ -130,9 +105,5 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
130
105
|
Logger: createLoggerAPI(log),
|
|
131
106
|
|
|
132
107
|
settings,
|
|
133
|
-
|
|
134
|
-
destroy() {
|
|
135
|
-
return Promise.all(Object.keys(clients).map(key => clients[key].destroy())).then(() => { });
|
|
136
|
-
}
|
|
137
|
-
}, extraProps && extraProps(ctx), isPure && { init });
|
|
108
|
+
}, extraProps && extraProps(ctx));
|
|
138
109
|
}
|
package/src/sdkFactory/types.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { IStorageAsync, IStorageSync, IStorageFactoryParams } from '../storages/
|
|
|
8
8
|
import { ISyncManager } from '../sync/types';
|
|
9
9
|
import { IImpressionObserver } from '../trackers/impressionObserver/types';
|
|
10
10
|
import { IImpressionsTracker, IEventTracker, ITelemetryTracker, IFilterAdapter, IUniqueKeysTracker } from '../trackers/types';
|
|
11
|
-
import { SplitIO, ISettings, IEventEmitter
|
|
11
|
+
import { SplitIO, ISettings, IEventEmitter } from '../types';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Environment related dependencies.
|
|
@@ -49,8 +49,6 @@ export interface ISdkFactoryContext {
|
|
|
49
49
|
signalListener?: ISignalListener
|
|
50
50
|
splitApi?: ISplitApi
|
|
51
51
|
syncManager?: ISyncManager,
|
|
52
|
-
clients: Record<string, IBasicClient>,
|
|
53
|
-
whenInit(cb: () => void): void
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
export interface ISdkFactoryContextSync extends ISdkFactoryContext {
|
|
@@ -69,8 +67,6 @@ export interface ISdkFactoryContextAsync extends ISdkFactoryContext {
|
|
|
69
67
|
* Object parameter with the modules required to create an SDK factory instance
|
|
70
68
|
*/
|
|
71
69
|
export interface ISdkFactoryParams {
|
|
72
|
-
// If true, the `sdkFactory` is pure (no side effects), and the SDK instance includes a `init` method to run initialization side effects
|
|
73
|
-
isPure?: boolean,
|
|
74
70
|
|
|
75
71
|
// The settings must be already validated
|
|
76
72
|
settings: ISettings,
|
|
@@ -31,3 +31,8 @@ export function decorateHeaders(settings: ISettings, headers: Record<string, str
|
|
|
31
31
|
}
|
|
32
32
|
return headers;
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
export function removeNonISO88591(input: string) {
|
|
36
|
+
// eslint-disable-next-line no-control-regex
|
|
37
|
+
return input.replace(/[^\x00-\xFF]/g, '');
|
|
38
|
+
}
|