@featurevisor/sdk 1.35.3 → 2.0.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/README.md +2 -381
- package/coverage/clover.xml +707 -645
- package/coverage/coverage-final.json +11 -9
- package/coverage/lcov-report/{segments.ts.html → bucketer.ts.html} +155 -77
- package/coverage/lcov-report/child.ts.html +940 -0
- package/coverage/lcov-report/conditions.ts.html +107 -158
- package/coverage/lcov-report/datafileReader.ts.html +763 -103
- package/coverage/lcov-report/emitter.ts.html +77 -59
- package/coverage/lcov-report/evaluate.ts.html +689 -416
- package/coverage/lcov-report/events.ts.html +334 -0
- package/coverage/lcov-report/helpers.ts.html +184 -0
- package/coverage/lcov-report/{bucket.ts.html → hooks.ts.html} +86 -239
- package/coverage/lcov-report/index.html +119 -89
- package/coverage/lcov-report/instance.ts.html +341 -773
- package/coverage/lcov-report/logger.ts.html +64 -64
- package/coverage/lcov.info +1433 -1226
- package/dist/bucketer.d.ts +11 -0
- package/dist/child.d.ts +26 -0
- package/dist/compareVersions.d.ts +4 -0
- package/dist/conditions.d.ts +4 -4
- package/dist/datafileReader.d.ts +26 -6
- package/dist/emitter.d.ts +8 -9
- package/dist/evaluate.d.ts +31 -29
- package/dist/events.d.ts +5 -0
- package/dist/helpers.d.ts +5 -0
- package/dist/hooks.d.ts +45 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.gz +0 -0
- package/dist/index.mjs.map +1 -1
- package/dist/instance.d.ts +40 -72
- package/dist/logger.d.ts +6 -5
- package/dist/murmurhash.d.ts +1 -0
- package/jest.config.js +2 -0
- package/lib/bucketer.d.ts +11 -0
- package/lib/child.d.ts +26 -0
- package/lib/compareVersions.d.ts +4 -0
- package/lib/conditions.d.ts +4 -4
- package/lib/datafileReader.d.ts +26 -6
- package/lib/emitter.d.ts +8 -9
- package/lib/evaluate.d.ts +31 -29
- package/lib/events.d.ts +5 -0
- package/lib/helpers.d.ts +5 -0
- package/lib/hooks.d.ts +45 -0
- package/lib/index.d.ts +3 -2
- package/lib/instance.d.ts +40 -72
- package/lib/logger.d.ts +6 -5
- package/lib/murmurhash.d.ts +1 -0
- package/package.json +3 -5
- package/src/bucketer.spec.ts +165 -0
- package/src/bucketer.ts +84 -0
- package/src/child.spec.ts +267 -0
- package/src/child.ts +285 -0
- package/src/compareVersions.ts +93 -0
- package/src/conditions.spec.ts +563 -353
- package/src/conditions.ts +46 -63
- package/src/datafileReader.spec.ts +396 -84
- package/src/datafileReader.ts +280 -60
- package/src/emitter.spec.ts +27 -86
- package/src/emitter.ts +38 -32
- package/src/evaluate.ts +349 -258
- package/src/events.spec.ts +154 -0
- package/src/events.ts +83 -0
- package/src/helpers.ts +33 -0
- package/src/hooks.ts +88 -0
- package/src/index.ts +3 -2
- package/src/instance.spec.ts +305 -489
- package/src/instance.ts +247 -391
- package/src/logger.spec.ts +212 -134
- package/src/logger.ts +36 -36
- package/src/murmurhash.ts +71 -0
- package/coverage/lcov-report/feature.ts.html +0 -508
- package/dist/bucket.d.ts +0 -30
- package/dist/feature.d.ts +0 -16
- package/dist/segments.d.ts +0 -5
- package/lib/bucket.d.ts +0 -30
- package/lib/feature.d.ts +0 -16
- package/lib/segments.d.ts +0 -5
- package/src/bucket.spec.ts +0 -37
- package/src/bucket.ts +0 -139
- package/src/feature.ts +0 -141
- package/src/segments.spec.ts +0 -468
- package/src/segments.ts +0 -58
package/dist/instance.d.ts
CHANGED
|
@@ -1,99 +1,67 @@
|
|
|
1
|
-
import { Context,
|
|
1
|
+
import type { Context, Feature, FeatureKey, StickyFeatures, EvaluatedFeatures, VariableValue, VariationValue, VariableKey, DatafileContent } from "@featurevisor/types";
|
|
2
2
|
import { Logger, LogLevel } from "./logger";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { Hook } from "./hooks";
|
|
4
|
+
import { EventCallback, EventName } from "./emitter";
|
|
5
5
|
import { Evaluation } from "./evaluate";
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
import { FeaturevisorChildInstance } from "./child";
|
|
7
|
+
export interface OverrideOptions {
|
|
8
|
+
sticky?: StickyFeatures;
|
|
9
|
+
defaultVariationValue?: VariationValue;
|
|
10
|
+
defaultVariableValue?: VariableValue;
|
|
11
11
|
}
|
|
12
|
-
export type InterceptContext = (context: Context) => Context;
|
|
13
12
|
export interface InstanceOptions {
|
|
14
|
-
bucketKeySeparator?: string;
|
|
15
|
-
configureBucketKey?: ConfigureBucketKey;
|
|
16
|
-
configureBucketValue?: ConfigureBucketValue;
|
|
17
13
|
datafile?: DatafileContent | string;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
initialFeatures?: InitialFeatures;
|
|
21
|
-
interceptContext?: InterceptContext;
|
|
14
|
+
context?: Context;
|
|
15
|
+
logLevel?: LogLevel;
|
|
22
16
|
logger?: Logger;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
onRefresh?: () => void;
|
|
26
|
-
onUpdate?: () => void;
|
|
27
|
-
refreshInterval?: number;
|
|
28
|
-
stickyFeatures?: StickyFeatures;
|
|
17
|
+
sticky?: StickyFeatures;
|
|
18
|
+
hooks?: Hook[];
|
|
29
19
|
}
|
|
30
|
-
export type DatafileFetchHandler = (datafileUrl: string) => Promise<DatafileContent>;
|
|
31
|
-
type FieldType = string | VariableType;
|
|
32
|
-
type ValueType = VariableValue;
|
|
33
|
-
export declare function getValueByType(value: ValueType, fieldType: FieldType): ValueType;
|
|
34
20
|
export declare class FeaturevisorInstance {
|
|
35
|
-
private
|
|
36
|
-
private configureBucketKey?;
|
|
37
|
-
private configureBucketValue?;
|
|
38
|
-
private datafileUrl?;
|
|
39
|
-
private handleDatafileFetch?;
|
|
40
|
-
private initialFeatures?;
|
|
41
|
-
private interceptContext?;
|
|
21
|
+
private context;
|
|
42
22
|
private logger;
|
|
43
|
-
private
|
|
44
|
-
private stickyFeatures?;
|
|
23
|
+
private sticky?;
|
|
45
24
|
private datafileReader;
|
|
25
|
+
private hooksManager;
|
|
46
26
|
private emitter;
|
|
47
|
-
private statuses;
|
|
48
|
-
private intervalId?;
|
|
49
|
-
on: Emitter["addListener"];
|
|
50
|
-
addListener: Emitter["addListener"];
|
|
51
|
-
off: Emitter["removeListener"];
|
|
52
|
-
removeListener: Emitter["removeListener"];
|
|
53
|
-
removeAllListeners: Emitter["removeAllListeners"];
|
|
54
27
|
constructor(options: InstanceOptions);
|
|
55
|
-
|
|
56
|
-
onReady(): Promise<FeaturevisorInstance>;
|
|
28
|
+
setLogLevel(level: LogLevel): void;
|
|
57
29
|
setDatafile(datafile: DatafileContent | string): void;
|
|
58
|
-
|
|
30
|
+
setSticky(sticky: StickyFeatures, replace?: boolean): void;
|
|
59
31
|
getRevision(): string;
|
|
60
|
-
getFeature(featureKey: string
|
|
32
|
+
getFeature(featureKey: string): Feature | undefined;
|
|
33
|
+
addHook(hook: Hook): () => void;
|
|
34
|
+
on(eventName: EventName, callback: EventCallback): () => void;
|
|
35
|
+
close(): void;
|
|
61
36
|
/**
|
|
62
|
-
*
|
|
37
|
+
* Context
|
|
63
38
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*/
|
|
68
|
-
refresh(): void;
|
|
69
|
-
startRefreshing(): void;
|
|
70
|
-
stopRefreshing(): void;
|
|
39
|
+
setContext(context: Context, replace?: boolean): void;
|
|
40
|
+
getContext(context?: Context): Context;
|
|
41
|
+
spawn(context?: Context, options?: OverrideOptions): FeaturevisorChildInstance;
|
|
71
42
|
/**
|
|
72
43
|
* Flag
|
|
73
44
|
*/
|
|
74
|
-
|
|
75
|
-
|
|
45
|
+
private getEvaluationDependencies;
|
|
46
|
+
evaluateFlag(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): Evaluation;
|
|
47
|
+
isEnabled(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): boolean;
|
|
76
48
|
/**
|
|
77
49
|
* Variation
|
|
78
50
|
*/
|
|
79
|
-
evaluateVariation(featureKey: FeatureKey
|
|
80
|
-
getVariation(featureKey: FeatureKey
|
|
81
|
-
/**
|
|
82
|
-
* Activate
|
|
83
|
-
*/
|
|
84
|
-
activate(featureKey: FeatureKey, context?: Context): VariationValue | undefined;
|
|
51
|
+
evaluateVariation(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): Evaluation;
|
|
52
|
+
getVariation(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): VariationValue | null;
|
|
85
53
|
/**
|
|
86
54
|
* Variable
|
|
87
55
|
*/
|
|
88
|
-
evaluateVariable(featureKey: FeatureKey
|
|
89
|
-
getVariable(featureKey: FeatureKey
|
|
90
|
-
getVariableBoolean(featureKey: FeatureKey
|
|
91
|
-
getVariableString(featureKey: FeatureKey
|
|
92
|
-
getVariableInteger(featureKey: FeatureKey
|
|
93
|
-
getVariableDouble(featureKey: FeatureKey
|
|
94
|
-
getVariableArray(featureKey: FeatureKey
|
|
95
|
-
getVariableObject<T>(featureKey: FeatureKey
|
|
96
|
-
getVariableJSON<T>(featureKey: FeatureKey
|
|
56
|
+
evaluateVariable(featureKey: FeatureKey, variableKey: VariableKey, context?: Context, options?: OverrideOptions): Evaluation;
|
|
57
|
+
getVariable(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): VariableValue | null;
|
|
58
|
+
getVariableBoolean(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): boolean | null;
|
|
59
|
+
getVariableString(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string | null;
|
|
60
|
+
getVariableInteger(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
|
|
61
|
+
getVariableDouble(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
|
|
62
|
+
getVariableArray(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string[] | null;
|
|
63
|
+
getVariableObject<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
|
|
64
|
+
getVariableJSON<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
|
|
65
|
+
getAllEvaluations(context?: Context, featureKeys?: string[], options?: OverrideOptions): EvaluatedFeatures;
|
|
97
66
|
}
|
|
98
67
|
export declare function createInstance(options: InstanceOptions): FeaturevisorInstance;
|
|
99
|
-
export {};
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
export type LogLevel = "
|
|
1
|
+
export type LogLevel = "fatal" | "error" | "warn" | "info" | "debug";
|
|
2
2
|
export type LogMessage = string;
|
|
3
3
|
export interface LogDetails {
|
|
4
4
|
[key: string]: any;
|
|
5
5
|
}
|
|
6
6
|
export type LogHandler = (level: LogLevel, message: LogMessage, details?: LogDetails) => void;
|
|
7
7
|
export interface CreateLoggerOptions {
|
|
8
|
-
|
|
8
|
+
level?: LogLevel;
|
|
9
9
|
handler?: LogHandler;
|
|
10
10
|
}
|
|
11
11
|
export declare const loggerPrefix = "[Featurevisor]";
|
|
12
|
-
export declare const defaultLogLevels: LogLevel[];
|
|
13
12
|
export declare const defaultLogHandler: LogHandler;
|
|
14
13
|
export declare class Logger {
|
|
15
|
-
|
|
14
|
+
static allLevels: LogLevel[];
|
|
15
|
+
static defaultLevel: LogLevel;
|
|
16
|
+
private level;
|
|
16
17
|
private handle;
|
|
17
18
|
constructor(options: CreateLoggerOptions);
|
|
18
|
-
|
|
19
|
+
setLevel(level: LogLevel): void;
|
|
19
20
|
log(level: LogLevel, message: LogMessage, details?: LogDetails): void;
|
|
20
21
|
debug(message: LogMessage, details?: LogDetails): void;
|
|
21
22
|
info(message: LogMessage, details?: LogDetails): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function MurmurHashV3(key: any, seed: any): number;
|
package/jest.config.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BucketKey, Context, FeatureKey, BucketBy } from "@featurevisor/types";
|
|
2
|
+
import { Logger } from "./logger";
|
|
3
|
+
export declare const MAX_BUCKETED_NUMBER = 100000;
|
|
4
|
+
export declare function getBucketedNumber(bucketKey: string): number;
|
|
5
|
+
export interface GetBucketKeyOptions {
|
|
6
|
+
featureKey: FeatureKey;
|
|
7
|
+
bucketBy: BucketBy;
|
|
8
|
+
context: Context;
|
|
9
|
+
logger: Logger;
|
|
10
|
+
}
|
|
11
|
+
export declare function getBucketKey(options: GetBucketKeyOptions): BucketKey;
|
package/lib/child.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Context, StickyFeatures, FeatureKey, VariationValue, VariableValue, EvaluatedFeatures } from "@featurevisor/types";
|
|
2
|
+
import { EventName, EventCallback } from "./emitter";
|
|
3
|
+
import type { OverrideOptions } from "./instance";
|
|
4
|
+
export declare class FeaturevisorChildInstance {
|
|
5
|
+
private parent;
|
|
6
|
+
private context;
|
|
7
|
+
private sticky;
|
|
8
|
+
private emitter;
|
|
9
|
+
constructor(options: any);
|
|
10
|
+
on(eventName: EventName, callback: EventCallback): () => void;
|
|
11
|
+
close(): void;
|
|
12
|
+
setContext(context: Context, replace?: boolean): void;
|
|
13
|
+
getContext(context?: Context): Context;
|
|
14
|
+
setSticky(sticky: StickyFeatures, replace?: boolean): void;
|
|
15
|
+
isEnabled(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): boolean;
|
|
16
|
+
getVariation(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): VariationValue | null;
|
|
17
|
+
getVariable(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): VariableValue | null;
|
|
18
|
+
getVariableBoolean(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): boolean | null;
|
|
19
|
+
getVariableString(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string | null;
|
|
20
|
+
getVariableInteger(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
|
|
21
|
+
getVariableDouble(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
|
|
22
|
+
getVariableArray(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string[] | null;
|
|
23
|
+
getVariableObject<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
|
|
24
|
+
getVariableJSON<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
|
|
25
|
+
getAllEvaluations(context?: Context, featureKeys?: string[], options?: OverrideOptions): EvaluatedFeatures;
|
|
26
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const semver: RegExp;
|
|
2
|
+
export declare const validateAndParse: (version: string) => RegExpMatchArray;
|
|
3
|
+
export declare const compareSegments: (a: string | string[] | RegExpMatchArray, b: string | string[] | RegExpMatchArray) => 1 | 0 | -1;
|
|
4
|
+
export declare const compareVersions: (v1: string, v2: string) => 1 | 0 | -1;
|
package/lib/conditions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context,
|
|
2
|
-
import {
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
1
|
+
import type { Context, PlainCondition, AttributeValue } from "@featurevisor/types";
|
|
2
|
+
import { GetRegex } from "./datafileReader";
|
|
3
|
+
export declare function getValueFromContext(obj: any, path: any): AttributeValue;
|
|
4
|
+
export declare function conditionIsMatched(condition: PlainCondition, context: Context, getRegex: GetRegex): boolean;
|
package/lib/datafileReader.d.ts
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
import { Feature, Segment,
|
|
2
|
-
|
|
1
|
+
import type { Feature, Segment, DatafileContent, SegmentKey, FeatureKey, Context, Traffic, Allocation, GroupSegment, Condition, Force } from "@featurevisor/types";
|
|
2
|
+
import { Logger } from "./logger";
|
|
3
|
+
export type GetRegex = (regexString: string, regexFlags: string) => RegExp;
|
|
4
|
+
export interface DatafileReaderOptions {
|
|
5
|
+
datafile: DatafileContent;
|
|
6
|
+
logger: Logger;
|
|
7
|
+
}
|
|
8
|
+
export interface ForceResult {
|
|
9
|
+
force?: Force;
|
|
10
|
+
forceIndex?: number;
|
|
11
|
+
}
|
|
3
12
|
export declare class DatafileReader {
|
|
4
13
|
private schemaVersion;
|
|
5
14
|
private revision;
|
|
6
|
-
private attributes;
|
|
7
15
|
private segments;
|
|
8
16
|
private features;
|
|
9
|
-
|
|
17
|
+
private logger;
|
|
18
|
+
private regexCache;
|
|
19
|
+
constructor(options: DatafileReaderOptions);
|
|
10
20
|
getRevision(): string;
|
|
11
21
|
getSchemaVersion(): string;
|
|
12
|
-
getAllAttributes(): Attribute[];
|
|
13
|
-
getAttribute(attributeKey: AttributeKey): Attribute | undefined;
|
|
14
22
|
getSegment(segmentKey: SegmentKey): Segment | undefined;
|
|
23
|
+
getFeatureKeys(): string[];
|
|
15
24
|
getFeature(featureKey: FeatureKey): Feature | undefined;
|
|
25
|
+
getVariableKeys(featureKey: FeatureKey): string[];
|
|
26
|
+
hasVariations(featureKey: FeatureKey): boolean;
|
|
27
|
+
getRegex(regexString: string, regexFlags?: string): RegExp;
|
|
28
|
+
allConditionsAreMatched(conditions: Condition[] | Condition, context: Context): boolean;
|
|
29
|
+
segmentIsMatched(segment: Segment, context: Context): boolean;
|
|
30
|
+
allSegmentsAreMatched(groupSegments: GroupSegment | GroupSegment[] | "*", context: Context): boolean;
|
|
31
|
+
getMatchedTraffic(traffic: Traffic[], context: Context): Traffic | undefined;
|
|
32
|
+
getMatchedAllocation(traffic: Traffic, bucketValue: number): Allocation | undefined;
|
|
33
|
+
getMatchedForce(featureKey: FeatureKey | Feature, context: Context): ForceResult;
|
|
34
|
+
parseConditionsIfStringified(conditions: Condition | Condition[]): Condition | Condition[];
|
|
35
|
+
parseSegmentsIfStringified(segments: GroupSegment | GroupSegment[]): GroupSegment | GroupSegment[];
|
|
16
36
|
}
|
package/lib/emitter.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
export type EventName = "
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
}
|
|
1
|
+
export type EventName = "datafile_set" | "context_set" | "sticky_set";
|
|
2
|
+
export type EventDetails = Record<string, unknown>;
|
|
3
|
+
export type EventCallback = (details: EventDetails) => void;
|
|
4
|
+
export type Listeners = Record<EventName, EventCallback[]> | {};
|
|
5
5
|
export declare class Emitter {
|
|
6
|
-
|
|
6
|
+
listeners: Listeners;
|
|
7
7
|
constructor();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
emit(eventName: EventName, ...args: any[]): void;
|
|
8
|
+
on(eventName: EventName, callback: EventCallback): () => void;
|
|
9
|
+
trigger(eventName: EventName, details?: EventDetails): void;
|
|
10
|
+
clearAll(): void;
|
|
12
11
|
}
|
package/lib/evaluate.d.ts
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FeatureKey, Context, BucketKey, BucketValue, RuleKey, Traffic, Force, Required, Variation, VariationValue, VariableKey, VariableValue, VariableSchema, EvaluatedFeature, StickyFeatures } from "@featurevisor/types";
|
|
2
2
|
import { Logger } from "./logger";
|
|
3
|
+
import { HooksManager } from "./hooks";
|
|
3
4
|
import { DatafileReader } from "./datafileReader";
|
|
4
|
-
import { ConfigureBucketKey, ConfigureBucketValue } from "./bucket";
|
|
5
|
-
import type { Statuses, InterceptContext } from "./instance";
|
|
6
5
|
export declare enum EvaluationReason {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
FEATURE_NOT_FOUND = "feature_not_found",// feature is not found in datafile
|
|
7
|
+
DISABLED = "disabled",// feature is disabled
|
|
8
|
+
REQUIRED = "required",// required features are not enabled
|
|
9
|
+
OUT_OF_RANGE = "out_of_range",// out of range when mutually exclusive experiments are involved via Groups
|
|
10
|
+
NO_VARIATIONS = "no_variations",// feature has no variations
|
|
11
|
+
VARIATION_DISABLED = "variation_disabled",// feature is disabled, and variation's disabledVariationValue is used
|
|
12
|
+
VARIABLE_NOT_FOUND = "variable_not_found",// variable's schema is not defined in the feature
|
|
13
|
+
VARIABLE_DEFAULT = "variable_default",// default variable value used
|
|
14
|
+
VARIABLE_DISABLED = "variable_disabled",// feature is disabled, and variable's disabledValue is used
|
|
15
|
+
VARIABLE_OVERRIDE = "variable_override",// variable overridden from inside a variation
|
|
16
|
+
NO_MATCH = "no_match",// no rules matched
|
|
17
|
+
FORCED = "forced",// against a forced rule
|
|
18
|
+
STICKY = "sticky",// against a sticky feature
|
|
19
|
+
RULE = "rule",// against a regular rule
|
|
20
|
+
ALLOCATED = "allocated",// regular allocation based on bucketing
|
|
20
21
|
ERROR = "error"
|
|
21
22
|
}
|
|
22
23
|
type EvaluationType = "flag" | "variation" | "variable";
|
|
23
24
|
export interface Evaluation {
|
|
25
|
+
type: EvaluationType;
|
|
24
26
|
featureKey: FeatureKey;
|
|
25
27
|
reason: EvaluationReason;
|
|
26
28
|
bucketKey?: BucketKey;
|
|
@@ -32,28 +34,28 @@ export interface Evaluation {
|
|
|
32
34
|
forceIndex?: number;
|
|
33
35
|
force?: Force;
|
|
34
36
|
required?: Required[];
|
|
35
|
-
sticky?:
|
|
36
|
-
initial?: OverrideFeature;
|
|
37
|
+
sticky?: EvaluatedFeature;
|
|
37
38
|
variation?: Variation;
|
|
38
39
|
variationValue?: VariationValue;
|
|
39
40
|
variableKey?: VariableKey;
|
|
40
41
|
variableValue?: VariableValue;
|
|
41
42
|
variableSchema?: VariableSchema;
|
|
42
43
|
}
|
|
43
|
-
export interface
|
|
44
|
-
type: EvaluationType;
|
|
45
|
-
featureKey: FeatureKey | Feature;
|
|
46
|
-
variableKey?: VariableKey;
|
|
44
|
+
export interface EvaluateDependencies {
|
|
47
45
|
context: Context;
|
|
48
46
|
logger: Logger;
|
|
47
|
+
hooksManager: HooksManager;
|
|
49
48
|
datafileReader: DatafileReader;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
sticky?: StickyFeatures;
|
|
50
|
+
defaultVariationValue?: VariationValue;
|
|
51
|
+
defaultVariableValue?: VariableValue;
|
|
52
|
+
}
|
|
53
|
+
export interface EvaluateParams {
|
|
54
|
+
type: EvaluationType;
|
|
55
|
+
featureKey: FeatureKey;
|
|
56
|
+
variableKey?: VariableKey;
|
|
57
57
|
}
|
|
58
|
+
export type EvaluateOptions = EvaluateParams & EvaluateDependencies;
|
|
59
|
+
export declare function evaluateWithHooks(opts: EvaluateOptions): Evaluation;
|
|
58
60
|
export declare function evaluate(options: EvaluateOptions): Evaluation;
|
|
59
61
|
export {};
|
package/lib/events.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StickyFeatures } from "@featurevisor/types";
|
|
2
|
+
import type { EventDetails } from "./emitter";
|
|
3
|
+
import type { DatafileReader } from "./datafileReader";
|
|
4
|
+
export declare function getParamsForStickySetEvent(previousStickyFeatures: StickyFeatures, newStickyFeatures: StickyFeatures, replace: any): EventDetails;
|
|
5
|
+
export declare function getParamsForDatafileSetEvent(previousDatafileReader: DatafileReader, newDatafileReader: DatafileReader): EventDetails;
|
package/lib/helpers.d.ts
ADDED
package/lib/hooks.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { BucketBy, BucketKey, BucketValue, Context, FeatureKey } from "@featurevisor/types";
|
|
2
|
+
import type { EvaluateOptions, Evaluation } from "./evaluate";
|
|
3
|
+
import type { Logger } from "./logger";
|
|
4
|
+
/**
|
|
5
|
+
* bucketKey
|
|
6
|
+
*/
|
|
7
|
+
export interface ConfigureBucketKeyOptions {
|
|
8
|
+
featureKey: FeatureKey;
|
|
9
|
+
context: Context;
|
|
10
|
+
bucketBy: BucketBy;
|
|
11
|
+
bucketKey: string;
|
|
12
|
+
}
|
|
13
|
+
export type ConfigureBucketKey = (options: ConfigureBucketKeyOptions) => BucketKey;
|
|
14
|
+
/**
|
|
15
|
+
* bucketValue
|
|
16
|
+
*/
|
|
17
|
+
export interface ConfigureBucketValueOptions {
|
|
18
|
+
featureKey: FeatureKey;
|
|
19
|
+
bucketKey: string;
|
|
20
|
+
context: Context;
|
|
21
|
+
bucketValue: number;
|
|
22
|
+
}
|
|
23
|
+
export type ConfigureBucketValue = (options: ConfigureBucketValueOptions) => BucketValue;
|
|
24
|
+
/**
|
|
25
|
+
* Hooks
|
|
26
|
+
*/
|
|
27
|
+
export interface Hook {
|
|
28
|
+
name: string;
|
|
29
|
+
before?: (options: EvaluateOptions) => EvaluateOptions;
|
|
30
|
+
bucketKey?: ConfigureBucketKey;
|
|
31
|
+
bucketValue?: ConfigureBucketValue;
|
|
32
|
+
after?: (evaluation: Evaluation, options: EvaluateOptions) => Evaluation;
|
|
33
|
+
}
|
|
34
|
+
export interface HooksManagerOptions {
|
|
35
|
+
hooks?: Hook[];
|
|
36
|
+
logger: Logger;
|
|
37
|
+
}
|
|
38
|
+
export declare class HooksManager {
|
|
39
|
+
private hooks;
|
|
40
|
+
private logger;
|
|
41
|
+
constructor(options: HooksManagerOptions);
|
|
42
|
+
add(hook: Hook): (() => void) | undefined;
|
|
43
|
+
remove(name: string): void;
|
|
44
|
+
getAll(): Hook[];
|
|
45
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./bucketer";
|
|
2
2
|
export * from "./instance";
|
|
3
3
|
export * from "./logger";
|
|
4
4
|
export * from "./conditions";
|
|
5
|
-
export * from "./emitter";
|
|
6
5
|
export * from "./evaluate";
|
|
6
|
+
export * from "./datafileReader";
|
|
7
|
+
export * from "./child";
|
package/lib/instance.d.ts
CHANGED
|
@@ -1,99 +1,67 @@
|
|
|
1
|
-
import { Context,
|
|
1
|
+
import type { Context, Feature, FeatureKey, StickyFeatures, EvaluatedFeatures, VariableValue, VariationValue, VariableKey, DatafileContent } from "@featurevisor/types";
|
|
2
2
|
import { Logger, LogLevel } from "./logger";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { Hook } from "./hooks";
|
|
4
|
+
import { EventCallback, EventName } from "./emitter";
|
|
5
5
|
import { Evaluation } from "./evaluate";
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
import { FeaturevisorChildInstance } from "./child";
|
|
7
|
+
export interface OverrideOptions {
|
|
8
|
+
sticky?: StickyFeatures;
|
|
9
|
+
defaultVariationValue?: VariationValue;
|
|
10
|
+
defaultVariableValue?: VariableValue;
|
|
11
11
|
}
|
|
12
|
-
export type InterceptContext = (context: Context) => Context;
|
|
13
12
|
export interface InstanceOptions {
|
|
14
|
-
bucketKeySeparator?: string;
|
|
15
|
-
configureBucketKey?: ConfigureBucketKey;
|
|
16
|
-
configureBucketValue?: ConfigureBucketValue;
|
|
17
13
|
datafile?: DatafileContent | string;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
initialFeatures?: InitialFeatures;
|
|
21
|
-
interceptContext?: InterceptContext;
|
|
14
|
+
context?: Context;
|
|
15
|
+
logLevel?: LogLevel;
|
|
22
16
|
logger?: Logger;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
onRefresh?: () => void;
|
|
26
|
-
onUpdate?: () => void;
|
|
27
|
-
refreshInterval?: number;
|
|
28
|
-
stickyFeatures?: StickyFeatures;
|
|
17
|
+
sticky?: StickyFeatures;
|
|
18
|
+
hooks?: Hook[];
|
|
29
19
|
}
|
|
30
|
-
export type DatafileFetchHandler = (datafileUrl: string) => Promise<DatafileContent>;
|
|
31
|
-
type FieldType = string | VariableType;
|
|
32
|
-
type ValueType = VariableValue;
|
|
33
|
-
export declare function getValueByType(value: ValueType, fieldType: FieldType): ValueType;
|
|
34
20
|
export declare class FeaturevisorInstance {
|
|
35
|
-
private
|
|
36
|
-
private configureBucketKey?;
|
|
37
|
-
private configureBucketValue?;
|
|
38
|
-
private datafileUrl?;
|
|
39
|
-
private handleDatafileFetch?;
|
|
40
|
-
private initialFeatures?;
|
|
41
|
-
private interceptContext?;
|
|
21
|
+
private context;
|
|
42
22
|
private logger;
|
|
43
|
-
private
|
|
44
|
-
private stickyFeatures?;
|
|
23
|
+
private sticky?;
|
|
45
24
|
private datafileReader;
|
|
25
|
+
private hooksManager;
|
|
46
26
|
private emitter;
|
|
47
|
-
private statuses;
|
|
48
|
-
private intervalId?;
|
|
49
|
-
on: Emitter["addListener"];
|
|
50
|
-
addListener: Emitter["addListener"];
|
|
51
|
-
off: Emitter["removeListener"];
|
|
52
|
-
removeListener: Emitter["removeListener"];
|
|
53
|
-
removeAllListeners: Emitter["removeAllListeners"];
|
|
54
27
|
constructor(options: InstanceOptions);
|
|
55
|
-
|
|
56
|
-
onReady(): Promise<FeaturevisorInstance>;
|
|
28
|
+
setLogLevel(level: LogLevel): void;
|
|
57
29
|
setDatafile(datafile: DatafileContent | string): void;
|
|
58
|
-
|
|
30
|
+
setSticky(sticky: StickyFeatures, replace?: boolean): void;
|
|
59
31
|
getRevision(): string;
|
|
60
|
-
getFeature(featureKey: string
|
|
32
|
+
getFeature(featureKey: string): Feature | undefined;
|
|
33
|
+
addHook(hook: Hook): () => void;
|
|
34
|
+
on(eventName: EventName, callback: EventCallback): () => void;
|
|
35
|
+
close(): void;
|
|
61
36
|
/**
|
|
62
|
-
*
|
|
37
|
+
* Context
|
|
63
38
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*/
|
|
68
|
-
refresh(): void;
|
|
69
|
-
startRefreshing(): void;
|
|
70
|
-
stopRefreshing(): void;
|
|
39
|
+
setContext(context: Context, replace?: boolean): void;
|
|
40
|
+
getContext(context?: Context): Context;
|
|
41
|
+
spawn(context?: Context, options?: OverrideOptions): FeaturevisorChildInstance;
|
|
71
42
|
/**
|
|
72
43
|
* Flag
|
|
73
44
|
*/
|
|
74
|
-
|
|
75
|
-
|
|
45
|
+
private getEvaluationDependencies;
|
|
46
|
+
evaluateFlag(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): Evaluation;
|
|
47
|
+
isEnabled(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): boolean;
|
|
76
48
|
/**
|
|
77
49
|
* Variation
|
|
78
50
|
*/
|
|
79
|
-
evaluateVariation(featureKey: FeatureKey
|
|
80
|
-
getVariation(featureKey: FeatureKey
|
|
81
|
-
/**
|
|
82
|
-
* Activate
|
|
83
|
-
*/
|
|
84
|
-
activate(featureKey: FeatureKey, context?: Context): VariationValue | undefined;
|
|
51
|
+
evaluateVariation(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): Evaluation;
|
|
52
|
+
getVariation(featureKey: FeatureKey, context?: Context, options?: OverrideOptions): VariationValue | null;
|
|
85
53
|
/**
|
|
86
54
|
* Variable
|
|
87
55
|
*/
|
|
88
|
-
evaluateVariable(featureKey: FeatureKey
|
|
89
|
-
getVariable(featureKey: FeatureKey
|
|
90
|
-
getVariableBoolean(featureKey: FeatureKey
|
|
91
|
-
getVariableString(featureKey: FeatureKey
|
|
92
|
-
getVariableInteger(featureKey: FeatureKey
|
|
93
|
-
getVariableDouble(featureKey: FeatureKey
|
|
94
|
-
getVariableArray(featureKey: FeatureKey
|
|
95
|
-
getVariableObject<T>(featureKey: FeatureKey
|
|
96
|
-
getVariableJSON<T>(featureKey: FeatureKey
|
|
56
|
+
evaluateVariable(featureKey: FeatureKey, variableKey: VariableKey, context?: Context, options?: OverrideOptions): Evaluation;
|
|
57
|
+
getVariable(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): VariableValue | null;
|
|
58
|
+
getVariableBoolean(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): boolean | null;
|
|
59
|
+
getVariableString(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string | null;
|
|
60
|
+
getVariableInteger(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
|
|
61
|
+
getVariableDouble(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
|
|
62
|
+
getVariableArray(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string[] | null;
|
|
63
|
+
getVariableObject<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
|
|
64
|
+
getVariableJSON<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
|
|
65
|
+
getAllEvaluations(context?: Context, featureKeys?: string[], options?: OverrideOptions): EvaluatedFeatures;
|
|
97
66
|
}
|
|
98
67
|
export declare function createInstance(options: InstanceOptions): FeaturevisorInstance;
|
|
99
|
-
export {};
|
package/lib/logger.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
export type LogLevel = "
|
|
1
|
+
export type LogLevel = "fatal" | "error" | "warn" | "info" | "debug";
|
|
2
2
|
export type LogMessage = string;
|
|
3
3
|
export interface LogDetails {
|
|
4
4
|
[key: string]: any;
|
|
5
5
|
}
|
|
6
6
|
export type LogHandler = (level: LogLevel, message: LogMessage, details?: LogDetails) => void;
|
|
7
7
|
export interface CreateLoggerOptions {
|
|
8
|
-
|
|
8
|
+
level?: LogLevel;
|
|
9
9
|
handler?: LogHandler;
|
|
10
10
|
}
|
|
11
11
|
export declare const loggerPrefix = "[Featurevisor]";
|
|
12
|
-
export declare const defaultLogLevels: LogLevel[];
|
|
13
12
|
export declare const defaultLogHandler: LogHandler;
|
|
14
13
|
export declare class Logger {
|
|
15
|
-
|
|
14
|
+
static allLevels: LogLevel[];
|
|
15
|
+
static defaultLevel: LogLevel;
|
|
16
|
+
private level;
|
|
16
17
|
private handle;
|
|
17
18
|
constructor(options: CreateLoggerOptions);
|
|
18
|
-
|
|
19
|
+
setLevel(level: LogLevel): void;
|
|
19
20
|
log(level: LogLevel, message: LogMessage, details?: LogDetails): void;
|
|
20
21
|
debug(message: LogMessage, details?: LogDetails): void;
|
|
21
22
|
info(message: LogMessage, details?: LogDetails): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function MurmurHashV3(key: any, seed: any): number;
|