@statsig/on-device-eval-core 3.26.0 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/Evaluator.d.ts +3 -2
- package/src/Evaluator.js +49 -29
- package/src/SpecStore.d.ts +2 -0
- package/src/SpecStore.js +7 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statsig/on-device-eval-core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.28.0",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"homepage": "https://github.com/statsig-io/js-client-monorepo",
|
|
6
6
|
"repository": {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"directory": "packages/on-device-eval-core"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@statsig/client-core": "3.
|
|
13
|
-
"@statsig/sha256": "3.
|
|
12
|
+
"@statsig/client-core": "3.28.0",
|
|
13
|
+
"@statsig/sha256": "3.28.0"
|
|
14
14
|
},
|
|
15
15
|
"type": "commonjs",
|
|
16
16
|
"main": "./src/index.js",
|
package/src/Evaluator.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DynamicConfigEvaluation, EvaluationDetails, GateEvaluation, LayerEvaluation, ParamStoreConfig, StatsigUserInternal } from '@statsig/client-core';
|
|
1
|
+
import { DynamicConfigEvaluation, EvaluationDetails, GateEvaluation, LayerEvaluation, ParamStoreConfig, Spec, StatsigUserInternal } from '@statsig/client-core';
|
|
2
|
+
import { EvaluationResult } from './EvaluationResult';
|
|
2
3
|
import { SpecStore } from './SpecStore';
|
|
3
4
|
type DetailedEvaluation<T> = {
|
|
4
5
|
evaluation: T | null;
|
|
@@ -15,9 +16,9 @@ export declare class Evaluator {
|
|
|
15
16
|
config: ParamStoreConfig | null;
|
|
16
17
|
details: EvaluationDetails;
|
|
17
18
|
};
|
|
19
|
+
evaluateSpec(spec: Spec, user: StatsigUserInternal): EvaluationResult;
|
|
18
20
|
private _getSpecAndDetails;
|
|
19
21
|
private _getEvaluationDetails;
|
|
20
|
-
private _evaluateSpec;
|
|
21
22
|
private _evaluateRule;
|
|
22
23
|
private _evaluateCondition;
|
|
23
24
|
private _evaluateDelegate;
|
package/src/Evaluator.js
CHANGED
|
@@ -15,7 +15,7 @@ class Evaluator {
|
|
|
15
15
|
if (!spec) {
|
|
16
16
|
return { evaluation: null, details };
|
|
17
17
|
}
|
|
18
|
-
const result = this.
|
|
18
|
+
const result = this.evaluateSpec(spec, user);
|
|
19
19
|
const evaluation = (0, EvaluationResult_1.resultToGateEval)(spec, result);
|
|
20
20
|
this._handleUnsupportedEvaluation(result, details);
|
|
21
21
|
return { evaluation, details };
|
|
@@ -25,7 +25,7 @@ class Evaluator {
|
|
|
25
25
|
if (!spec) {
|
|
26
26
|
return { evaluation: null, details };
|
|
27
27
|
}
|
|
28
|
-
const result = this.
|
|
28
|
+
const result = this.evaluateSpec(spec, user);
|
|
29
29
|
const evaluation = (0, EvaluationResult_1.resultToConfigEval)(spec, result);
|
|
30
30
|
this._handleUnsupportedEvaluation(result, details);
|
|
31
31
|
return { evaluation, details };
|
|
@@ -36,7 +36,7 @@ class Evaluator {
|
|
|
36
36
|
if (!spec) {
|
|
37
37
|
return { evaluation: null, details };
|
|
38
38
|
}
|
|
39
|
-
const result = this.
|
|
39
|
+
const result = this.evaluateSpec(spec, user);
|
|
40
40
|
const experimentName = (_a = result === null || result === void 0 ? void 0 : result.allocated_experiment_name) !== null && _a !== void 0 ? _a : '';
|
|
41
41
|
const experimentSpec = this._store.getSpecAndSourceInfo('config', experimentName).spec;
|
|
42
42
|
const evaluation = (0, EvaluationResult_1.resultToLayerEval)(spec, experimentSpec, result);
|
|
@@ -57,23 +57,7 @@ class Evaluator {
|
|
|
57
57
|
details,
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
const specAndSourceInfo = this._store.getSpecAndSourceInfo(kind, name);
|
|
62
|
-
const details = this._getEvaluationDetails(specAndSourceInfo);
|
|
63
|
-
return { details, spec: specAndSourceInfo.spec };
|
|
64
|
-
}
|
|
65
|
-
_getEvaluationDetails(info) {
|
|
66
|
-
const { source, lcut, receivedAt } = info;
|
|
67
|
-
if (source === 'Uninitialized' || source === 'NoValues') {
|
|
68
|
-
return { reason: source };
|
|
69
|
-
}
|
|
70
|
-
const subreason = ('spec' in info ? info.spec : info.paramStoreConfig) == null
|
|
71
|
-
? 'Unrecognized'
|
|
72
|
-
: 'Recognized';
|
|
73
|
-
const reason = `${source}:${subreason}`;
|
|
74
|
-
return { reason, lcut, receivedAt };
|
|
75
|
-
}
|
|
76
|
-
_evaluateSpec(spec, user) {
|
|
60
|
+
evaluateSpec(spec, user) {
|
|
77
61
|
const defaultValue = _isRecord(spec.defaultValue)
|
|
78
62
|
? spec.defaultValue
|
|
79
63
|
: undefined;
|
|
@@ -84,12 +68,20 @@ class Evaluator {
|
|
|
84
68
|
});
|
|
85
69
|
}
|
|
86
70
|
const exposures = [];
|
|
71
|
+
const seen = {};
|
|
87
72
|
for (const rule of spec.rules) {
|
|
88
73
|
const result = this._evaluateRule(rule, user);
|
|
89
74
|
if (result.unsupported) {
|
|
90
75
|
return result;
|
|
91
76
|
}
|
|
92
|
-
|
|
77
|
+
for (const exposure of result.secondary_exposures) {
|
|
78
|
+
const key = `${exposure.gate}|${exposure.gateValue}|${exposure.ruleID}`;
|
|
79
|
+
if (seen[key]) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
seen[key] = true;
|
|
83
|
+
exposures.push(exposure);
|
|
84
|
+
}
|
|
93
85
|
if (!result.bool_value) {
|
|
94
86
|
continue;
|
|
95
87
|
}
|
|
@@ -115,6 +107,22 @@ class Evaluator {
|
|
|
115
107
|
rule_id: 'default',
|
|
116
108
|
});
|
|
117
109
|
}
|
|
110
|
+
_getSpecAndDetails(kind, name) {
|
|
111
|
+
const specAndSourceInfo = this._store.getSpecAndSourceInfo(kind, name);
|
|
112
|
+
const details = this._getEvaluationDetails(specAndSourceInfo);
|
|
113
|
+
return { details, spec: specAndSourceInfo.spec };
|
|
114
|
+
}
|
|
115
|
+
_getEvaluationDetails(info) {
|
|
116
|
+
const { source, lcut, receivedAt } = info;
|
|
117
|
+
if (source === 'Uninitialized' || source === 'NoValues') {
|
|
118
|
+
return { reason: source };
|
|
119
|
+
}
|
|
120
|
+
const subreason = ('spec' in info ? info.spec : info.paramStoreConfig) == null
|
|
121
|
+
? 'Unrecognized'
|
|
122
|
+
: 'Recognized';
|
|
123
|
+
const reason = `${source}:${subreason}`;
|
|
124
|
+
return { reason, lcut, receivedAt };
|
|
125
|
+
}
|
|
118
126
|
_evaluateRule(rule, user) {
|
|
119
127
|
const exposures = [];
|
|
120
128
|
let pass = true;
|
|
@@ -268,25 +276,37 @@ class Evaluator {
|
|
|
268
276
|
if (!spec) {
|
|
269
277
|
return null;
|
|
270
278
|
}
|
|
271
|
-
const result = this.
|
|
272
|
-
|
|
279
|
+
const result = this.evaluateSpec(spec, user);
|
|
280
|
+
const seen = {};
|
|
281
|
+
const mergedExposures = [];
|
|
282
|
+
for (const exposure of exposures.concat(result.secondary_exposures)) {
|
|
283
|
+
const key = `${exposure.gate}|${exposure.gateValue}|${exposure.ruleID}`;
|
|
284
|
+
if (seen[key]) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
seen[key] = true;
|
|
288
|
+
mergedExposures.push(exposure);
|
|
289
|
+
}
|
|
290
|
+
return (0, EvaluationResult_1.makeEvalResult)(Object.assign(Object.assign({}, result), { allocated_experiment_name: configDelegate, explicit_parameters: spec.explicitParameters, secondary_exposures: mergedExposures, undelegated_secondary_exposures: exposures }));
|
|
273
291
|
}
|
|
274
292
|
_evaluateNestedGate(name, user) {
|
|
275
293
|
const exposures = [];
|
|
276
294
|
let pass = false;
|
|
277
295
|
const { spec } = this._store.getSpecAndSourceInfo('gate', name);
|
|
278
296
|
if (spec) {
|
|
279
|
-
const result = this.
|
|
297
|
+
const result = this.evaluateSpec(spec, user);
|
|
280
298
|
if (result.unsupported) {
|
|
281
299
|
return result;
|
|
282
300
|
}
|
|
283
301
|
pass = result.bool_value;
|
|
284
302
|
exposures.push(...result.secondary_exposures);
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
303
|
+
if (!name.startsWith('segment:')) {
|
|
304
|
+
exposures.push({
|
|
305
|
+
gate: name,
|
|
306
|
+
gateValue: String(pass),
|
|
307
|
+
ruleID: result.rule_id,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
290
310
|
}
|
|
291
311
|
return (0, EvaluationResult_1.makeEvalResult)({
|
|
292
312
|
bool_value: pass,
|
package/src/SpecStore.d.ts
CHANGED
|
@@ -27,4 +27,6 @@ export declare class SpecStore {
|
|
|
27
27
|
getSpecAndSourceInfo(kind: SpecKind, name: string): SpecAndSourceInfo;
|
|
28
28
|
getParamStoreAndSourceInfo(name: string): ParamStoreAndSourceInfo;
|
|
29
29
|
private _getSpecs;
|
|
30
|
+
getAllSpecs(kind: SpecKind): Spec[];
|
|
31
|
+
getLastUpdateTime(): number;
|
|
30
32
|
}
|
package/src/SpecStore.js
CHANGED
|
@@ -86,5 +86,12 @@ class SpecStore {
|
|
|
86
86
|
return (_c = this._values) === null || _c === void 0 ? void 0 : _c.layer_configs;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
getAllSpecs(kind) {
|
|
90
|
+
const specs = this._getSpecs(kind);
|
|
91
|
+
return specs || [];
|
|
92
|
+
}
|
|
93
|
+
getLastUpdateTime() {
|
|
94
|
+
return this._lcut;
|
|
95
|
+
}
|
|
89
96
|
}
|
|
90
97
|
exports.SpecStore = SpecStore;
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./Evaluator"), exports);
|
|
18
|
+
__exportStar(require("./EvaluationResult"), exports);
|
|
18
19
|
__exportStar(require("./SpecStore"), exports);
|