@featurevisor/sdk 0.12.0 → 0.13.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/CHANGELOG.md +22 -0
- package/README.md +86 -12
- package/dist/index.js +1 -1
- package/dist/index.js.gz +0 -0
- package/dist/index.js.map +1 -1
- package/lib/client.d.ts +5 -0
- package/lib/client.js +20 -13
- package/lib/client.js.map +1 -1
- package/lib/conditions.js +7 -12
- package/lib/conditions.js.map +1 -1
- package/lib/createInstance.d.ts +8 -0
- package/lib/createInstance.js +50 -22
- package/lib/createInstance.js.map +1 -1
- package/lib/emitter.d.ts +12 -0
- package/lib/emitter.js +46 -0
- package/lib/emitter.js.map +1 -0
- package/package.json +5 -5
- package/src/client.ts +34 -13
- package/src/conditions.ts +8 -13
- package/src/createInstance.spec.ts +26 -0
- package/src/createInstance.ts +78 -22
- package/src/emitter.ts +53 -0
package/lib/conditions.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as semverLt from "semver/functions/lt";
|
|
3
|
-
import * as semverEq from "semver/functions/eq";
|
|
4
|
-
import * as semverNeq from "semver/functions/neq";
|
|
5
|
-
import * as semverGte from "semver/functions/gte";
|
|
6
|
-
import * as semverLte from "semver/functions/lte";
|
|
1
|
+
import { compareVersions } from "compare-versions";
|
|
7
2
|
export function conditionIsMatched(condition, attributes) {
|
|
8
3
|
var attribute = condition.attribute, operator = condition.operator, value = condition.value;
|
|
9
4
|
if (operator === "equals") {
|
|
@@ -38,22 +33,22 @@ export function conditionIsMatched(condition, attributes) {
|
|
|
38
33
|
return valueInAttributes.endsWith(value);
|
|
39
34
|
}
|
|
40
35
|
else if (operator === "semverEquals") {
|
|
41
|
-
return
|
|
36
|
+
return compareVersions(valueInAttributes, value) === 0;
|
|
42
37
|
}
|
|
43
38
|
else if (operator === "semverNotEquals") {
|
|
44
|
-
return
|
|
39
|
+
return compareVersions(valueInAttributes, value) !== 0;
|
|
45
40
|
}
|
|
46
41
|
else if (operator === "semverGreaterThan") {
|
|
47
|
-
return
|
|
42
|
+
return compareVersions(valueInAttributes, value) === 1;
|
|
48
43
|
}
|
|
49
44
|
else if (operator === "semverGreaterThanOrEquals") {
|
|
50
|
-
return
|
|
45
|
+
return compareVersions(valueInAttributes, value) >= 0;
|
|
51
46
|
}
|
|
52
47
|
else if (operator === "semverLessThan") {
|
|
53
|
-
return
|
|
48
|
+
return compareVersions(valueInAttributes, value) === -1;
|
|
54
49
|
}
|
|
55
50
|
else if (operator === "semverLessThanOrEquals") {
|
|
56
|
-
return
|
|
51
|
+
return compareVersions(valueInAttributes, value) <= 0;
|
|
57
52
|
}
|
|
58
53
|
}
|
|
59
54
|
else if (typeof attributes[attribute] === "number" && typeof value === "number") {
|
package/lib/conditions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditions.js","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conditions.js","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"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"}
|
package/lib/createInstance.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DatafileContent, Attributes } from "@featurevisor/types";
|
|
2
2
|
import { FeaturevisorSDK, ConfigureBucketValue, ActivationCallback } from "./client";
|
|
3
3
|
import { Logger } from "./logger";
|
|
4
|
+
import { Emitter } from "./emitter";
|
|
4
5
|
export type ReadyCallback = () => void;
|
|
5
6
|
export interface InstanceOptions {
|
|
6
7
|
datafile?: DatafileContent | string;
|
|
@@ -15,6 +16,7 @@ export interface InstanceOptions {
|
|
|
15
16
|
onRefresh?: () => void;
|
|
16
17
|
onUpdate?: () => void;
|
|
17
18
|
}
|
|
19
|
+
export type Event = "ready" | "refresh" | "update" | "activation";
|
|
18
20
|
export interface FeaturevisorInstance {
|
|
19
21
|
/**
|
|
20
22
|
* From FeaturevisorSDK
|
|
@@ -43,5 +45,11 @@ export interface FeaturevisorInstance {
|
|
|
43
45
|
refresh: () => void;
|
|
44
46
|
startRefreshing: () => void;
|
|
45
47
|
stopRefreshing: () => void;
|
|
48
|
+
addListener: Emitter["addListener"];
|
|
49
|
+
on: Emitter["addListener"];
|
|
50
|
+
removeListener: Emitter["removeListener"];
|
|
51
|
+
off: Emitter["removeListener"];
|
|
52
|
+
removeAllListeners: Emitter["removeAllListeners"];
|
|
53
|
+
isReady: () => boolean;
|
|
46
54
|
}
|
|
47
55
|
export declare function createInstance(options: InstanceOptions): FeaturevisorInstance;
|
package/lib/createInstance.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { FeaturevisorSDK } from "./client";
|
|
2
2
|
import { createLogger } from "./logger";
|
|
3
|
+
import { Emitter } from "./emitter";
|
|
3
4
|
function fetchDatafileContent(datafileUrl, options) {
|
|
4
5
|
if (options.handleDatafileFetch) {
|
|
5
6
|
return options.handleDatafileFetch(datafileUrl);
|
|
6
7
|
}
|
|
7
8
|
return fetch(datafileUrl).then(function (res) { return res.json(); });
|
|
8
9
|
}
|
|
9
|
-
function getInstanceFromSdk(sdk, options, logger) {
|
|
10
|
+
function getInstanceFromSdk(sdk, options, logger, emitter, statuses) {
|
|
10
11
|
var intervalId;
|
|
11
|
-
var
|
|
12
|
+
var on = emitter.addListener.bind(emitter);
|
|
13
|
+
var off = emitter.removeListener.bind(emitter);
|
|
12
14
|
var instance = {
|
|
13
15
|
// variation
|
|
14
16
|
getVariation: sdk.getVariation.bind(sdk),
|
|
@@ -32,15 +34,22 @@ function getInstanceFromSdk(sdk, options, logger) {
|
|
|
32
34
|
getVariableObject: sdk.getVariableObject.bind(sdk),
|
|
33
35
|
// additions
|
|
34
36
|
setLogLevels: logger.setLevels.bind(logger),
|
|
37
|
+
// emitter
|
|
38
|
+
on: on,
|
|
39
|
+
addListener: on,
|
|
40
|
+
off: off,
|
|
41
|
+
removeListener: off,
|
|
42
|
+
removeAllListeners: emitter.removeAllListeners.bind(emitter),
|
|
43
|
+
// refresh
|
|
35
44
|
refresh: function () {
|
|
36
45
|
logger.debug("refreshing datafile");
|
|
37
|
-
if (refreshInProgress) {
|
|
46
|
+
if (statuses.refreshInProgress) {
|
|
38
47
|
return logger.warn("refresh in progress, skipping");
|
|
39
48
|
}
|
|
40
49
|
if (!options.datafileUrl) {
|
|
41
50
|
return logger.error("cannot refresh since `datafileUrl` is not provided");
|
|
42
51
|
}
|
|
43
|
-
refreshInProgress = true;
|
|
52
|
+
statuses.refreshInProgress = true;
|
|
44
53
|
fetchDatafileContent(options.datafileUrl, options)
|
|
45
54
|
.then(function (datafile) {
|
|
46
55
|
var currentRevision = sdk.getRevision();
|
|
@@ -48,17 +57,15 @@ function getInstanceFromSdk(sdk, options, logger) {
|
|
|
48
57
|
var isNotSameRevision = currentRevision !== newRevision;
|
|
49
58
|
sdk.setDatafile(datafile);
|
|
50
59
|
logger.info("refreshed datafile");
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
emitter.emit("refresh");
|
|
61
|
+
if (isNotSameRevision) {
|
|
62
|
+
emitter.emit("update");
|
|
53
63
|
}
|
|
54
|
-
|
|
55
|
-
options.onUpdate();
|
|
56
|
-
}
|
|
57
|
-
refreshInProgress = false;
|
|
64
|
+
statuses.refreshInProgress = false;
|
|
58
65
|
})
|
|
59
66
|
.catch(function (e) {
|
|
60
67
|
logger.error("failed to refresh datafile", { error: e });
|
|
61
|
-
refreshInProgress = false;
|
|
68
|
+
statuses.refreshInProgress = false;
|
|
62
69
|
});
|
|
63
70
|
},
|
|
64
71
|
startRefreshing: function () {
|
|
@@ -81,6 +88,9 @@ function getInstanceFromSdk(sdk, options, logger) {
|
|
|
81
88
|
}
|
|
82
89
|
clearInterval(intervalId);
|
|
83
90
|
},
|
|
91
|
+
isReady: function () {
|
|
92
|
+
return statuses.ready;
|
|
93
|
+
},
|
|
84
94
|
};
|
|
85
95
|
if (options.datafileUrl && options.refreshInterval) {
|
|
86
96
|
instance.startRefreshing();
|
|
@@ -99,9 +109,26 @@ export function createInstance(options) {
|
|
|
99
109
|
throw new Error("Featurevisor SDK instance cannot be created without both `datafile` and `datafileUrl` options");
|
|
100
110
|
}
|
|
101
111
|
var logger = options.logger || createLogger();
|
|
112
|
+
var emitter = new Emitter();
|
|
113
|
+
var statuses = {
|
|
114
|
+
ready: false,
|
|
115
|
+
refreshInProgress: false,
|
|
116
|
+
};
|
|
102
117
|
if (!options.datafileUrl && options.refreshInterval) {
|
|
103
118
|
logger.warn("refreshing datafile requires `datafileUrl` option");
|
|
104
119
|
}
|
|
120
|
+
if (options.onReady) {
|
|
121
|
+
emitter.addListener("ready", options.onReady);
|
|
122
|
+
}
|
|
123
|
+
if (options.onActivation) {
|
|
124
|
+
emitter.addListener("activation", options.onActivation);
|
|
125
|
+
}
|
|
126
|
+
if (options.onRefresh) {
|
|
127
|
+
emitter.addListener("refresh", options.onRefresh);
|
|
128
|
+
}
|
|
129
|
+
if (options.onUpdate) {
|
|
130
|
+
emitter.addListener("update", options.onUpdate);
|
|
131
|
+
}
|
|
105
132
|
// datafile content is already provided
|
|
106
133
|
if (options.datafile) {
|
|
107
134
|
var sdk_1 = new FeaturevisorSDK({
|
|
@@ -109,15 +136,15 @@ export function createInstance(options) {
|
|
|
109
136
|
onActivation: options.onActivation,
|
|
110
137
|
configureBucketValue: options.configureBucketValue,
|
|
111
138
|
logger: logger,
|
|
139
|
+
emitter: emitter,
|
|
112
140
|
interceptAttributes: options.interceptAttributes,
|
|
141
|
+
fromInstance: true,
|
|
113
142
|
});
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
return getInstanceFromSdk(sdk_1, options, logger);
|
|
143
|
+
statuses.ready = true;
|
|
144
|
+
setTimeout(function () {
|
|
145
|
+
emitter.emit("ready");
|
|
146
|
+
}, 0);
|
|
147
|
+
return getInstanceFromSdk(sdk_1, options, logger, emitter, statuses);
|
|
121
148
|
}
|
|
122
149
|
// datafile has to be fetched
|
|
123
150
|
var sdk = new FeaturevisorSDK({
|
|
@@ -125,21 +152,22 @@ export function createInstance(options) {
|
|
|
125
152
|
onActivation: options.onActivation,
|
|
126
153
|
configureBucketValue: options.configureBucketValue,
|
|
127
154
|
logger: logger,
|
|
155
|
+
emitter: emitter,
|
|
128
156
|
interceptAttributes: options.interceptAttributes,
|
|
157
|
+
fromInstance: true,
|
|
129
158
|
});
|
|
130
159
|
if (options.datafileUrl) {
|
|
131
160
|
fetchDatafileContent(options.datafileUrl, options)
|
|
132
161
|
.then(function (datafile) {
|
|
133
162
|
sdk.setDatafile(datafile);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
163
|
+
statuses.ready = true;
|
|
164
|
+
emitter.emit("ready");
|
|
137
165
|
})
|
|
138
166
|
.catch(function (e) {
|
|
139
167
|
logger.error("failed to fetch datafile:");
|
|
140
168
|
console.error(e);
|
|
141
169
|
});
|
|
142
170
|
}
|
|
143
|
-
return getInstanceFromSdk(sdk, options, logger);
|
|
171
|
+
return getInstanceFromSdk(sdk, options, logger, emitter, statuses);
|
|
144
172
|
}
|
|
145
173
|
//# sourceMappingURL=createInstance.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createInstance.js","sourceRoot":"","sources":["../src/createInstance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4C,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,YAAY,EAAU,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"createInstance.js","sourceRoot":"","sources":["../src/createInstance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4C,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,YAAY,EAAU,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsEpC,SAAS,oBAAoB,CAAC,WAAW,EAAE,OAAwB;IACjE,IAAI,OAAO,CAAC,mBAAmB,EAAE;QAC/B,OAAO,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;KACjD;IAED,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAC,GAAG,IAAK,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC,CAAC;AACtD,CAAC;AAWD,SAAS,kBAAkB,CACzB,GAAoB,EACpB,OAAwB,EACxB,MAAc,EACd,OAAgB,EAChB,QAAkB;IAElB,IAAI,UAAU,CAAC;IAEf,IAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAM,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEjD,IAAM,QAAQ,GAAyB;QACrC,YAAY;QACZ,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QACxC,mBAAmB,EAAE,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QACtD,mBAAmB,EAAE,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QACtD,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;QACpD,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;QAEpD,WAAW;QACX,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QAC9C,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QAC9C,cAAc,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;QAC5C,cAAc,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;QAE5C,WAAW;QACX,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;QACtC,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;QACpD,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;QACpD,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;QAClD,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;QAClD,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;QAChD,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;QAElD,YAAY;QACZ,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QAE3C,UAAU;QACV,EAAE,EAAE,EAAE;QACN,WAAW,EAAE,EAAE;QACf,GAAG,EAAE,GAAG;QACR,cAAc,EAAE,GAAG;QACnB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;QAE5D,UAAU;QACV,OAAO;YACL,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAEpC,IAAI,QAAQ,CAAC,iBAAiB,EAAE;gBAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;aACrD;YAED,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;gBACxB,OAAO,MAAM,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;aAC3E;YAED,QAAQ,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAElC,oBAAoB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC;iBAC/C,IAAI,CAAC,UAAC,QAAQ;gBACb,IAAM,eAAe,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;gBAC1C,IAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC;gBACtC,IAAM,iBAAiB,GAAG,eAAe,KAAK,WAAW,CAAC;gBAE1D,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAElC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAExB,IAAI,iBAAiB,EAAE;oBACrB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;iBACxB;gBAED,QAAQ,CAAC,iBAAiB,GAAG,KAAK,CAAC;YACrC,CAAC,CAAC;iBACD,KAAK,CAAC,UAAC,CAAC;gBACP,MAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBACzD,QAAQ,CAAC,iBAAiB,GAAG,KAAK,CAAC;YACrC,CAAC,CAAC,CAAC;QACP,CAAC;QAED,eAAe;YACb,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;gBACxB,OAAO,MAAM,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;aACpF;YAED,IAAI,UAAU,EAAE;gBACd,OAAO,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;aACtD;YAED,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;gBAC5B,OAAO,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;aAC5D;YAED,UAAU,GAAG,WAAW,CAAC;gBACvB,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC,EAAE,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,cAAc;YACZ,IAAI,CAAC,UAAU,EAAE;gBACf,OAAO,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;aACtD;YAED,aAAa,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO;YACL,OAAO,QAAQ,CAAC,KAAK,CAAC;QACxB,CAAC;KACF,CAAC;IAEF,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE;QAClD,QAAQ,CAAC,eAAe,EAAE,CAAC;KAC5B;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,IAAM,aAAa,GAAoB;IACrC,aAAa,EAAE,GAAG;IAClB,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,EAAE;IACd,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;CACb,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,OAAwB;IACrD,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;QAC7C,MAAM,IAAI,KAAK,CACb,+FAA+F,CAChG,CAAC;KACH;IAED,IAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,CAAC;IAChD,IAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,IAAM,QAAQ,GAAa;QACzB,KAAK,EAAE,KAAK;QACZ,iBAAiB,EAAE,KAAK;KACzB,CAAC;IAEF,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE;QACnD,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;KAClE;IAED,IAAI,OAAO,CAAC,OAAO,EAAE;QACnB,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KAC/C;IAED,IAAI,OAAO,CAAC,YAAY,EAAE;QACxB,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;KACzD;IAED,IAAI,OAAO,CAAC,SAAS,EAAE;QACrB,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;KACnD;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE;QACpB,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;KACjD;IAED,uCAAuC;IACvC,IAAI,OAAO,CAAC,QAAQ,EAAE;QACpB,IAAM,KAAG,GAAG,IAAI,eAAe,CAAC;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;YAClD,MAAM,QAAA;YACN,OAAO,SAAA;YACP,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;YAChD,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QAEH,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;QACtB,UAAU,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,kBAAkB,CAAC,KAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;KACpE;IAED,6BAA6B;IAC7B,IAAM,GAAG,GAAG,IAAI,eAAe,CAAC;QAC9B,QAAQ,EAAE,aAAa;QACvB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,MAAM,QAAA;QACN,OAAO,SAAA;QACP,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;QAChD,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,WAAW,EAAE;QACvB,oBAAoB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC;aAC/C,IAAI,CAAC,UAAC,QAAQ;YACb,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAE1B,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,CAAC;YACP,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;KACN;IAED,OAAO,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AACrE,CAAC"}
|
package/lib/emitter.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type EventName = "ready" | "refresh" | "update" | "activation";
|
|
2
|
+
export interface Listeners {
|
|
3
|
+
[key: string]: Function[];
|
|
4
|
+
}
|
|
5
|
+
export declare class Emitter {
|
|
6
|
+
private _listeners;
|
|
7
|
+
constructor();
|
|
8
|
+
addListener(eventName: EventName, fn: Function): void;
|
|
9
|
+
removeListener(eventName: EventName, fn: Function): void;
|
|
10
|
+
removeAllListeners(eventName?: EventName): void;
|
|
11
|
+
emit(eventName: EventName, ...args: any[]): void;
|
|
12
|
+
}
|
package/lib/emitter.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
var Emitter = /** @class */ (function () {
|
|
2
|
+
function Emitter() {
|
|
3
|
+
this._listeners = {};
|
|
4
|
+
}
|
|
5
|
+
Emitter.prototype.addListener = function (eventName, fn) {
|
|
6
|
+
if (typeof this._listeners[eventName] === "undefined") {
|
|
7
|
+
this._listeners[eventName] = [];
|
|
8
|
+
}
|
|
9
|
+
this._listeners[eventName].push(fn);
|
|
10
|
+
};
|
|
11
|
+
Emitter.prototype.removeListener = function (eventName, fn) {
|
|
12
|
+
if (typeof this._listeners[eventName] === "undefined") {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
var index = this._listeners[eventName].indexOf(fn);
|
|
16
|
+
if (index !== -1) {
|
|
17
|
+
this._listeners[eventName].splice(index, 1);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
Emitter.prototype.removeAllListeners = function (eventName) {
|
|
21
|
+
var _this = this;
|
|
22
|
+
if (eventName) {
|
|
23
|
+
this._listeners[eventName] = [];
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
Object.keys(this._listeners).forEach(function (key) {
|
|
27
|
+
_this._listeners[key] = [];
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
Emitter.prototype.emit = function (eventName) {
|
|
32
|
+
var args = [];
|
|
33
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
34
|
+
args[_i - 1] = arguments[_i];
|
|
35
|
+
}
|
|
36
|
+
if (typeof this._listeners[eventName] === "undefined") {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this._listeners[eventName].forEach(function (fn) {
|
|
40
|
+
fn.apply(void 0, args);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
return Emitter;
|
|
44
|
+
}());
|
|
45
|
+
export { Emitter };
|
|
46
|
+
//# sourceMappingURL=emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAMA;IAGE;QACE,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACvB,CAAC;IAEM,6BAAW,GAAlB,UAAmB,SAAoB,EAAE,EAAY;QACnD,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,WAAW,EAAE;YACrD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;SACjC;QAED,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAEM,gCAAc,GAArB,UAAsB,SAAoB,EAAE,EAAY;QACtD,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,WAAW,EAAE;YACrD,OAAO;SACR;QAED,IAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAErD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;SAC7C;IACH,CAAC;IAEM,oCAAkB,GAAzB,UAA0B,SAAqB;QAA/C,iBAQC;QAPC,IAAI,SAAS,EAAE;YACb,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;SACjC;aAAM;YACL,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,UAAC,GAAG;gBACvC,KAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5B,CAAC,CAAC,CAAC;SACJ;IACH,CAAC;IAEM,sBAAI,GAAX,UAAY,SAAoB;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QAC9C,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,WAAW,EAAE;YACrD,OAAO;SACR;QAED,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,UAAC,EAAE;YACpC,EAAE,eAAI,IAAI,EAAE;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACH,cAAC;AAAD,CAAC,AA9CD,IA8CC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@featurevisor/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Featurevisor SDK for Node.js and the browser",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
},
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@featurevisor/types": "^0.
|
|
46
|
-
"
|
|
47
|
-
"
|
|
45
|
+
"@featurevisor/types": "^0.13.0",
|
|
46
|
+
"compare-versions": "^6.0.0-rc.1",
|
|
47
|
+
"murmurhash": "^2.0.1"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "84bc69876c7b5ea080d0dff53b305bd47b3d43e1"
|
|
50
50
|
}
|
package/src/client.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from "./feature";
|
|
20
20
|
import { getBucketedNumber } from "./bucket";
|
|
21
21
|
import { createLogger, Logger } from "./logger";
|
|
22
|
+
import { Emitter } from "./emitter";
|
|
22
23
|
|
|
23
24
|
export type ActivationCallback = (
|
|
24
25
|
featureName: string,
|
|
@@ -34,7 +35,9 @@ export interface SdkOptions {
|
|
|
34
35
|
onActivation?: ActivationCallback; // @TODO: move it to FeaturevisorInstance in next breaking semver
|
|
35
36
|
configureBucketValue?: ConfigureBucketValue;
|
|
36
37
|
logger?: Logger; // @TODO: keep it in FeaturevisorInstance only in next breaking semver
|
|
38
|
+
emitter?: Emitter; // @TODO: keep it in FeaturevisorInstance only in next breaking semver
|
|
37
39
|
interceptAttributes?: (attributes: Attributes) => Attributes; // @TODO: move it to FeaturevisorInstance in next breaking semver
|
|
40
|
+
fromInstance?: boolean;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
type FieldType = VariationType | VariableType;
|
|
@@ -71,7 +74,9 @@ export class FeaturevisorSDK {
|
|
|
71
74
|
private datafileReader: DatafileReader;
|
|
72
75
|
private configureBucketValue?: ConfigureBucketValue;
|
|
73
76
|
private logger: Logger;
|
|
77
|
+
private emitter?: Emitter;
|
|
74
78
|
private interceptAttributes?: (attributes: Attributes) => Attributes;
|
|
79
|
+
private fromInstance: boolean;
|
|
75
80
|
|
|
76
81
|
constructor(options: SdkOptions) {
|
|
77
82
|
if (options.onActivation) {
|
|
@@ -88,7 +93,13 @@ export class FeaturevisorSDK {
|
|
|
88
93
|
this.interceptAttributes = options.interceptAttributes;
|
|
89
94
|
}
|
|
90
95
|
|
|
96
|
+
if (options.emitter) {
|
|
97
|
+
this.emitter = options.emitter;
|
|
98
|
+
}
|
|
99
|
+
|
|
91
100
|
this.setDatafile(options.datafile);
|
|
101
|
+
|
|
102
|
+
this.fromInstance = options.fromInstance || false;
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
setDatafile(datafile: DatafileContent | string) {
|
|
@@ -243,23 +254,33 @@ export class FeaturevisorSDK {
|
|
|
243
254
|
return undefined;
|
|
244
255
|
}
|
|
245
256
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
const finalAttributes = this.interceptAttributes
|
|
258
|
+
? this.interceptAttributes(attributes)
|
|
259
|
+
: attributes;
|
|
260
|
+
|
|
261
|
+
const captureAttributes: Attributes = {};
|
|
250
262
|
|
|
251
|
-
|
|
263
|
+
const attributesForCapturing = this.datafileReader
|
|
264
|
+
.getAllAttributes()
|
|
265
|
+
.filter((a) => a.capture === true);
|
|
252
266
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
.
|
|
267
|
+
attributesForCapturing.forEach((a) => {
|
|
268
|
+
if (typeof finalAttributes[a.key] !== "undefined") {
|
|
269
|
+
captureAttributes[a.key] = attributes[a.key];
|
|
270
|
+
}
|
|
271
|
+
});
|
|
256
272
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
273
|
+
if (this.emitter) {
|
|
274
|
+
this.emitter.emit(
|
|
275
|
+
"activation",
|
|
276
|
+
featureKey,
|
|
277
|
+
variationValue,
|
|
278
|
+
finalAttributes,
|
|
279
|
+
captureAttributes,
|
|
280
|
+
);
|
|
281
|
+
}
|
|
262
282
|
|
|
283
|
+
if (this.fromInstance && this.onActivation) {
|
|
263
284
|
this.onActivation(featureKey, variationValue, finalAttributes, captureAttributes);
|
|
264
285
|
}
|
|
265
286
|
|
package/src/conditions.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compareVersions } from "compare-versions";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import * as semverLt from "semver/functions/lt";
|
|
5
|
-
import * as semverEq from "semver/functions/eq";
|
|
6
|
-
import * as semverNeq from "semver/functions/neq";
|
|
7
|
-
import * as semverGte from "semver/functions/gte";
|
|
8
|
-
import * as semverLte from "semver/functions/lte";
|
|
3
|
+
import { Attributes, Condition, PlainCondition } from "@featurevisor/types";
|
|
9
4
|
|
|
10
5
|
export function conditionIsMatched(condition: PlainCondition, attributes: Attributes): boolean {
|
|
11
6
|
const { attribute, operator, value } = condition;
|
|
@@ -36,17 +31,17 @@ export function conditionIsMatched(condition: PlainCondition, attributes: Attrib
|
|
|
36
31
|
} else if (operator === "endsWith") {
|
|
37
32
|
return valueInAttributes.endsWith(value);
|
|
38
33
|
} else if (operator === "semverEquals") {
|
|
39
|
-
return
|
|
34
|
+
return compareVersions(valueInAttributes, value) === 0;
|
|
40
35
|
} else if (operator === "semverNotEquals") {
|
|
41
|
-
return
|
|
36
|
+
return compareVersions(valueInAttributes, value) !== 0;
|
|
42
37
|
} else if (operator === "semverGreaterThan") {
|
|
43
|
-
return
|
|
38
|
+
return compareVersions(valueInAttributes, value) === 1;
|
|
44
39
|
} else if (operator === "semverGreaterThanOrEquals") {
|
|
45
|
-
return
|
|
40
|
+
return compareVersions(valueInAttributes, value) >= 0;
|
|
46
41
|
} else if (operator === "semverLessThan") {
|
|
47
|
-
return
|
|
42
|
+
return compareVersions(valueInAttributes, value) === -1;
|
|
48
43
|
} else if (operator === "semverLessThanOrEquals") {
|
|
49
|
-
return
|
|
44
|
+
return compareVersions(valueInAttributes, value) <= 0;
|
|
50
45
|
}
|
|
51
46
|
} else if (typeof attributes[attribute] === "number" && typeof value === "number") {
|
|
52
47
|
// numeric
|
|
@@ -21,6 +21,28 @@ describe("sdk: createInstance", function () {
|
|
|
21
21
|
expect(typeof sdk.getVariation).toEqual("function");
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
it("should trigger onReady event once", function (done) {
|
|
25
|
+
let readyCount = 0;
|
|
26
|
+
|
|
27
|
+
const sdk = createInstance({
|
|
28
|
+
datafile: {
|
|
29
|
+
schemaVersion: "1",
|
|
30
|
+
revision: "1.0",
|
|
31
|
+
features: [],
|
|
32
|
+
attributes: [],
|
|
33
|
+
segments: [],
|
|
34
|
+
},
|
|
35
|
+
onReady: () => {
|
|
36
|
+
readyCount += 1;
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
expect(readyCount).toEqual(1);
|
|
42
|
+
done();
|
|
43
|
+
}, 0);
|
|
44
|
+
});
|
|
45
|
+
|
|
24
46
|
it("should intercept attributes", function () {
|
|
25
47
|
let intercepted = false;
|
|
26
48
|
|
|
@@ -126,10 +148,14 @@ describe("sdk: createInstance", function () {
|
|
|
126
148
|
},
|
|
127
149
|
});
|
|
128
150
|
|
|
151
|
+
expect(sdk.isReady()).toEqual(false);
|
|
152
|
+
|
|
129
153
|
setTimeout(function () {
|
|
130
154
|
expect(refreshed).toEqual(true);
|
|
131
155
|
expect(updated).toEqual(true);
|
|
132
156
|
|
|
157
|
+
expect(sdk.isReady()).toEqual(true);
|
|
158
|
+
|
|
133
159
|
sdk.stopRefreshing();
|
|
134
160
|
|
|
135
161
|
done();
|