@splitsoftware/splitio-commons 2.1.0 → 2.1.1-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 +3 -0
- package/cjs/logger/constants.js +4 -6
- package/cjs/logger/messages/debug.js +1 -3
- package/cjs/logger/messages/error.js +1 -1
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/sdkClient/client.js +29 -19
- package/cjs/sdkClient/clientAttributesDecoration.js +19 -25
- package/cjs/sdkClient/clientInputValidation.js +28 -26
- package/cjs/storages/AbstractSplitsCacheAsync.js +12 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +5 -7
- package/cjs/storages/KeyBuilder.js +0 -16
- package/cjs/storages/KeyBuilderCS.js +8 -2
- package/cjs/storages/dataLoader.js +1 -2
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +5 -2
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +24 -31
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +4 -21
- package/cjs/storages/pluggable/SplitsCachePluggable.js +2 -19
- package/cjs/storages/utils.js +1 -0
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +12 -13
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +9 -23
- package/cjs/sync/submitters/impressionsSubmitter.js +3 -2
- package/cjs/trackers/strategy/strategyOptimized.js +3 -0
- package/cjs/utils/inputValidation/eventProperties.js +12 -1
- package/cjs/utils/inputValidation/index.js +3 -1
- package/esm/logger/constants.js +1 -3
- package/esm/logger/messages/debug.js +1 -3
- package/esm/logger/messages/error.js +1 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/sdkClient/client.js +29 -19
- package/esm/sdkClient/clientAttributesDecoration.js +19 -25
- package/esm/sdkClient/clientInputValidation.js +29 -27
- package/esm/storages/AbstractSplitsCacheAsync.js +12 -1
- package/esm/storages/AbstractSplitsCacheSync.js +5 -7
- package/esm/storages/KeyBuilder.js +0 -16
- package/esm/storages/KeyBuilderCS.js +8 -2
- package/esm/storages/dataLoader.js +1 -2
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +5 -2
- package/esm/storages/inMemory/SplitsCacheInMemory.js +24 -31
- package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -21
- package/esm/storages/pluggable/SplitsCachePluggable.js +2 -19
- package/esm/storages/utils.js +1 -0
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +12 -13
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +10 -24
- package/esm/sync/submitters/impressionsSubmitter.js +3 -2
- package/esm/trackers/strategy/strategyOptimized.js +3 -0
- package/esm/utils/inputValidation/eventProperties.js +10 -0
- package/esm/utils/inputValidation/index.js +1 -0
- package/package.json +1 -1
- package/src/logger/constants.ts +1 -3
- package/src/logger/messages/debug.ts +1 -3
- package/src/logger/messages/error.ts +1 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/sdkClient/client.ts +31 -21
- package/src/sdkClient/clientAttributesDecoration.ts +20 -27
- package/src/sdkClient/clientInputValidation.ts +30 -27
- package/src/storages/AbstractSplitsCacheAsync.ts +15 -5
- package/src/storages/AbstractSplitsCacheSync.ts +9 -13
- package/src/storages/KeyBuilder.ts +0 -20
- package/src/storages/KeyBuilderCS.ts +10 -3
- package/src/storages/dataLoader.ts +1 -2
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +5 -2
- package/src/storages/inMemory/SplitsCacheInMemory.ts +22 -27
- package/src/storages/inRedis/SplitsCacheInRedis.ts +4 -21
- package/src/storages/pluggable/SplitsCachePluggable.ts +2 -19
- package/src/storages/types.ts +10 -16
- package/src/storages/utils.ts +1 -0
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +14 -15
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -2
- package/src/sync/polling/updaters/splitChangesUpdater.ts +12 -27
- package/src/sync/submitters/impressionsSubmitter.ts +3 -2
- package/src/sync/submitters/types.ts +23 -33
- package/src/trackers/strategy/strategyOptimized.ts +3 -0
- package/src/utils/inputValidation/eventProperties.ts +10 -0
- package/src/utils/inputValidation/index.ts +1 -0
- package/types/splitio.d.ts +100 -35
package/package.json
CHANGED
package/src/logger/constants.ts
CHANGED
|
@@ -20,9 +20,7 @@ export const RETRIEVE_CLIENT_EXISTING = 28;
|
|
|
20
20
|
export const RETRIEVE_MANAGER = 29;
|
|
21
21
|
export const SYNC_OFFLINE_DATA = 30;
|
|
22
22
|
export const SYNC_SPLITS_FETCH = 31;
|
|
23
|
-
export const
|
|
24
|
-
export const SYNC_SPLITS_REMOVED = 33;
|
|
25
|
-
export const SYNC_SPLITS_SEGMENTS = 34;
|
|
23
|
+
export const SYNC_SPLITS_UPDATE = 32;
|
|
26
24
|
export const STREAMING_NEW_MESSAGE = 35;
|
|
27
25
|
export const SYNC_TASK_START = 36;
|
|
28
26
|
export const SYNC_TASK_EXECUTE = 37;
|
|
@@ -21,9 +21,7 @@ export const codesDebug: [number, string][] = codesInfo.concat([
|
|
|
21
21
|
// synchronizer
|
|
22
22
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
|
|
23
23
|
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up feature flags update using since = %s'],
|
|
24
|
-
[c.
|
|
25
|
-
[c.SYNC_SPLITS_REMOVED, c.LOG_PREFIX_SYNC_SPLITS + 'Removed feature flags %s'],
|
|
26
|
-
[c.SYNC_SPLITS_SEGMENTS, c.LOG_PREFIX_SYNC_SPLITS + 'Segment names collected %s'],
|
|
24
|
+
[c.SYNC_SPLITS_UPDATE, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s. Removed feature flags %s. Segment names collected %s'],
|
|
27
25
|
[c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
|
|
28
26
|
[c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + ': Starting %s. Running each %s millis'],
|
|
29
27
|
[c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + ': Running %s'],
|
|
@@ -21,7 +21,7 @@ export const codesError: [number, string][] = [
|
|
|
21
21
|
// input validation
|
|
22
22
|
[c.ERROR_EVENT_TYPE_FORMAT, '%s: you passed "%s", event_type must adhere to the regular expression /^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$/g. This means an event_type must be alphanumeric, cannot be more than 80 characters long, and can only include a dash, underscore, period, or colon as separators of alphanumeric characters.'],
|
|
23
23
|
[c.ERROR_NOT_PLAIN_OBJECT, '%s: %s must be a plain object.'],
|
|
24
|
-
[c.ERROR_SIZE_EXCEEDED, '%s: the maximum size allowed for the properties is 32768 bytes, which was exceeded.
|
|
24
|
+
[c.ERROR_SIZE_EXCEEDED, '%s: the maximum size allowed for the properties is 32768 bytes, which was exceeded.'],
|
|
25
25
|
[c.ERROR_NOT_FINITE, '%s: value must be a finite number.'],
|
|
26
26
|
[c.ERROR_NULL, '%s: you passed a null or undefined %s. It must be a non-empty string.'],
|
|
27
27
|
[c.ERROR_TOO_LONG, '%s: %s too long. It must have 250 characters or less.'],
|
|
@@ -18,7 +18,7 @@ export const codesWarn: [number, string][] = codesError.concat([
|
|
|
18
18
|
[c.CLIENT_NO_LISTENER, 'No listeners for SDK Readiness detected. Incorrect control treatments could have been logged if you called getTreatment/s while the SDK was not yet ready.'],
|
|
19
19
|
// input validation
|
|
20
20
|
[c.WARN_SETTING_NULL, '%s: Property "%s" is of invalid type. Setting value to null.'],
|
|
21
|
-
[c.WARN_TRIMMING_PROPERTIES, '%s:
|
|
21
|
+
[c.WARN_TRIMMING_PROPERTIES, '%s: more than 300 properties were provided. Some of them will be trimmed when processed.'],
|
|
22
22
|
[c.WARN_CONVERTING, '%s: %s "%s" is not of type string, converting.'],
|
|
23
23
|
[c.WARN_TRIMMING, '%s: %s "%s" has extra whitespace, trimming.'],
|
|
24
24
|
[c.WARN_NOT_EXISTENT_SPLIT, '%s: feature flag "%s" does not exist in this environment. Please double check what feature flags exist in the Split user interface.'],
|
package/src/sdkClient/client.ts
CHANGED
|
@@ -23,6 +23,14 @@ function treatmentsNotReady(featureFlagNames: string[]) {
|
|
|
23
23
|
return evaluations;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function stringify(options?: SplitIO.EvaluationOptions) {
|
|
27
|
+
if (options && options.properties) {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.stringify(options.properties);
|
|
30
|
+
} catch { /* JSON.stringify should never throw with validated options, but handling just in case */ }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
/**
|
|
27
35
|
* Creator of base client with getTreatments and track methods.
|
|
28
36
|
*/
|
|
@@ -31,12 +39,12 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
31
39
|
const { log, mode } = settings;
|
|
32
40
|
const isAsync = isConsumerMode(mode);
|
|
33
41
|
|
|
34
|
-
function getTreatment(key: SplitIO.SplitKey, featureFlagName: string, attributes
|
|
42
|
+
function getTreatment(key: SplitIO.SplitKey, featureFlagName: string, attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions, withConfig = false, methodName = GET_TREATMENT) {
|
|
35
43
|
const stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENT_WITH_CONFIG : TREATMENT);
|
|
36
44
|
|
|
37
45
|
const wrapUp = (evaluationResult: IEvaluationResult) => {
|
|
38
46
|
const queue: ImpressionDecorated[] = [];
|
|
39
|
-
const treatment = processEvaluation(evaluationResult, featureFlagName, key,
|
|
47
|
+
const treatment = processEvaluation(evaluationResult, featureFlagName, key, stringify(options), withConfig, methodName, queue);
|
|
40
48
|
impressionsTracker.track(queue, attributes);
|
|
41
49
|
|
|
42
50
|
stopTelemetryTracker(queue[0] && queue[0].imp.label);
|
|
@@ -52,18 +60,19 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
52
60
|
return thenable(evaluation) ? evaluation.then((res) => wrapUp(res)) : wrapUp(evaluation);
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
function getTreatmentWithConfig(key: SplitIO.SplitKey, featureFlagName: string, attributes
|
|
56
|
-
return getTreatment(key, featureFlagName, attributes, true, GET_TREATMENT_WITH_CONFIG);
|
|
63
|
+
function getTreatmentWithConfig(key: SplitIO.SplitKey, featureFlagName: string, attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions) {
|
|
64
|
+
return getTreatment(key, featureFlagName, attributes, options, true, GET_TREATMENT_WITH_CONFIG);
|
|
57
65
|
}
|
|
58
66
|
|
|
59
|
-
function getTreatments(key: SplitIO.SplitKey, featureFlagNames: string[], attributes
|
|
67
|
+
function getTreatments(key: SplitIO.SplitKey, featureFlagNames: string[], attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions, withConfig = false, methodName = GET_TREATMENTS) {
|
|
60
68
|
const stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENTS_WITH_CONFIG : TREATMENTS);
|
|
61
69
|
|
|
62
70
|
const wrapUp = (evaluationResults: Record<string, IEvaluationResult>) => {
|
|
63
71
|
const queue: ImpressionDecorated[] = [];
|
|
64
|
-
const treatments:
|
|
72
|
+
const treatments: SplitIO.Treatments | SplitIO.TreatmentsWithConfig = {};
|
|
73
|
+
const properties = stringify(options);
|
|
65
74
|
Object.keys(evaluationResults).forEach(featureFlagName => {
|
|
66
|
-
treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key,
|
|
75
|
+
treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
|
|
67
76
|
});
|
|
68
77
|
impressionsTracker.track(queue, attributes);
|
|
69
78
|
|
|
@@ -80,19 +89,19 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
80
89
|
return thenable(evaluations) ? evaluations.then((res) => wrapUp(res)) : wrapUp(evaluations);
|
|
81
90
|
}
|
|
82
91
|
|
|
83
|
-
function getTreatmentsWithConfig(key: SplitIO.SplitKey, featureFlagNames: string[], attributes
|
|
84
|
-
return getTreatments(key, featureFlagNames, attributes, true, GET_TREATMENTS_WITH_CONFIG);
|
|
92
|
+
function getTreatmentsWithConfig(key: SplitIO.SplitKey, featureFlagNames: string[], attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions) {
|
|
93
|
+
return getTreatments(key, featureFlagNames, attributes, options, true, GET_TREATMENTS_WITH_CONFIG);
|
|
85
94
|
}
|
|
86
95
|
|
|
87
|
-
function getTreatmentsByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes
|
|
96
|
+
function getTreatmentsByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions, withConfig = false, method: Method = TREATMENTS_BY_FLAGSETS, methodName = GET_TREATMENTS_BY_FLAG_SETS) {
|
|
88
97
|
const stopTelemetryTracker = telemetryTracker.trackEval(method);
|
|
89
98
|
|
|
90
99
|
const wrapUp = (evaluationResults: Record<string, IEvaluationResult>) => {
|
|
91
100
|
const queue: ImpressionDecorated[] = [];
|
|
92
|
-
const treatments:
|
|
93
|
-
const
|
|
94
|
-
Object.keys(
|
|
95
|
-
treatments[featureFlagName] = processEvaluation(
|
|
101
|
+
const treatments: SplitIO.Treatments | SplitIO.TreatmentsWithConfig = {};
|
|
102
|
+
const properties = stringify(options);
|
|
103
|
+
Object.keys(evaluationResults).forEach(featureFlagName => {
|
|
104
|
+
treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
|
|
96
105
|
});
|
|
97
106
|
impressionsTracker.track(queue, attributes);
|
|
98
107
|
|
|
@@ -109,16 +118,16 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
109
118
|
return thenable(evaluations) ? evaluations.then((res) => wrapUp(res)) : wrapUp(evaluations);
|
|
110
119
|
}
|
|
111
120
|
|
|
112
|
-
function getTreatmentsWithConfigByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes
|
|
113
|
-
return getTreatmentsByFlagSets(key, flagSetNames, attributes, true, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS);
|
|
121
|
+
function getTreatmentsWithConfigByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions) {
|
|
122
|
+
return getTreatmentsByFlagSets(key, flagSetNames, attributes, options, true, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS);
|
|
114
123
|
}
|
|
115
124
|
|
|
116
|
-
function getTreatmentsByFlagSet(key: SplitIO.SplitKey, flagSetName: string, attributes
|
|
117
|
-
return getTreatmentsByFlagSets(key, [flagSetName], attributes, false, TREATMENTS_BY_FLAGSET, GET_TREATMENTS_BY_FLAG_SET);
|
|
125
|
+
function getTreatmentsByFlagSet(key: SplitIO.SplitKey, flagSetName: string, attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions) {
|
|
126
|
+
return getTreatmentsByFlagSets(key, [flagSetName], attributes, options, false, TREATMENTS_BY_FLAGSET, GET_TREATMENTS_BY_FLAG_SET);
|
|
118
127
|
}
|
|
119
128
|
|
|
120
|
-
function getTreatmentsWithConfigByFlagSet(key: SplitIO.SplitKey, flagSetName: string, attributes
|
|
121
|
-
return getTreatmentsByFlagSets(key, [flagSetName], attributes, true, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
|
|
129
|
+
function getTreatmentsWithConfigByFlagSet(key: SplitIO.SplitKey, flagSetName: string, attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions) {
|
|
130
|
+
return getTreatmentsByFlagSets(key, [flagSetName], attributes, options, true, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
// Internal function
|
|
@@ -126,7 +135,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
126
135
|
evaluation: IEvaluationResult,
|
|
127
136
|
featureFlagName: string,
|
|
128
137
|
key: SplitIO.SplitKey,
|
|
129
|
-
|
|
138
|
+
properties: string | undefined,
|
|
130
139
|
withConfig: boolean,
|
|
131
140
|
invokingMethodName: string,
|
|
132
141
|
queue: ImpressionDecorated[]
|
|
@@ -148,6 +157,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
148
157
|
bucketingKey,
|
|
149
158
|
label,
|
|
150
159
|
changeNumber: changeNumber as number,
|
|
160
|
+
properties
|
|
151
161
|
},
|
|
152
162
|
disabled: impressionsDisabled
|
|
153
163
|
});
|
|
@@ -20,50 +20,44 @@ export function clientAttributesDecoration<TClient extends SplitIO.IClient | Spl
|
|
|
20
20
|
const clientGetTreatmentsWithConfigByFlagSets = client.getTreatmentsWithConfigByFlagSets;
|
|
21
21
|
const clientGetTreatmentsByFlagSet = client.getTreatmentsByFlagSet;
|
|
22
22
|
const clientGetTreatmentsWithConfigByFlagSet = client.getTreatmentsWithConfigByFlagSet;
|
|
23
|
-
const clientTrack = client.track;
|
|
24
23
|
|
|
25
|
-
function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
|
|
26
|
-
return clientGetTreatment(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes));
|
|
24
|
+
function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
25
|
+
return clientGetTreatment(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes), maybeOptions);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
|
|
30
|
-
return clientGetTreatmentWithConfig(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes));
|
|
28
|
+
function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
29
|
+
return clientGetTreatmentWithConfig(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes), maybeOptions);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
34
|
-
return clientGetTreatments(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes));
|
|
32
|
+
function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
33
|
+
return clientGetTreatments(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes), maybeOptions);
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
38
|
-
return clientGetTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes));
|
|
36
|
+
function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
37
|
+
return clientGetTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes), maybeOptions);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
42
|
-
return clientGetTreatmentsByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes));
|
|
40
|
+
function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
41
|
+
return clientGetTreatmentsByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes), maybeOptions);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
46
|
-
return clientGetTreatmentsWithConfigByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes));
|
|
44
|
+
function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
45
|
+
return clientGetTreatmentsWithConfigByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes), maybeOptions);
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
|
|
50
|
-
return clientGetTreatmentsByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes));
|
|
48
|
+
function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
49
|
+
return clientGetTreatmentsByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes), maybeOptions);
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
|
|
54
|
-
return clientGetTreatmentsWithConfigByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes));
|
|
52
|
+
function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
53
|
+
return clientGetTreatmentsWithConfigByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes), maybeOptions);
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
function
|
|
58
|
-
return clientTrack(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function combineAttributes(maybeAttributes: SplitIO.Attributes | undefined): SplitIO.Attributes | undefined{
|
|
56
|
+
function combineAttributes(maybeAttributes: SplitIO.Attributes | undefined): SplitIO.Attributes | undefined {
|
|
62
57
|
const storedAttributes = attributeStorage.getAll();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return maybeAttributes;
|
|
58
|
+
return Object.keys(storedAttributes).length > 0 ?
|
|
59
|
+
objectAssign({}, storedAttributes, maybeAttributes) :
|
|
60
|
+
maybeAttributes;
|
|
67
61
|
}
|
|
68
62
|
|
|
69
63
|
return objectAssign(client, {
|
|
@@ -75,7 +69,6 @@ export function clientAttributesDecoration<TClient extends SplitIO.IClient | Spl
|
|
|
75
69
|
getTreatmentsWithConfigByFlagSets: getTreatmentsWithConfigByFlagSets,
|
|
76
70
|
getTreatmentsByFlagSet: getTreatmentsByFlagSet,
|
|
77
71
|
getTreatmentsWithConfigByFlagSet: getTreatmentsWithConfigByFlagSet,
|
|
78
|
-
track: track,
|
|
79
72
|
|
|
80
73
|
/**
|
|
81
74
|
* Add an attribute to client's in memory attributes storage
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
validateSplits,
|
|
10
10
|
validateTrafficType,
|
|
11
11
|
validateIfNotDestroyed,
|
|
12
|
-
validateIfOperational
|
|
12
|
+
validateIfOperational,
|
|
13
|
+
validateEvaluationOptions
|
|
13
14
|
} from '../utils/inputValidation';
|
|
14
15
|
import { startsWith } from '../utils/lang';
|
|
15
16
|
import { CONTROL, CONTROL_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG, TRACK_FN_LABEL } from '../utils/constants';
|
|
@@ -32,7 +33,7 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
32
33
|
/**
|
|
33
34
|
* Avoid repeating this validations code
|
|
34
35
|
*/
|
|
35
|
-
function validateEvaluationParams(maybeKey: SplitIO.SplitKey, maybeNameOrNames: string | string[], maybeAttributes
|
|
36
|
+
function validateEvaluationParams(methodName: string, maybeKey: SplitIO.SplitKey, maybeNameOrNames: string | string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
36
37
|
const key = validateKey(log, maybeKey, methodName);
|
|
37
38
|
|
|
38
39
|
const nameOrNames = methodName.indexOf('ByFlagSet') > -1 ?
|
|
@@ -43,6 +44,7 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
43
44
|
|
|
44
45
|
const attributes = validateAttributes(log, maybeAttributes, methodName);
|
|
45
46
|
const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, methodName);
|
|
47
|
+
const options = validateEvaluationOptions(log, maybeOptions, methodName);
|
|
46
48
|
|
|
47
49
|
validateIfOperational(log, readinessManager, methodName, nameOrNames);
|
|
48
50
|
|
|
@@ -52,7 +54,8 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
52
54
|
valid,
|
|
53
55
|
key,
|
|
54
56
|
nameOrNames,
|
|
55
|
-
attributes
|
|
57
|
+
attributes,
|
|
58
|
+
options
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
|
|
@@ -60,31 +63,31 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
60
63
|
return isAsync ? Promise.resolve(value) : value;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
|
|
64
|
-
const params = validateEvaluationParams(maybeKey, maybeFeatureFlagName, maybeAttributes,
|
|
66
|
+
function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
67
|
+
const params = validateEvaluationParams(GET_TREATMENT, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
|
|
65
68
|
|
|
66
69
|
if (params.valid) {
|
|
67
|
-
return client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined);
|
|
70
|
+
return client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
68
71
|
} else {
|
|
69
72
|
return wrapResult(CONTROL);
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
|
|
74
|
-
const params = validateEvaluationParams(maybeKey, maybeFeatureFlagName, maybeAttributes,
|
|
76
|
+
function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
77
|
+
const params = validateEvaluationParams(GET_TREATMENT_WITH_CONFIG, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
|
|
75
78
|
|
|
76
79
|
if (params.valid) {
|
|
77
|
-
return client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined);
|
|
80
|
+
return client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
78
81
|
} else {
|
|
79
82
|
return wrapResult(objectAssign({}, CONTROL_WITH_CONFIG));
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
84
|
-
const params = validateEvaluationParams(maybeKey, maybeFeatureFlagNames, maybeAttributes,
|
|
86
|
+
function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
87
|
+
const params = validateEvaluationParams(GET_TREATMENTS, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
|
|
85
88
|
|
|
86
89
|
if (params.valid) {
|
|
87
|
-
return client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
|
|
90
|
+
return client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
88
91
|
} else {
|
|
89
92
|
const res: SplitIO.Treatments = {};
|
|
90
93
|
if (params.nameOrNames) (params.nameOrNames as string[]).forEach((split: string) => res[split] = CONTROL);
|
|
@@ -93,11 +96,11 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
97
|
-
const params = validateEvaluationParams(maybeKey, maybeFeatureFlagNames, maybeAttributes,
|
|
99
|
+
function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
100
|
+
const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
|
|
98
101
|
|
|
99
102
|
if (params.valid) {
|
|
100
|
-
return client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
|
|
103
|
+
return client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
101
104
|
} else {
|
|
102
105
|
const res: SplitIO.TreatmentsWithConfig = {};
|
|
103
106
|
if (params.nameOrNames) (params.nameOrNames as string[]).forEach(split => res[split] = objectAssign({}, CONTROL_WITH_CONFIG));
|
|
@@ -106,41 +109,41 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
110
|
-
const params = validateEvaluationParams(maybeKey, maybeFlagSets, maybeAttributes,
|
|
112
|
+
function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
113
|
+
const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
|
|
111
114
|
|
|
112
115
|
if (params.valid) {
|
|
113
|
-
return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
|
|
116
|
+
return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
114
117
|
} else {
|
|
115
118
|
return wrapResult({});
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
120
|
-
const params = validateEvaluationParams(maybeKey, maybeFlagSets, maybeAttributes,
|
|
122
|
+
function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
123
|
+
const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
|
|
121
124
|
|
|
122
125
|
if (params.valid) {
|
|
123
|
-
return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
|
|
126
|
+
return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
124
127
|
} else {
|
|
125
128
|
return wrapResult({});
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
|
|
130
|
-
const params = validateEvaluationParams(maybeKey, [maybeFlagSet], maybeAttributes,
|
|
132
|
+
function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
133
|
+
const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
|
|
131
134
|
|
|
132
135
|
if (params.valid) {
|
|
133
|
-
return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined);
|
|
136
|
+
return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
134
137
|
} else {
|
|
135
138
|
return wrapResult({});
|
|
136
139
|
}
|
|
137
140
|
}
|
|
138
141
|
|
|
139
|
-
function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
|
|
140
|
-
const params = validateEvaluationParams(maybeKey, [maybeFlagSet], maybeAttributes,
|
|
142
|
+
function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
|
|
143
|
+
const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
|
|
141
144
|
|
|
142
145
|
if (params.valid) {
|
|
143
|
-
return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined);
|
|
146
|
+
return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
|
|
144
147
|
} else {
|
|
145
148
|
return wrapResult({});
|
|
146
149
|
}
|
|
@@ -8,12 +8,22 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
8
8
|
*/
|
|
9
9
|
export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
|
|
10
10
|
|
|
11
|
-
abstract addSplit(
|
|
12
|
-
abstract
|
|
13
|
-
abstract
|
|
11
|
+
protected abstract addSplit(split: ISplit): Promise<boolean>
|
|
12
|
+
protected abstract removeSplit(name: string): Promise<boolean>
|
|
13
|
+
protected abstract setChangeNumber(changeNumber: number): Promise<boolean | void>
|
|
14
|
+
|
|
15
|
+
update(toAdd: ISplit[], toRemove: ISplit[], changeNumber: number): Promise<boolean> {
|
|
16
|
+
return Promise.all([
|
|
17
|
+
this.setChangeNumber(changeNumber),
|
|
18
|
+
Promise.all(toAdd.map(addedFF => this.addSplit(addedFF))),
|
|
19
|
+
Promise.all(toRemove.map(removedFF => this.removeSplit(removedFF.name)))
|
|
20
|
+
]).then(([, added, removed]) => {
|
|
21
|
+
return added.some(result => result) || removed.some(result => result);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
14
25
|
abstract getSplit(name: string): Promise<ISplit | null>
|
|
15
26
|
abstract getSplits(names: string[]): Promise<Record<string, ISplit | null>>
|
|
16
|
-
abstract setChangeNumber(changeNumber: number): Promise<boolean | void>
|
|
17
27
|
abstract getChangeNumber(): Promise<number>
|
|
18
28
|
abstract getAll(): Promise<ISplit[]>
|
|
19
29
|
abstract getSplitNames(): Promise<string[]>
|
|
@@ -52,7 +62,7 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
|
|
|
52
62
|
newSplit.defaultTreatment = defaultTreatment;
|
|
53
63
|
newSplit.changeNumber = changeNumber;
|
|
54
64
|
|
|
55
|
-
return this.addSplit(
|
|
65
|
+
return this.addSplit(newSplit);
|
|
56
66
|
}
|
|
57
67
|
return false;
|
|
58
68
|
}).catch(() => false);
|
|
@@ -9,16 +9,14 @@ import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
|
|
|
9
9
|
*/
|
|
10
10
|
export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
11
11
|
|
|
12
|
-
abstract addSplit(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
removeSplits(names: string[]): boolean[] {
|
|
21
|
-
return names.map(name => this.removeSplit(name));
|
|
12
|
+
protected abstract addSplit(split: ISplit): boolean
|
|
13
|
+
protected abstract removeSplit(name: string): boolean
|
|
14
|
+
protected abstract setChangeNumber(changeNumber: number): boolean | void
|
|
15
|
+
|
|
16
|
+
update(toAdd: ISplit[], toRemove: ISplit[], changeNumber: number): boolean {
|
|
17
|
+
this.setChangeNumber(changeNumber);
|
|
18
|
+
const updated = toAdd.map(addedFF => this.addSplit(addedFF)).some(result => result);
|
|
19
|
+
return toRemove.map(removedFF => this.removeSplit(removedFF.name)).some(result => result) || updated;
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
abstract getSplit(name: string): ISplit | null
|
|
@@ -31,8 +29,6 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
|
31
29
|
return splits;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
abstract setChangeNumber(changeNumber: number): boolean | void
|
|
35
|
-
|
|
36
32
|
abstract getChangeNumber(): number
|
|
37
33
|
|
|
38
34
|
getAll(): ISplit[] {
|
|
@@ -71,7 +67,7 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
|
71
67
|
newSplit.defaultTreatment = defaultTreatment;
|
|
72
68
|
newSplit.changeNumber = changeNumber;
|
|
73
69
|
|
|
74
|
-
return this.addSplit(
|
|
70
|
+
return this.addSplit(newSplit);
|
|
75
71
|
}
|
|
76
72
|
return false;
|
|
77
73
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ISettings } from '../types';
|
|
2
|
-
import { startsWith } from '../utils/lang';
|
|
3
2
|
import { hash } from '../utils/murmur3/murmur3';
|
|
4
3
|
|
|
5
4
|
const everythingAtTheEnd = /[^.]+$/;
|
|
@@ -34,24 +33,10 @@ export class KeyBuilder {
|
|
|
34
33
|
return `${this.prefix}.splits.till`;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
// NOT USED
|
|
38
|
-
// buildSplitsReady() {
|
|
39
|
-
// return `${this.prefix}.splits.ready`;
|
|
40
|
-
// }
|
|
41
|
-
|
|
42
|
-
isSplitKey(key: string) {
|
|
43
|
-
return startsWith(key, `${this.prefix}.split.`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
36
|
buildSplitKeyPrefix() {
|
|
47
37
|
return `${this.prefix}.split.`;
|
|
48
38
|
}
|
|
49
39
|
|
|
50
|
-
// Only used by InLocalStorage.
|
|
51
|
-
buildSplitsWithSegmentCountKey() {
|
|
52
|
-
return `${this.prefix}.splits.usingSegments`;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
40
|
buildSegmentNameKey(segmentName: string) {
|
|
56
41
|
return `${this.prefix}.segment.${segmentName}`;
|
|
57
42
|
}
|
|
@@ -60,11 +45,6 @@ export class KeyBuilder {
|
|
|
60
45
|
return `${this.prefix}.segment.${segmentName}.till`;
|
|
61
46
|
}
|
|
62
47
|
|
|
63
|
-
// NOT USED
|
|
64
|
-
// buildSegmentsReady() {
|
|
65
|
-
// return `${this.prefix}.segments.ready`;
|
|
66
|
-
// }
|
|
67
|
-
|
|
68
48
|
extractKey(builtKey: string) {
|
|
69
49
|
const s = builtKey.match(everythingAtTheEnd);
|
|
70
50
|
|
|
@@ -28,8 +28,7 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
|
|
|
28
28
|
extractSegmentName(builtSegmentKeyName: string) {
|
|
29
29
|
const prefix = `${this.prefix}.${this.matchingKey}.segment.`;
|
|
30
30
|
|
|
31
|
-
if (startsWith(builtSegmentKeyName, prefix))
|
|
32
|
-
return builtSegmentKeyName.substr(prefix.length);
|
|
31
|
+
if (startsWith(builtSegmentKeyName, prefix)) return builtSegmentKeyName.slice(prefix.length);
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
buildLastUpdatedKey() {
|
|
@@ -43,6 +42,14 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
|
|
|
43
42
|
buildTillKey() {
|
|
44
43
|
return `${this.prefix}.${this.matchingKey}.segments.till`;
|
|
45
44
|
}
|
|
45
|
+
|
|
46
|
+
isSplitKey(key: string) {
|
|
47
|
+
return startsWith(key, `${this.prefix}.split.`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
buildSplitsWithSegmentCountKey() {
|
|
51
|
+
return `${this.prefix}.splits.usingSegments`;
|
|
52
|
+
}
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string): MySegmentsKeyBuilder {
|
|
@@ -54,7 +61,7 @@ export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string):
|
|
|
54
61
|
extractSegmentName(builtSegmentKeyName: string) {
|
|
55
62
|
const p = `${prefix}.${matchingKey}.largeSegment.`;
|
|
56
63
|
|
|
57
|
-
if (startsWith(builtSegmentKeyName, p)) return builtSegmentKeyName.
|
|
64
|
+
if (startsWith(builtSegmentKeyName, p)) return builtSegmentKeyName.slice(p.length);
|
|
58
65
|
},
|
|
59
66
|
|
|
60
67
|
buildTillKey() {
|
|
@@ -35,10 +35,9 @@ export function dataLoaderFactory(preloadedData: PreloadedData): DataLoader {
|
|
|
35
35
|
|
|
36
36
|
// cleaning up the localStorage data, since some cached splits might need be part of the preloaded data
|
|
37
37
|
storage.splits.clear();
|
|
38
|
-
storage.splits.setChangeNumber(since);
|
|
39
38
|
|
|
40
39
|
// splitsData in an object where the property is the split name and the pertaining value is a stringified json of its data
|
|
41
|
-
storage.splits.
|
|
40
|
+
storage.splits.update(Object.keys(splitsData).map(splitName => JSON.parse(splitsData[splitName])), [], since);
|
|
42
41
|
|
|
43
42
|
// add mySegments data
|
|
44
43
|
let mySegmentsData = preloadedData.mySegmentsData && preloadedData.mySegmentsData[userId];
|
|
@@ -96,8 +96,9 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
96
96
|
this.hasSync = false;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
addSplit(
|
|
99
|
+
addSplit(split: ISplit) {
|
|
100
100
|
try {
|
|
101
|
+
const name = split.name;
|
|
101
102
|
const splitKey = this.keys.buildSplitKey(name);
|
|
102
103
|
const splitFromLocalStorage = localStorage.getItem(splitKey);
|
|
103
104
|
const previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
|
|
@@ -120,6 +121,8 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
120
121
|
removeSplit(name: string): boolean {
|
|
121
122
|
try {
|
|
122
123
|
const split = this.getSplit(name);
|
|
124
|
+
if (!split) return false;
|
|
125
|
+
|
|
123
126
|
localStorage.removeItem(this.keys.buildSplitKey(name));
|
|
124
127
|
|
|
125
128
|
this._decrementCounts(split);
|
|
@@ -132,7 +135,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
137
|
|
|
135
|
-
getSplit(name: string) {
|
|
138
|
+
getSplit(name: string): ISplit | null {
|
|
136
139
|
const item = localStorage.getItem(this.keys.buildSplitKey(name));
|
|
137
140
|
return item && JSON.parse(item);
|
|
138
141
|
}
|