@statsig/client-core 0.0.1-beta.3 → 0.0.1-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/EventLogger.d.ts +5 -0
- package/src/EventLogger.js +16 -3
- package/src/NetworkCore.d.ts +4 -1
- package/src/NetworkCore.js +26 -20
- package/src/StatsigEvent.d.ts +2 -3
- package/src/StatsigEvent.js +15 -8
- package/src/StatsigMetadata.js +1 -1
- package/src/StatsigTypes.d.ts +9 -4
- package/src/StatsigTypes.js +6 -6
package/package.json
CHANGED
package/src/EventLogger.d.ts
CHANGED
|
@@ -13,11 +13,16 @@ export declare class EventLogger {
|
|
|
13
13
|
private _lastExposureMap;
|
|
14
14
|
private _maxQueueSize;
|
|
15
15
|
private _failedLogs;
|
|
16
|
+
private _hasFiredQuickFlush;
|
|
16
17
|
constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon | null);
|
|
17
18
|
enqueue(event: StatsigEventInternal): void;
|
|
18
19
|
reset(): void;
|
|
19
20
|
onVisibilityChanged(visibility: Visibility): void;
|
|
20
21
|
shutdown(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* We 'Quick Flush' following the very first enqueued event
|
|
24
|
+
*/
|
|
25
|
+
private _quickFlushIfNeeded;
|
|
21
26
|
private _shouldLogEvent;
|
|
22
27
|
private _flushAndForget;
|
|
23
28
|
private _flush;
|
package/src/EventLogger.js
CHANGED
|
@@ -70,6 +70,7 @@ var EventLogger = /** @class */ (function () {
|
|
|
70
70
|
this._options = _options;
|
|
71
71
|
this._queue = [];
|
|
72
72
|
this._lastExposureMap = {};
|
|
73
|
+
this._hasFiredQuickFlush = false;
|
|
73
74
|
this._maxQueueSize = (_a = _options === null || _options === void 0 ? void 0 : _options.loggingBufferMaxSize) !== null && _a !== void 0 ? _a : DEFAULT_QUEUE_SIZE;
|
|
74
75
|
var flushInterval = (_b = _options === null || _options === void 0 ? void 0 : _options.loggingIntervalMs) !== null && _b !== void 0 ? _b : DEFAULT_FLUSH_INTERVAL_MS;
|
|
75
76
|
this._flushTimer = setInterval(function () { return _this._flushAndForget(); }, flushInterval);
|
|
@@ -87,6 +88,7 @@ var EventLogger = /** @class */ (function () {
|
|
|
87
88
|
}
|
|
88
89
|
var _a = StatsigMetadata_1.StatsigMetadataProvider.get(), sdkType = _a.sdkType, sdkVersion = _a.sdkVersion;
|
|
89
90
|
this._queue.push(__assign(__assign({}, event), { statsigMetadata: { sdkType: sdkType, sdkVersion: sdkVersion } }));
|
|
91
|
+
this._quickFlushIfNeeded();
|
|
90
92
|
if (this._queue.length > this._maxQueueSize) {
|
|
91
93
|
this._flushAndForget();
|
|
92
94
|
}
|
|
@@ -116,6 +118,17 @@ var EventLogger = /** @class */ (function () {
|
|
|
116
118
|
});
|
|
117
119
|
});
|
|
118
120
|
};
|
|
121
|
+
/**
|
|
122
|
+
* We 'Quick Flush' following the very first enqueued event
|
|
123
|
+
*/
|
|
124
|
+
EventLogger.prototype._quickFlushIfNeeded = function () {
|
|
125
|
+
var _this = this;
|
|
126
|
+
if (this._hasFiredQuickFlush) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this._hasFiredQuickFlush = true;
|
|
130
|
+
setTimeout(function () { return _this._flushAndForget(); }, 200);
|
|
131
|
+
};
|
|
119
132
|
EventLogger.prototype._shouldLogEvent = function (event) {
|
|
120
133
|
var _a, _b, _c, _d;
|
|
121
134
|
if (!(0, StatsigEvent_1.isExposureEvent)(event)) {
|
|
@@ -213,9 +226,9 @@ var EventLogger = /** @class */ (function () {
|
|
|
213
226
|
},
|
|
214
227
|
url: "".concat(api, "/rgstr"),
|
|
215
228
|
retries: 3,
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
229
|
+
params: {
|
|
230
|
+
// ec = Event Count
|
|
231
|
+
ec: String(events.length),
|
|
219
232
|
},
|
|
220
233
|
})];
|
|
221
234
|
case 1:
|
package/src/NetworkCore.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { StatsigClientEmitEventFunc } from './StatsigClientBase';
|
|
1
2
|
import { StatsigOptionsCommon } from './StatsigOptionsCommon';
|
|
2
3
|
type RequestArgs = {
|
|
3
4
|
sdkKey: string;
|
|
4
5
|
url: string;
|
|
5
6
|
timeoutMs?: number;
|
|
6
7
|
retries?: number;
|
|
8
|
+
params?: Record<string, string>;
|
|
7
9
|
headers?: Record<string, string>;
|
|
8
10
|
};
|
|
9
11
|
type RequestArgsWithData = RequestArgs & {
|
|
@@ -11,8 +13,9 @@ type RequestArgsWithData = RequestArgs & {
|
|
|
11
13
|
};
|
|
12
14
|
export declare class NetworkCore {
|
|
13
15
|
private _options;
|
|
16
|
+
private _emitter?;
|
|
14
17
|
private readonly _timeout;
|
|
15
|
-
constructor(_options: StatsigOptionsCommon | null);
|
|
18
|
+
constructor(_options: StatsigOptionsCommon | null, _emitter?: StatsigClientEmitEventFunc | undefined);
|
|
16
19
|
post(args: RequestArgsWithData): Promise<string | null>;
|
|
17
20
|
get(args: RequestArgs): Promise<string | null>;
|
|
18
21
|
beacon(args: RequestArgsWithData): boolean;
|
package/src/NetworkCore.js
CHANGED
|
@@ -79,9 +79,10 @@ var NetworkError = /** @class */ (function (_super) {
|
|
|
79
79
|
return NetworkError;
|
|
80
80
|
}(Error));
|
|
81
81
|
var NetworkCore = /** @class */ (function () {
|
|
82
|
-
function NetworkCore(_options) {
|
|
82
|
+
function NetworkCore(_options, _emitter) {
|
|
83
83
|
var _a;
|
|
84
84
|
this._options = _options;
|
|
85
|
+
this._emitter = _emitter;
|
|
85
86
|
this._timeout = (_a = _options === null || _options === void 0 ? void 0 : _options.networkTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
|
|
86
87
|
}
|
|
87
88
|
NetworkCore.prototype.post = function (args) {
|
|
@@ -114,35 +115,33 @@ var NetworkCore = /** @class */ (function () {
|
|
|
114
115
|
return navigator.sendBeacon(url, JSON.stringify(args.data));
|
|
115
116
|
};
|
|
116
117
|
NetworkCore.prototype._sendRequest = function (args) {
|
|
118
|
+
var _a;
|
|
117
119
|
return __awaiter(this, void 0, void 0, function () {
|
|
118
120
|
var method, body, retries, controller, handle, response, fullUrl, text, error_1, errorMessage;
|
|
119
121
|
var _this = this;
|
|
120
|
-
return __generator(this, function (
|
|
121
|
-
switch (
|
|
122
|
+
return __generator(this, function (_b) {
|
|
123
|
+
switch (_b.label) {
|
|
122
124
|
case 0:
|
|
123
125
|
method = args.method, body = args.body, retries = args.retries;
|
|
124
126
|
controller = new AbortController();
|
|
125
127
|
handle = setTimeout(function () { return controller.abort("Timeout of ".concat(_this._timeout, "ms expired.")); }, this._timeout);
|
|
126
128
|
response = null;
|
|
127
|
-
|
|
129
|
+
_b.label = 1;
|
|
128
130
|
case 1:
|
|
129
|
-
|
|
131
|
+
_b.trys.push([1, 4, , 5]);
|
|
130
132
|
fullUrl = this._getPopulatedURL(args);
|
|
131
133
|
return [4 /*yield*/, fetch(fullUrl, {
|
|
132
134
|
method: method,
|
|
133
135
|
body: body,
|
|
134
|
-
headers: __assign({
|
|
135
|
-
// Must set this content type to bypass cors
|
|
136
|
-
// can override via headers if necessary (recommended for logevent)
|
|
137
|
-
'Content-Type': 'text/plain' }, args.headers),
|
|
136
|
+
headers: __assign({}, args.headers),
|
|
138
137
|
signal: controller.signal,
|
|
139
138
|
})];
|
|
140
139
|
case 2:
|
|
141
|
-
response =
|
|
140
|
+
response = _b.sent();
|
|
142
141
|
clearTimeout(handle);
|
|
143
142
|
return [4 /*yield*/, response.text()];
|
|
144
143
|
case 3:
|
|
145
|
-
text =
|
|
144
|
+
text = _b.sent();
|
|
146
145
|
if (!response.ok) {
|
|
147
146
|
throw new NetworkError('Fetch Failure', text);
|
|
148
147
|
}
|
|
@@ -152,7 +151,7 @@ var NetworkCore = /** @class */ (function () {
|
|
|
152
151
|
});
|
|
153
152
|
return [2 /*return*/, text];
|
|
154
153
|
case 4:
|
|
155
|
-
error_1 =
|
|
154
|
+
error_1 = _b.sent();
|
|
156
155
|
errorMessage = _getErrorMessage(controller, error_1);
|
|
157
156
|
Diagnostics_1.Diagnostics.mark('_sendRequest:error', {
|
|
158
157
|
error: errorMessage,
|
|
@@ -160,6 +159,7 @@ var NetworkCore = /** @class */ (function () {
|
|
|
160
159
|
contentLength: response === null || response === void 0 ? void 0 : response.headers.get('content-length'),
|
|
161
160
|
});
|
|
162
161
|
if (!retries || retries <= 0) {
|
|
162
|
+
(_a = this._emitter) === null || _a === void 0 ? void 0 : _a.call(this, { event: 'error', error: error_1 });
|
|
163
163
|
Log_1.Log.error('A networking error occured.', errorMessage);
|
|
164
164
|
return [2 /*return*/, null];
|
|
165
165
|
}
|
|
@@ -170,14 +170,20 @@ var NetworkCore = /** @class */ (function () {
|
|
|
170
170
|
});
|
|
171
171
|
};
|
|
172
172
|
NetworkCore.prototype._getPopulatedURL = function (args) {
|
|
173
|
-
var
|
|
174
|
-
var
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
173
|
+
var metadata = StatsigMetadata_1.StatsigMetadataProvider.get();
|
|
174
|
+
var url = new URL(args.url);
|
|
175
|
+
url.searchParams.append('k', args.sdkKey);
|
|
176
|
+
url.searchParams.append('st', metadata.sdkType);
|
|
177
|
+
url.searchParams.append('sv', metadata.sdkVersion);
|
|
178
|
+
url.searchParams.append('t', String(Date.now()));
|
|
179
|
+
url.searchParams.append('sid', SessionID_1.SessionID.get(args.sdkKey));
|
|
180
|
+
if (args.params) {
|
|
181
|
+
Object.entries(args.params).forEach(function (_a) {
|
|
182
|
+
var k = _a[0], v = _a[1];
|
|
183
|
+
url.searchParams.append(k, v);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return url.toString();
|
|
181
187
|
};
|
|
182
188
|
return NetworkCore;
|
|
183
189
|
}());
|
package/src/StatsigEvent.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DynamicConfig, FeatureGate } from './StatsigTypes';
|
|
1
|
+
import { DynamicConfig, EvaluationDetails, FeatureGate } from './StatsigTypes';
|
|
3
2
|
import { StatsigUser } from './StatsigUser';
|
|
4
3
|
export type SecondaryExposure = {
|
|
5
4
|
gate: string;
|
|
@@ -27,5 +26,5 @@ export declare function createLayerParameterExposure(user: StatsigUser, layerNam
|
|
|
27
26
|
undelegated_secondary_exposures?: SecondaryExposure[];
|
|
28
27
|
secondary_exposures: SecondaryExposure[];
|
|
29
28
|
allocated_experiment_name: string;
|
|
30
|
-
|
|
29
|
+
details: EvaluationDetails;
|
|
31
30
|
}): StatsigEventInternal;
|
package/src/StatsigEvent.js
CHANGED
|
@@ -4,12 +4,12 @@ exports.createLayerParameterExposure = exports.createConfigExposure = exports.cr
|
|
|
4
4
|
var CONFIG_EXPOSURE_NAME = 'statsig::config_exposure';
|
|
5
5
|
var GATE_EXPOSURE_NAME = 'statsig::gate_exposure';
|
|
6
6
|
var LAYER_EXPOSURE_NAME = 'statsig::layer_exposure';
|
|
7
|
-
function createExposure(eventName, user, metadata, secondaryExposures) {
|
|
7
|
+
function createExposure(eventName, user, details, metadata, secondaryExposures) {
|
|
8
8
|
return {
|
|
9
9
|
eventName: eventName,
|
|
10
10
|
user: user,
|
|
11
11
|
value: null,
|
|
12
|
-
metadata: metadata,
|
|
12
|
+
metadata: _addEvaluationDetailsToMetadata(details, metadata),
|
|
13
13
|
secondaryExposures: secondaryExposures,
|
|
14
14
|
time: Date.now(),
|
|
15
15
|
};
|
|
@@ -20,19 +20,17 @@ function isExposureEvent(_a) {
|
|
|
20
20
|
}
|
|
21
21
|
exports.isExposureEvent = isExposureEvent;
|
|
22
22
|
function createGateExposure(user, gate, secondaryExposures) {
|
|
23
|
-
return createExposure(GATE_EXPOSURE_NAME, user, {
|
|
23
|
+
return createExposure(GATE_EXPOSURE_NAME, user, gate.details, {
|
|
24
24
|
gate: gate.name,
|
|
25
25
|
gateValue: String(gate.value),
|
|
26
26
|
ruleID: gate.ruleID,
|
|
27
|
-
reason: gate.source,
|
|
28
27
|
}, secondaryExposures !== null && secondaryExposures !== void 0 ? secondaryExposures : []);
|
|
29
28
|
}
|
|
30
29
|
exports.createGateExposure = createGateExposure;
|
|
31
30
|
function createConfigExposure(user, config, secondaryExposures) {
|
|
32
|
-
return createExposure(CONFIG_EXPOSURE_NAME, user, {
|
|
31
|
+
return createExposure(CONFIG_EXPOSURE_NAME, user, config.details, {
|
|
33
32
|
config: config.name,
|
|
34
33
|
ruleID: config.ruleID,
|
|
35
|
-
reason: config.source,
|
|
36
34
|
}, secondaryExposures !== null && secondaryExposures !== void 0 ? secondaryExposures : []);
|
|
37
35
|
}
|
|
38
36
|
exports.createConfigExposure = createConfigExposure;
|
|
@@ -45,13 +43,22 @@ function createLayerParameterExposure(user, layerName, parameterName, spec) {
|
|
|
45
43
|
allocatedExperiment = spec.allocated_experiment_name;
|
|
46
44
|
secondaryExposures = spec.secondary_exposures;
|
|
47
45
|
}
|
|
48
|
-
return createExposure(LAYER_EXPOSURE_NAME, user, {
|
|
46
|
+
return createExposure(LAYER_EXPOSURE_NAME, user, spec.details, {
|
|
49
47
|
config: layerName,
|
|
50
48
|
parameterName: parameterName,
|
|
51
49
|
ruleID: spec.rule_id,
|
|
52
50
|
allocatedExperiment: allocatedExperiment,
|
|
53
51
|
isExplicitParameter: String(isExplicit),
|
|
54
|
-
reason: spec.source,
|
|
55
52
|
}, secondaryExposures);
|
|
56
53
|
}
|
|
57
54
|
exports.createLayerParameterExposure = createLayerParameterExposure;
|
|
55
|
+
function _addEvaluationDetailsToMetadata(details, metadata) {
|
|
56
|
+
metadata['reason'] = details.reason;
|
|
57
|
+
if (details.lcut) {
|
|
58
|
+
metadata['lcut'] = String(details.lcut);
|
|
59
|
+
}
|
|
60
|
+
if (details.receivedAt) {
|
|
61
|
+
metadata['receivedAt'] = String(details.receivedAt);
|
|
62
|
+
}
|
|
63
|
+
return metadata;
|
|
64
|
+
}
|
package/src/StatsigMetadata.js
CHANGED
|
@@ -12,7 +12,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.StatsigMetadataProvider = void 0;
|
|
15
|
-
var SDK_VERSION = '0.0.1-beta.
|
|
15
|
+
var SDK_VERSION = '0.0.1-beta.5';
|
|
16
16
|
var metadata = {
|
|
17
17
|
sdkVersion: SDK_VERSION,
|
|
18
18
|
sdkType: 'js-mono', // js-mono is overwritten by Precomp and OnDevice clients
|
package/src/StatsigTypes.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
export type Flatten<T> = {
|
|
2
2
|
[K in keyof T]: T[K];
|
|
3
3
|
} & {};
|
|
4
|
+
export type EvaluationDetails = {
|
|
5
|
+
reason: string;
|
|
6
|
+
lcut?: number;
|
|
7
|
+
receivedAt?: number;
|
|
8
|
+
};
|
|
4
9
|
type EvaluatedSpec = {
|
|
5
10
|
readonly name: string;
|
|
6
11
|
readonly ruleID: string;
|
|
7
|
-
readonly
|
|
12
|
+
readonly details: EvaluationDetails;
|
|
8
13
|
};
|
|
9
14
|
export type FeatureGate = EvaluatedSpec & {
|
|
10
15
|
readonly value: boolean;
|
|
@@ -16,7 +21,7 @@ export type Experiment = DynamicConfig;
|
|
|
16
21
|
export type Layer = EvaluatedSpec & {
|
|
17
22
|
readonly getValue: (parameterName: string) => unknown;
|
|
18
23
|
};
|
|
19
|
-
export declare function makeFeatureGate(name: string,
|
|
20
|
-
export declare function makeDynamicConfig(name: string,
|
|
21
|
-
export declare function makeLayer(name: string,
|
|
24
|
+
export declare function makeFeatureGate(name: string, details: EvaluationDetails, ruleID?: string, value?: boolean): FeatureGate;
|
|
25
|
+
export declare function makeDynamicConfig(name: string, details: EvaluationDetails, ruleID?: string, value?: Record<string, unknown>): DynamicConfig;
|
|
26
|
+
export declare function makeLayer(name: string, details: EvaluationDetails, ruleID?: string, getValue?: (param: string) => unknown): Layer;
|
|
22
27
|
export {};
|
package/src/StatsigTypes.js
CHANGED
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeLayer = exports.makeDynamicConfig = exports.makeFeatureGate = void 0;
|
|
4
4
|
var DEFAULT_RULE = 'default';
|
|
5
|
-
function makeFeatureGate(name,
|
|
5
|
+
function makeFeatureGate(name, details, ruleID, value) {
|
|
6
6
|
return {
|
|
7
7
|
name: name,
|
|
8
|
-
|
|
8
|
+
details: details,
|
|
9
9
|
ruleID: ruleID !== null && ruleID !== void 0 ? ruleID : DEFAULT_RULE,
|
|
10
10
|
value: value === true,
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
exports.makeFeatureGate = makeFeatureGate;
|
|
14
|
-
function makeDynamicConfig(name,
|
|
14
|
+
function makeDynamicConfig(name, details, ruleID, value) {
|
|
15
15
|
return {
|
|
16
16
|
name: name,
|
|
17
|
-
|
|
17
|
+
details: details,
|
|
18
18
|
ruleID: ruleID !== null && ruleID !== void 0 ? ruleID : DEFAULT_RULE,
|
|
19
19
|
value: value !== null && value !== void 0 ? value : {},
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
exports.makeDynamicConfig = makeDynamicConfig;
|
|
23
|
-
function makeLayer(name,
|
|
23
|
+
function makeLayer(name, details, ruleID, getValue) {
|
|
24
24
|
return {
|
|
25
25
|
name: name,
|
|
26
|
-
|
|
26
|
+
details: details,
|
|
27
27
|
getValue: getValue !== null && getValue !== void 0 ? getValue : (function () { return undefined; }),
|
|
28
28
|
ruleID: ruleID !== null && ruleID !== void 0 ? ruleID : DEFAULT_RULE,
|
|
29
29
|
};
|