@statsig/client-core 0.0.1-beta.1 → 0.0.1-beta.10
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 +4 -1
- package/package.json +1 -1
- package/src/ClientInterfaces.d.ts +6 -2
- package/src/DataAdapterCore.d.ts +33 -0
- package/src/DataAdapterCore.js +241 -0
- package/src/ErrorBoundary.d.ts +1 -0
- package/src/ErrorBoundary.js +3 -0
- package/src/EventLogger.d.ts +7 -1
- package/src/EventLogger.js +55 -29
- package/src/Monitoring.d.ts +1 -2
- package/src/Monitoring.js +66 -13
- package/src/NetworkCore.d.ts +13 -4
- package/src/NetworkCore.js +68 -60
- package/src/StableID.js +1 -1
- package/src/StatsigClientBase.d.ts +10 -17
- package/src/StatsigClientBase.js +19 -219
- package/src/StatsigClientEventEmitter.d.ts +26 -4
- package/src/StatsigDataAdapter.d.ts +43 -0
- package/src/StatsigDataAdapter.js +4 -0
- package/src/StatsigEvent.d.ts +2 -3
- package/src/StatsigEvent.js +15 -8
- package/src/StatsigMetadata.js +1 -1
- package/src/StatsigOptionsCommon.d.ts +5 -5
- package/src/StatsigTypes.d.ts +9 -4
- package/src/StatsigTypes.js +6 -6
- package/src/StatsigUser.js +16 -17
- package/src/StorageProvider.d.ts +2 -0
- package/src/StorageProvider.js +11 -0
- package/src/VisibilityChangeObserver.js +4 -1
- package/src/index.d.ts +6 -3
- package/src/index.js +9 -4
- package/src/StatsigDataProvider.d.ts +0 -9
- package/src/StatsigDataProvider.js +0 -2
package/src/NetworkCore.js
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
2
|
var __assign = (this && this.__assign) || function () {
|
|
18
3
|
__assign = Object.assign || function(t) {
|
|
19
4
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
@@ -69,33 +54,21 @@ var SessionID_1 = require("./SessionID");
|
|
|
69
54
|
var StableID_1 = require("./StableID");
|
|
70
55
|
var StatsigMetadata_1 = require("./StatsigMetadata");
|
|
71
56
|
var DEFAULT_TIMEOUT_MS = 10000;
|
|
72
|
-
var NetworkError = /** @class */ (function (_super) {
|
|
73
|
-
__extends(NetworkError, _super);
|
|
74
|
-
function NetworkError(message, errorDescription) {
|
|
75
|
-
var _this = _super.call(this, message) || this;
|
|
76
|
-
_this.errorDescription = errorDescription;
|
|
77
|
-
return _this;
|
|
78
|
-
}
|
|
79
|
-
return NetworkError;
|
|
80
|
-
}(Error));
|
|
81
57
|
var NetworkCore = /** @class */ (function () {
|
|
82
|
-
function NetworkCore(_options) {
|
|
58
|
+
function NetworkCore(_options, _emitter) {
|
|
83
59
|
var _a;
|
|
84
60
|
this._options = _options;
|
|
61
|
+
this._emitter = _emitter;
|
|
85
62
|
this._timeout = (_a = _options === null || _options === void 0 ? void 0 : _options.networkTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
|
|
86
63
|
}
|
|
87
64
|
NetworkCore.prototype.post = function (args) {
|
|
88
65
|
return __awaiter(this, void 0, void 0, function () {
|
|
89
|
-
var
|
|
66
|
+
var body;
|
|
90
67
|
return __generator(this, function (_a) {
|
|
91
68
|
switch (_a.label) {
|
|
92
|
-
case 0:
|
|
93
|
-
data = args.data;
|
|
94
|
-
return [4 /*yield*/, StableID_1.StableID.get(args.sdkKey)];
|
|
69
|
+
case 0: return [4 /*yield*/, this._getPopulatedBody(args)];
|
|
95
70
|
case 1:
|
|
96
|
-
|
|
97
|
-
sessionID = SessionID_1.SessionID.get(args.sdkKey);
|
|
98
|
-
body = JSON.stringify(__assign(__assign({}, data), { statsigMetadata: __assign(__assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID: stableID, sessionID: sessionID }) }));
|
|
71
|
+
body = _a.sent();
|
|
99
72
|
return [2 /*return*/, this._sendRequest(__assign({ method: 'POST', body: body }, args))];
|
|
100
73
|
}
|
|
101
74
|
});
|
|
@@ -108,51 +81,68 @@ var NetworkCore = /** @class */ (function () {
|
|
|
108
81
|
});
|
|
109
82
|
});
|
|
110
83
|
};
|
|
84
|
+
NetworkCore.prototype.isBeaconSupported = function () {
|
|
85
|
+
return (typeof navigator !== 'undefined' &&
|
|
86
|
+
typeof (navigator === null || navigator === void 0 ? void 0 : navigator.sendBeacon) === 'function');
|
|
87
|
+
};
|
|
111
88
|
NetworkCore.prototype.beacon = function (args) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
89
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
90
|
+
var url, body;
|
|
91
|
+
return __generator(this, function (_a) {
|
|
92
|
+
switch (_a.label) {
|
|
93
|
+
case 0:
|
|
94
|
+
url = this._getPopulatedURL(args);
|
|
95
|
+
return [4 /*yield*/, this._getPopulatedBody(args)];
|
|
96
|
+
case 1:
|
|
97
|
+
body = _a.sent();
|
|
98
|
+
return [2 /*return*/, navigator.sendBeacon(url, body)];
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
115
102
|
};
|
|
116
103
|
NetworkCore.prototype._sendRequest = function (args) {
|
|
104
|
+
var _a;
|
|
117
105
|
return __awaiter(this, void 0, void 0, function () {
|
|
118
|
-
var method, body, retries, controller, handle, response,
|
|
106
|
+
var method, body, retries, controller, handle, response, url, text, err, error_1, errorMessage;
|
|
119
107
|
var _this = this;
|
|
120
|
-
return __generator(this, function (
|
|
121
|
-
switch (
|
|
108
|
+
return __generator(this, function (_b) {
|
|
109
|
+
switch (_b.label) {
|
|
122
110
|
case 0:
|
|
123
111
|
method = args.method, body = args.body, retries = args.retries;
|
|
124
112
|
controller = new AbortController();
|
|
125
113
|
handle = setTimeout(function () { return controller.abort("Timeout of ".concat(_this._timeout, "ms expired.")); }, this._timeout);
|
|
126
114
|
response = null;
|
|
127
|
-
|
|
115
|
+
_b.label = 1;
|
|
128
116
|
case 1:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return [4 /*yield*/, fetch(
|
|
117
|
+
_b.trys.push([1, 4, , 5]);
|
|
118
|
+
url = this._getPopulatedURL(args);
|
|
119
|
+
return [4 /*yield*/, fetch(url, {
|
|
132
120
|
method: method,
|
|
133
121
|
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),
|
|
122
|
+
headers: __assign({}, args.headers),
|
|
138
123
|
signal: controller.signal,
|
|
139
124
|
})];
|
|
140
125
|
case 2:
|
|
141
|
-
response =
|
|
126
|
+
response = _b.sent();
|
|
142
127
|
clearTimeout(handle);
|
|
143
128
|
return [4 /*yield*/, response.text()];
|
|
144
129
|
case 3:
|
|
145
|
-
text =
|
|
130
|
+
text = _b.sent();
|
|
146
131
|
if (!response.ok) {
|
|
147
|
-
|
|
132
|
+
err = new Error("Failed to fetch: ".concat(url, " ").concat(text));
|
|
133
|
+
err.name = 'NetworkError';
|
|
134
|
+
throw err;
|
|
148
135
|
}
|
|
149
136
|
Diagnostics_1.Diagnostics.mark('_sendRequest:response-received', {
|
|
150
137
|
status: response.status,
|
|
151
138
|
contentLength: response.headers.get('content-length'),
|
|
152
139
|
});
|
|
153
|
-
return [2 /*return*/,
|
|
140
|
+
return [2 /*return*/, {
|
|
141
|
+
body: text,
|
|
142
|
+
code: response.status,
|
|
143
|
+
}];
|
|
154
144
|
case 4:
|
|
155
|
-
error_1 =
|
|
145
|
+
error_1 = _b.sent();
|
|
156
146
|
errorMessage = _getErrorMessage(controller, error_1);
|
|
157
147
|
Diagnostics_1.Diagnostics.mark('_sendRequest:error', {
|
|
158
148
|
error: errorMessage,
|
|
@@ -160,7 +150,8 @@ var NetworkCore = /** @class */ (function () {
|
|
|
160
150
|
contentLength: response === null || response === void 0 ? void 0 : response.headers.get('content-length'),
|
|
161
151
|
});
|
|
162
152
|
if (!retries || retries <= 0) {
|
|
163
|
-
|
|
153
|
+
(_a = this._emitter) === null || _a === void 0 ? void 0 : _a.call(this, { event: 'error', error: error_1 });
|
|
154
|
+
Log_1.Log.error('A networking error occured.', errorMessage, error_1);
|
|
164
155
|
return [2 /*return*/, null];
|
|
165
156
|
}
|
|
166
157
|
return [2 /*return*/, this._sendRequest(__assign(__assign({}, args), { retries: retries - 1 }))];
|
|
@@ -170,14 +161,31 @@ var NetworkCore = /** @class */ (function () {
|
|
|
170
161
|
});
|
|
171
162
|
};
|
|
172
163
|
NetworkCore.prototype._getPopulatedURL = function (args) {
|
|
173
|
-
var
|
|
174
|
-
var
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
164
|
+
var metadata = StatsigMetadata_1.StatsigMetadataProvider.get();
|
|
165
|
+
var params = __assign(__assign({}, args.params), { k: args.sdkKey, st: metadata.sdkType, sv: metadata.sdkVersion, t: String(Date.now()), sid: SessionID_1.SessionID.get(args.sdkKey) });
|
|
166
|
+
var query = Object.entries(params)
|
|
167
|
+
.map(function (_a) {
|
|
168
|
+
var key = _a[0], value = _a[1];
|
|
169
|
+
return "".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value));
|
|
170
|
+
})
|
|
171
|
+
.join('&');
|
|
172
|
+
return "".concat(args.url).concat(query ? "?".concat(query) : '');
|
|
173
|
+
};
|
|
174
|
+
NetworkCore.prototype._getPopulatedBody = function (args) {
|
|
175
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
176
|
+
var data, stableID, sessionID;
|
|
177
|
+
return __generator(this, function (_a) {
|
|
178
|
+
switch (_a.label) {
|
|
179
|
+
case 0:
|
|
180
|
+
data = args.data;
|
|
181
|
+
return [4 /*yield*/, StableID_1.StableID.get(args.sdkKey)];
|
|
182
|
+
case 1:
|
|
183
|
+
stableID = _a.sent();
|
|
184
|
+
sessionID = SessionID_1.SessionID.get(args.sdkKey);
|
|
185
|
+
return [2 /*return*/, JSON.stringify(__assign(__assign({}, data), { statsigMetadata: __assign(__assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID: stableID, sessionID: sessionID }) }))];
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
181
189
|
};
|
|
182
190
|
return NetworkCore;
|
|
183
191
|
}());
|
package/src/StableID.js
CHANGED
|
@@ -64,7 +64,7 @@ exports.StableID = {
|
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
66
|
function _getStableIDStorageKey(sdkKey) {
|
|
67
|
-
return "
|
|
67
|
+
return "statsig.stable_id.".concat((0, Hashing_1.DJB2)(sdkKey));
|
|
68
68
|
}
|
|
69
69
|
function _persistToStorage(stableID, sdkKey) {
|
|
70
70
|
var storageKey = _getStableIDStorageKey(sdkKey);
|
|
@@ -3,35 +3,28 @@ import { ErrorBoundary } from './ErrorBoundary';
|
|
|
3
3
|
import { EventLogger } from './EventLogger';
|
|
4
4
|
import { NetworkCore } from './NetworkCore';
|
|
5
5
|
import { StatsigClientEvent, StatsigClientEventCallback, StatsigClientEventData, StatsigClientEventEmitterInterface, StatsigLoadingStatus } from './StatsigClientEventEmitter';
|
|
6
|
-
import {
|
|
6
|
+
import { StatsigDataAdapter, StatsigDataAdapterResult } from './StatsigDataAdapter';
|
|
7
7
|
import { StatsigEventInternal } from './StatsigEvent';
|
|
8
8
|
import { StatsigOptionsCommon } from './StatsigOptionsCommon';
|
|
9
9
|
import { StatsigUser } from './StatsigUser';
|
|
10
|
-
type DataProviderResult = {
|
|
11
|
-
data: string | null;
|
|
12
|
-
source: DataSource;
|
|
13
|
-
};
|
|
14
10
|
export type EvaluationOptions = {
|
|
15
11
|
disableExposureLog?: boolean;
|
|
16
12
|
};
|
|
17
13
|
export declare const DEFAULT_EVAL_OPTIONS: EvaluationOptions;
|
|
18
14
|
export type StatsigClientEmitEventFunc = (data: StatsigClientEventData) => void;
|
|
19
|
-
export declare class StatsigClientBase implements StatsigClientEventEmitterInterface {
|
|
15
|
+
export declare abstract class StatsigClientBase implements StatsigClientEventEmitterInterface {
|
|
16
|
+
protected readonly _sdkKey: string;
|
|
17
|
+
protected readonly _adapter: StatsigDataAdapter;
|
|
20
18
|
loadingStatus: StatsigLoadingStatus;
|
|
21
|
-
protected _errorBoundary: ErrorBoundary;
|
|
22
|
-
protected _logger: EventLogger;
|
|
23
|
-
protected _sdkKey: string;
|
|
24
|
-
protected _dataProviders: StatsigDataProvider[];
|
|
19
|
+
protected readonly _errorBoundary: ErrorBoundary;
|
|
20
|
+
protected readonly _logger: EventLogger;
|
|
25
21
|
private _listeners;
|
|
26
|
-
constructor(
|
|
22
|
+
constructor(_sdkKey: string, _adapter: StatsigDataAdapter, network: NetworkCore, options: StatsigOptionsCommon | null);
|
|
27
23
|
on(event: StatsigClientEvent | '*', listener: StatsigClientEventCallback): void;
|
|
28
24
|
off(event: StatsigClientEvent | '*', listener: StatsigClientEventCallback): void;
|
|
25
|
+
getDataAdapter(): StatsigDataAdapter;
|
|
29
26
|
protected emit(data: StatsigClientEventData): void;
|
|
30
|
-
protected _setStatus(newStatus: StatsigLoadingStatus): void;
|
|
31
|
-
protected _getDataFromProviders(user?: StatsigUser): DataProviderResult;
|
|
32
|
-
protected _getDataFromProvidersAsync(user?: StatsigUser): Promise<DataProviderResult>;
|
|
33
|
-
protected _getDataPostInitFromProviders(user?: StatsigUser): Promise<DataProviderResult>;
|
|
34
|
-
protected _saveToDataProviders(data: string | null, user?: StatsigUser): void;
|
|
27
|
+
protected _setStatus(newStatus: StatsigLoadingStatus, values: StatsigDataAdapterResult | null): void;
|
|
35
28
|
protected _enqueueExposure(options: EvaluationOptions, exposure: StatsigEventInternal): void;
|
|
29
|
+
protected _runPostUpdate(current: StatsigDataAdapterResult | null, user?: StatsigUser): void;
|
|
36
30
|
}
|
|
37
|
-
export {};
|
package/src/StatsigClientBase.js
CHANGED
|
@@ -1,47 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
39
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
40
|
-
var m = o[Symbol.asyncIterator], i;
|
|
41
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
42
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
43
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
44
|
-
};
|
|
45
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
3
|
exports.StatsigClientBase = exports.DEFAULT_EVAL_OPTIONS = void 0;
|
|
47
4
|
require("./$_StatsigGlobal");
|
|
@@ -53,22 +10,23 @@ exports.DEFAULT_EVAL_OPTIONS = {
|
|
|
53
10
|
disableExposureLog: false,
|
|
54
11
|
};
|
|
55
12
|
var StatsigClientBase = /** @class */ (function () {
|
|
56
|
-
function StatsigClientBase(
|
|
13
|
+
function StatsigClientBase(_sdkKey, _adapter, network, options) {
|
|
57
14
|
var _a, _b;
|
|
15
|
+
this._sdkKey = _sdkKey;
|
|
16
|
+
this._adapter = _adapter;
|
|
58
17
|
this.loadingStatus = 'Uninitialized';
|
|
59
18
|
this._listeners = {};
|
|
60
|
-
|
|
61
|
-
this.
|
|
62
|
-
this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(
|
|
19
|
+
Log_1.Log.level = (_a = options === null || options === void 0 ? void 0 : options.logLevel) !== null && _a !== void 0 ? _a : Log_1.LogLevel.Warn;
|
|
20
|
+
this._logger = new EventLogger_1.EventLogger(_sdkKey, this.emit.bind(this), network, options);
|
|
21
|
+
this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(_sdkKey);
|
|
63
22
|
if (options === null || options === void 0 ? void 0 : options.overrideStableID) {
|
|
64
|
-
StableID_1.StableID.setOverride(options.overrideStableID,
|
|
23
|
+
StableID_1.StableID.setOverride(options.overrideStableID, _sdkKey);
|
|
65
24
|
}
|
|
66
25
|
__STATSIG__ = __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {};
|
|
67
|
-
var instances = (
|
|
26
|
+
var instances = (_b = __STATSIG__.instances) !== null && _b !== void 0 ? _b : new Set();
|
|
68
27
|
instances.add(this);
|
|
69
28
|
__STATSIG__.instances = instances;
|
|
70
|
-
|
|
71
|
-
this._dataProviders = dataProviders;
|
|
29
|
+
this._adapter.attach(_sdkKey, options);
|
|
72
30
|
}
|
|
73
31
|
StatsigClientBase.prototype.on = function (event, listener) {
|
|
74
32
|
if (!this._listeners[event]) {
|
|
@@ -84,6 +42,9 @@ var StatsigClientBase = /** @class */ (function () {
|
|
|
84
42
|
}
|
|
85
43
|
}
|
|
86
44
|
};
|
|
45
|
+
StatsigClientBase.prototype.getDataAdapter = function () {
|
|
46
|
+
return this._adapter;
|
|
47
|
+
};
|
|
87
48
|
StatsigClientBase.prototype.emit = function (data) {
|
|
88
49
|
var _a;
|
|
89
50
|
if (this._listeners[data.event]) {
|
|
@@ -91,175 +52,9 @@ var StatsigClientBase = /** @class */ (function () {
|
|
|
91
52
|
}
|
|
92
53
|
(_a = this._listeners['*']) === null || _a === void 0 ? void 0 : _a.forEach(function (listener) { return listener(data); });
|
|
93
54
|
};
|
|
94
|
-
StatsigClientBase.prototype._setStatus = function (newStatus) {
|
|
55
|
+
StatsigClientBase.prototype._setStatus = function (newStatus, values) {
|
|
95
56
|
this.loadingStatus = newStatus;
|
|
96
|
-
this.emit({ event: '
|
|
97
|
-
};
|
|
98
|
-
StatsigClientBase.prototype._getDataFromProviders = function (user) {
|
|
99
|
-
var _a;
|
|
100
|
-
for (var _i = 0, _b = this._dataProviders; _i < _b.length; _i++) {
|
|
101
|
-
var provider = _b[_i];
|
|
102
|
-
var data = (_a = provider.getData) === null || _a === void 0 ? void 0 : _a.call(provider, this._sdkKey, user);
|
|
103
|
-
if (data) {
|
|
104
|
-
return { data: data, source: provider.source };
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return { data: null, source: 'NoValues' };
|
|
108
|
-
};
|
|
109
|
-
StatsigClientBase.prototype._getDataFromProvidersAsync = function (user) {
|
|
110
|
-
var _a, e_1, _b, _c;
|
|
111
|
-
var _d;
|
|
112
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
113
|
-
var _e, _f, _g, provider, data, e_1_1;
|
|
114
|
-
return __generator(this, function (_h) {
|
|
115
|
-
switch (_h.label) {
|
|
116
|
-
case 0:
|
|
117
|
-
_h.trys.push([0, 6, 7, 12]);
|
|
118
|
-
_e = true, _f = __asyncValues(this._dataProviders);
|
|
119
|
-
_h.label = 1;
|
|
120
|
-
case 1: return [4 /*yield*/, _f.next()];
|
|
121
|
-
case 2:
|
|
122
|
-
if (!(_g = _h.sent(), _a = _g.done, !_a)) return [3 /*break*/, 5];
|
|
123
|
-
_c = _g.value;
|
|
124
|
-
_e = false;
|
|
125
|
-
provider = _c;
|
|
126
|
-
return [4 /*yield*/, ((_d = provider.getDataAsync) === null || _d === void 0 ? void 0 : _d.call(provider, this._sdkKey, user))];
|
|
127
|
-
case 3:
|
|
128
|
-
data = _h.sent();
|
|
129
|
-
if (data) {
|
|
130
|
-
return [2 /*return*/, { data: data, source: provider.source }];
|
|
131
|
-
}
|
|
132
|
-
_h.label = 4;
|
|
133
|
-
case 4:
|
|
134
|
-
_e = true;
|
|
135
|
-
return [3 /*break*/, 1];
|
|
136
|
-
case 5: return [3 /*break*/, 12];
|
|
137
|
-
case 6:
|
|
138
|
-
e_1_1 = _h.sent();
|
|
139
|
-
e_1 = { error: e_1_1 };
|
|
140
|
-
return [3 /*break*/, 12];
|
|
141
|
-
case 7:
|
|
142
|
-
_h.trys.push([7, , 10, 11]);
|
|
143
|
-
if (!(!_e && !_a && (_b = _f.return))) return [3 /*break*/, 9];
|
|
144
|
-
return [4 /*yield*/, _b.call(_f)];
|
|
145
|
-
case 8:
|
|
146
|
-
_h.sent();
|
|
147
|
-
_h.label = 9;
|
|
148
|
-
case 9: return [3 /*break*/, 11];
|
|
149
|
-
case 10:
|
|
150
|
-
if (e_1) throw e_1.error;
|
|
151
|
-
return [7 /*endfinally*/];
|
|
152
|
-
case 11: return [7 /*endfinally*/];
|
|
153
|
-
case 12: return [2 /*return*/, { data: null, source: 'NoValues' }];
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
};
|
|
158
|
-
StatsigClientBase.prototype._getDataPostInitFromProviders = function (user) {
|
|
159
|
-
var _a, e_2, _b, _c;
|
|
160
|
-
var _d;
|
|
161
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
162
|
-
var _e, _f, _g, provider, data, e_2_1;
|
|
163
|
-
return __generator(this, function (_h) {
|
|
164
|
-
switch (_h.label) {
|
|
165
|
-
case 0:
|
|
166
|
-
_h.trys.push([0, 6, 7, 12]);
|
|
167
|
-
_e = true, _f = __asyncValues(this._dataProviders);
|
|
168
|
-
_h.label = 1;
|
|
169
|
-
case 1: return [4 /*yield*/, _f.next()];
|
|
170
|
-
case 2:
|
|
171
|
-
if (!(_g = _h.sent(), _a = _g.done, !_a)) return [3 /*break*/, 5];
|
|
172
|
-
_c = _g.value;
|
|
173
|
-
_e = false;
|
|
174
|
-
provider = _c;
|
|
175
|
-
return [4 /*yield*/, ((_d = provider.getDataPostInit) === null || _d === void 0 ? void 0 : _d.call(provider, this._sdkKey, user))];
|
|
176
|
-
case 3:
|
|
177
|
-
data = _h.sent();
|
|
178
|
-
if (data) {
|
|
179
|
-
return [2 /*return*/, { data: data, source: provider.source }];
|
|
180
|
-
}
|
|
181
|
-
_h.label = 4;
|
|
182
|
-
case 4:
|
|
183
|
-
_e = true;
|
|
184
|
-
return [3 /*break*/, 1];
|
|
185
|
-
case 5: return [3 /*break*/, 12];
|
|
186
|
-
case 6:
|
|
187
|
-
e_2_1 = _h.sent();
|
|
188
|
-
e_2 = { error: e_2_1 };
|
|
189
|
-
return [3 /*break*/, 12];
|
|
190
|
-
case 7:
|
|
191
|
-
_h.trys.push([7, , 10, 11]);
|
|
192
|
-
if (!(!_e && !_a && (_b = _f.return))) return [3 /*break*/, 9];
|
|
193
|
-
return [4 /*yield*/, _b.call(_f)];
|
|
194
|
-
case 8:
|
|
195
|
-
_h.sent();
|
|
196
|
-
_h.label = 9;
|
|
197
|
-
case 9: return [3 /*break*/, 11];
|
|
198
|
-
case 10:
|
|
199
|
-
if (e_2) throw e_2.error;
|
|
200
|
-
return [7 /*endfinally*/];
|
|
201
|
-
case 11: return [7 /*endfinally*/];
|
|
202
|
-
case 12: return [2 /*return*/, { data: null, source: 'NoValues' }];
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
StatsigClientBase.prototype._saveToDataProviders = function (data, user) {
|
|
208
|
-
var _this = this;
|
|
209
|
-
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
210
|
-
var localResult, _a, _b, _c, provider, e_3_1;
|
|
211
|
-
var _d, e_3, _e, _f;
|
|
212
|
-
var _g, _h;
|
|
213
|
-
return __generator(this, function (_j) {
|
|
214
|
-
switch (_j.label) {
|
|
215
|
-
case 0: return [4 /*yield*/, this._getDataPostInitFromProviders(user)];
|
|
216
|
-
case 1:
|
|
217
|
-
localResult = _j.sent();
|
|
218
|
-
data = (_g = localResult.data) !== null && _g !== void 0 ? _g : data;
|
|
219
|
-
if (!data) {
|
|
220
|
-
return [2 /*return*/];
|
|
221
|
-
}
|
|
222
|
-
_j.label = 2;
|
|
223
|
-
case 2:
|
|
224
|
-
_j.trys.push([2, 8, 9, 14]);
|
|
225
|
-
_a = true, _b = __asyncValues(this._dataProviders);
|
|
226
|
-
_j.label = 3;
|
|
227
|
-
case 3: return [4 /*yield*/, _b.next()];
|
|
228
|
-
case 4:
|
|
229
|
-
if (!(_c = _j.sent(), _d = _c.done, !_d)) return [3 /*break*/, 7];
|
|
230
|
-
_f = _c.value;
|
|
231
|
-
_a = false;
|
|
232
|
-
provider = _f;
|
|
233
|
-
return [4 /*yield*/, ((_h = provider.setDataPostInit) === null || _h === void 0 ? void 0 : _h.call(provider, this._sdkKey, data, user))];
|
|
234
|
-
case 5:
|
|
235
|
-
_j.sent();
|
|
236
|
-
_j.label = 6;
|
|
237
|
-
case 6:
|
|
238
|
-
_a = true;
|
|
239
|
-
return [3 /*break*/, 3];
|
|
240
|
-
case 7: return [3 /*break*/, 14];
|
|
241
|
-
case 8:
|
|
242
|
-
e_3_1 = _j.sent();
|
|
243
|
-
e_3 = { error: e_3_1 };
|
|
244
|
-
return [3 /*break*/, 14];
|
|
245
|
-
case 9:
|
|
246
|
-
_j.trys.push([9, , 12, 13]);
|
|
247
|
-
if (!(!_a && !_d && (_e = _b.return))) return [3 /*break*/, 11];
|
|
248
|
-
return [4 /*yield*/, _e.call(_b)];
|
|
249
|
-
case 10:
|
|
250
|
-
_j.sent();
|
|
251
|
-
_j.label = 11;
|
|
252
|
-
case 11: return [3 /*break*/, 13];
|
|
253
|
-
case 12:
|
|
254
|
-
if (e_3) throw e_3.error;
|
|
255
|
-
return [7 /*endfinally*/];
|
|
256
|
-
case 13: return [7 /*endfinally*/];
|
|
257
|
-
case 14: return [2 /*return*/];
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
}); })().catch(function (error) {
|
|
261
|
-
_this.emit({ event: 'error', error: error });
|
|
262
|
-
});
|
|
57
|
+
this.emit({ event: 'values_updated', status: newStatus, values: values });
|
|
263
58
|
};
|
|
264
59
|
StatsigClientBase.prototype._enqueueExposure = function (options, exposure) {
|
|
265
60
|
if (options.disableExposureLog === true) {
|
|
@@ -267,6 +62,11 @@ var StatsigClientBase = /** @class */ (function () {
|
|
|
267
62
|
}
|
|
268
63
|
this._logger.enqueue(exposure);
|
|
269
64
|
};
|
|
65
|
+
StatsigClientBase.prototype._runPostUpdate = function (current, user) {
|
|
66
|
+
this._adapter.getDataAsync(current, user).catch(function (err) {
|
|
67
|
+
Log_1.Log.error('An error occurred after update.', err);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
270
70
|
return StatsigClientBase;
|
|
271
71
|
}());
|
|
272
72
|
exports.StatsigClientBase = StatsigClientBase;
|
|
@@ -1,11 +1,33 @@
|
|
|
1
|
+
import { StatsigDataAdapterResult } from './StatsigDataAdapter';
|
|
1
2
|
import { DynamicConfig, Experiment, FeatureGate, Layer } from './StatsigTypes';
|
|
2
|
-
export type StatsigLoadingStatus = 'Uninitialized' | 'Loading' | 'Ready'
|
|
3
|
-
|
|
3
|
+
export type StatsigLoadingStatus = 'Uninitialized' | 'Loading' | 'Ready';
|
|
4
|
+
/**
|
|
5
|
+
* All the possible events emitted from a Statsig client.
|
|
6
|
+
*
|
|
7
|
+
* `values_updated` - When the Statsig clients internal values change as the result of an initialize/update operation.
|
|
8
|
+
*
|
|
9
|
+
* `error` - When an unexpected error occurs within the Statsig client.
|
|
10
|
+
*
|
|
11
|
+
* `logs_flushed` - When queued StatsigEvents are flushed to Statsig servers.
|
|
12
|
+
*
|
|
13
|
+
* `gate_evaluation` - Fired when any gate is checked from the Statsig client.
|
|
14
|
+
*
|
|
15
|
+
* `dynamic_config_evaluation` - Fired when any dyanamic config is checked from the Statsig client.
|
|
16
|
+
*
|
|
17
|
+
* `experiment_evaluation` - Fired when any experiment is checked from the Statsig client.
|
|
18
|
+
*
|
|
19
|
+
* `layer_evaluation` - Fired when any layer is checked from the Statsig client.
|
|
20
|
+
*/
|
|
21
|
+
export type StatsigClientEvent = 'values_updated' | 'error' | 'logs_flushed' | 'gate_evaluation' | 'dynamic_config_evaluation' | 'experiment_evaluation' | 'layer_evaluation';
|
|
22
|
+
/**
|
|
23
|
+
* Type representing various events emitted by a Statsig client.
|
|
24
|
+
*/
|
|
4
25
|
export type StatsigClientEventData = {
|
|
5
26
|
event: StatsigClientEvent;
|
|
6
27
|
} | {
|
|
7
|
-
event: '
|
|
8
|
-
|
|
28
|
+
event: 'values_updated';
|
|
29
|
+
status: StatsigLoadingStatus;
|
|
30
|
+
values: StatsigDataAdapterResult | null;
|
|
9
31
|
} | {
|
|
10
32
|
event: 'error';
|
|
11
33
|
error: unknown;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { StatsigOptionsCommon } from './StatsigOptionsCommon';
|
|
2
|
+
import { StatsigUser } from './StatsigUser';
|
|
3
|
+
export type DataSource = 'Uninitialized' | 'Loading' | 'NoValues' | 'Cache' | 'Network' | 'NetworkNotModified' | 'Bootstrap' | 'Prefetch';
|
|
4
|
+
export type StatsigDataAdapterResult = {
|
|
5
|
+
readonly source: DataSource;
|
|
6
|
+
readonly data: string;
|
|
7
|
+
readonly receivedAt: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const DataAdapterCachePrefix = "statsig.cached";
|
|
10
|
+
/**
|
|
11
|
+
* Describes a type that is used during intialize/update operations of a Statsig client.
|
|
12
|
+
*
|
|
13
|
+
* See below to find the default adapters, but know that it is possible to create your
|
|
14
|
+
* own StatsigDataAdapter and provide it via {@link StatsigOptionsCommon.dataAdapter}.
|
|
15
|
+
*
|
|
16
|
+
* Defaults:
|
|
17
|
+
*
|
|
18
|
+
* - {@link PrecomputedEvaluationsClient} uses {@link EvaluationsDataAdapter}
|
|
19
|
+
*
|
|
20
|
+
* - {@link OnDeviceEvaluationsClient} uses {@link SpecsDataAdapter}
|
|
21
|
+
*/
|
|
22
|
+
export type StatsigDataAdapter = {
|
|
23
|
+
readonly _setInMemoryCache: (cache: Record<string, StatsigDataAdapterResult>) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Called when the StatsigDataAdapter is attached to the Statsig client instance during construction.
|
|
26
|
+
* @param {string} sdkKey The SDK key being used by the Statsig client.
|
|
27
|
+
* @param {StatsigOptionsCommon | null} options The StatsigOptions being used by the Statsig client.
|
|
28
|
+
*/
|
|
29
|
+
readonly attach: (sdkKey: string, options: StatsigOptionsCommon | null) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Synchronously get data for the given user (if any). Called during initializeSync and/or updateUserSync.
|
|
32
|
+
* It is also called during async update operations before StatsigDataAdapter.getDataAsync is called.
|
|
33
|
+
* @param {StatsigUser | undefined} user The StatsigUser to get data for.
|
|
34
|
+
* @returns {StatsigDataAdapterResult | null} The data that was found for the given StatsigUser.
|
|
35
|
+
*/
|
|
36
|
+
readonly getDataSync: (user?: StatsigUser) => StatsigDataAdapterResult | null;
|
|
37
|
+
/**
|
|
38
|
+
* Asynchronously get data for the given user (if any). Called during initializeAsync and/or updateUserAsync.
|
|
39
|
+
* @param {StatsigUser | undefined} user The StatsigUser to get data for.
|
|
40
|
+
* @returns {StatsigDataAdapterResult | null} The data that was found for the given StatsigUser.
|
|
41
|
+
*/
|
|
42
|
+
readonly getDataAsync: (current: StatsigDataAdapterResult | null, user?: StatsigUser) => Promise<StatsigDataAdapterResult | null>;
|
|
43
|
+
};
|
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;
|