@statsig/client-core 0.0.1-beta.2 → 0.0.1-beta.21
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 +1 -1
- package/package.json +1 -1
- package/src/$_StatsigGlobal.d.ts +2 -1
- package/src/$_StatsigGlobal.js +10 -12
- package/src/ClientInterfaces.d.ts +20 -13
- package/src/DataAdapterCore.d.ts +32 -0
- package/src/DataAdapterCore.js +167 -0
- package/src/Diagnostics.js +21 -26
- package/src/ErrorBoundary.d.ts +1 -0
- package/src/ErrorBoundary.js +39 -86
- package/src/EvaluationOptions.d.ts +20 -0
- package/src/EvaluationTypes.d.ts +39 -0
- package/src/EvaluationTypes.js +2 -0
- package/src/EventLogger.d.ts +17 -4
- package/src/EventLogger.js +186 -225
- package/src/Hashing.d.ts +1 -0
- package/src/Hashing.js +23 -4
- package/src/Log.js +15 -34
- package/src/Monitoring.d.ts +1 -2
- package/src/Monitoring.js +68 -27
- package/src/NetworkCore.d.ts +13 -5
- package/src/NetworkCore.js +96 -164
- package/src/OverrideAdapter.d.ts +16 -0
- package/src/OverrideAdapter.js +24 -0
- package/src/SessionID.js +3 -3
- package/src/StableID.js +23 -52
- package/src/StatsigClientBase.d.ts +20 -29
- package/src/StatsigClientBase.js +58 -248
- package/src/StatsigClientEventEmitter.d.ts +55 -28
- package/src/StatsigDataAdapter.d.ts +89 -0
- package/src/StatsigDataAdapter.js +4 -0
- package/src/StatsigEvent.d.ts +9 -18
- package/src/StatsigEvent.js +40 -31
- package/src/StatsigMetadata.js +5 -16
- package/src/StatsigOptionsCommon.d.ts +42 -12
- package/src/StatsigTypes.d.ts +23 -15
- package/src/StatsigTypes.js +23 -16
- package/src/StatsigUser.d.ts +1 -0
- package/src/StatsigUser.js +12 -20
- package/src/StorageProvider.d.ts +7 -2
- package/src/StorageProvider.js +53 -62
- package/src/TypedJsonParse.d.ts +8 -0
- package/src/TypedJsonParse.js +27 -0
- package/src/UUID.js +9 -5
- package/src/UrlOverrides.d.ts +1 -0
- package/src/UrlOverrides.js +15 -0
- package/src/UtitlityTypes.d.ts +3 -0
- package/src/UtitlityTypes.js +2 -0
- package/src/VisibilityChangeObserver.js +18 -24
- package/src/__tests__/MockLocalStorage.js +18 -19
- package/src/index.d.ts +12 -3
- package/src/index.js +18 -16
- package/src/StatsigDataProvider.d.ts +0 -9
- /package/src/{StatsigDataProvider.js → EvaluationOptions.js} +0 -0
package/src/EventLogger.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -19,267 +8,239 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
19
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
9
|
});
|
|
21
10
|
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
-
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;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
12
|
exports.EventLogger = void 0;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
13
|
+
const Hashing_1 = require("./Hashing");
|
|
14
|
+
const Log_1 = require("./Log");
|
|
15
|
+
const StatsigEvent_1 = require("./StatsigEvent");
|
|
16
|
+
const StatsigMetadata_1 = require("./StatsigMetadata");
|
|
17
|
+
const StorageProvider_1 = require("./StorageProvider");
|
|
18
|
+
const TypedJsonParse_1 = require("./TypedJsonParse");
|
|
19
|
+
const UrlOverrides_1 = require("./UrlOverrides");
|
|
20
|
+
const VisibilityChangeObserver_1 = require("./VisibilityChangeObserver");
|
|
21
|
+
const DEFAULT_QUEUE_SIZE = 50;
|
|
22
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 10000;
|
|
23
|
+
const MAX_DEDUPER_KEYS = 1000;
|
|
24
|
+
const DEDUPER_WINDOW_DURATION_MS = 60000;
|
|
25
|
+
const MAX_FAILED_LOGS = 500;
|
|
26
|
+
const DEFAULT_API = 'https://api.statsig.com/v1';
|
|
27
|
+
const DEFAULT_ENDPOINT = '/rgstr';
|
|
28
|
+
const DEFAULT_BEACON_ENDPOINT = '/log_event_beacon';
|
|
29
|
+
const QUICK_FLUSH_WINDOW_MS = 200;
|
|
30
|
+
class EventLogger {
|
|
31
|
+
constructor(_sdkKey, _emitter, _network, _options) {
|
|
66
32
|
var _a, _b;
|
|
67
33
|
this._sdkKey = _sdkKey;
|
|
68
34
|
this._emitter = _emitter;
|
|
69
35
|
this._network = _network;
|
|
70
36
|
this._options = _options;
|
|
71
37
|
this._queue = [];
|
|
72
|
-
this.
|
|
38
|
+
this._lastExposureTimeMap = {};
|
|
39
|
+
this._nonExposedChecks = {};
|
|
40
|
+
this._hasRunQuickFlush = false;
|
|
41
|
+
this._creationTime = Date.now();
|
|
42
|
+
this._isLoggingDisabled = (_options === null || _options === void 0 ? void 0 : _options.disableLogging) === true;
|
|
73
43
|
this._maxQueueSize = (_a = _options === null || _options === void 0 ? void 0 : _options.loggingBufferMaxSize) !== null && _a !== void 0 ? _a : DEFAULT_QUEUE_SIZE;
|
|
74
|
-
|
|
75
|
-
this._flushTimer = setInterval(
|
|
44
|
+
const flushInterval = (_b = _options === null || _options === void 0 ? void 0 : _options.loggingIntervalMs) !== null && _b !== void 0 ? _b : DEFAULT_FLUSH_INTERVAL_MS;
|
|
45
|
+
this._flushTimer = setInterval(() => this._flushAndForget(), flushInterval);
|
|
46
|
+
this._logEventUrl = (0, UrlOverrides_1._getOverridableUrl)(_options === null || _options === void 0 ? void 0 : _options.logEventUrl, _options === null || _options === void 0 ? void 0 : _options.api, DEFAULT_ENDPOINT, DEFAULT_API);
|
|
47
|
+
this._logEventBeaconUrl = (0, UrlOverrides_1._getOverridableUrl)(_options === null || _options === void 0 ? void 0 : _options.logEventBeaconUrl, _options === null || _options === void 0 ? void 0 : _options.api, DEFAULT_BEACON_ENDPOINT, DEFAULT_API);
|
|
76
48
|
VisibilityChangeObserver_1.VisibilityChangeObserver.add(this);
|
|
77
|
-
this._failedLogs = [];
|
|
78
49
|
this._retryFailedLogs();
|
|
79
50
|
}
|
|
80
|
-
|
|
51
|
+
setLoggingDisabled(isDisabled) {
|
|
52
|
+
this._isLoggingDisabled = isDisabled;
|
|
53
|
+
}
|
|
54
|
+
enqueue(event) {
|
|
81
55
|
if (!this._shouldLogEvent(event)) {
|
|
82
56
|
return;
|
|
83
57
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
delete event.user.privateAttributes;
|
|
87
|
-
}
|
|
88
|
-
var _a = StatsigMetadata_1.StatsigMetadataProvider.get(), sdkType = _a.sdkType, sdkVersion = _a.sdkVersion;
|
|
89
|
-
this._queue.push(__assign(__assign({}, event), { statsigMetadata: { sdkType: sdkType, sdkVersion: sdkVersion } }));
|
|
58
|
+
this._normalizeAndAppendEvent(event);
|
|
59
|
+
this._quickFlushIfNeeded();
|
|
90
60
|
if (this._queue.length > this._maxQueueSize) {
|
|
91
61
|
this._flushAndForget();
|
|
92
62
|
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
63
|
+
}
|
|
64
|
+
incrementNonExposureCount(name) {
|
|
65
|
+
var _a;
|
|
66
|
+
const current = (_a = this._nonExposedChecks[name]) !== null && _a !== void 0 ? _a : 0;
|
|
67
|
+
this._nonExposedChecks[name] = current + 1;
|
|
68
|
+
}
|
|
69
|
+
reset() {
|
|
70
|
+
this._lastExposureTimeMap = {};
|
|
71
|
+
}
|
|
72
|
+
onVisibilityChanged(visibility) {
|
|
98
73
|
if (visibility === 'background') {
|
|
99
74
|
this._flushAndForget();
|
|
100
75
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
76
|
+
}
|
|
77
|
+
shutdown() {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
if (this._flushTimer) {
|
|
80
|
+
clearInterval(this._flushTimer);
|
|
81
|
+
this._flushTimer = null;
|
|
82
|
+
}
|
|
83
|
+
yield this.flush();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
flush() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
this._appendAndResetNonExposedChecks();
|
|
89
|
+
if (this._queue.length === 0) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const events = this._queue;
|
|
93
|
+
this._queue = [];
|
|
94
|
+
yield this._sendEvents(events);
|
|
117
95
|
});
|
|
118
|
-
}
|
|
119
|
-
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* We 'Quick Flush' following the very first event enqueued
|
|
99
|
+
* within the quick flush window
|
|
100
|
+
*/
|
|
101
|
+
_quickFlushIfNeeded() {
|
|
102
|
+
if (this._hasRunQuickFlush) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this._hasRunQuickFlush = true;
|
|
106
|
+
if (Date.now() - this._creationTime > QUICK_FLUSH_WINDOW_MS) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
setTimeout(() => this._flushAndForget(), QUICK_FLUSH_WINDOW_MS);
|
|
110
|
+
}
|
|
111
|
+
_shouldLogEvent(event) {
|
|
120
112
|
var _a, _b, _c, _d;
|
|
121
113
|
if (!(0, StatsigEvent_1.isExposureEvent)(event)) {
|
|
122
114
|
return true;
|
|
123
115
|
}
|
|
124
|
-
|
|
116
|
+
const key = [
|
|
125
117
|
event.eventName,
|
|
126
118
|
(_a = event.user) === null || _a === void 0 ? void 0 : _a.userID,
|
|
127
119
|
(_b = event.metadata) === null || _b === void 0 ? void 0 : _b['gate'],
|
|
128
120
|
(_c = event.metadata) === null || _c === void 0 ? void 0 : _c['config'],
|
|
129
121
|
(_d = event.metadata) === null || _d === void 0 ? void 0 : _d['ruleID'],
|
|
130
122
|
].join('|');
|
|
131
|
-
|
|
132
|
-
|
|
123
|
+
const previous = this._lastExposureTimeMap[key];
|
|
124
|
+
const now = Date.now();
|
|
133
125
|
if (previous && now - previous < DEDUPER_WINDOW_DURATION_MS) {
|
|
134
126
|
return false;
|
|
135
127
|
}
|
|
136
|
-
if (Object.keys(this.
|
|
137
|
-
this.
|
|
128
|
+
if (Object.keys(this._lastExposureTimeMap).length > MAX_DEDUPER_KEYS) {
|
|
129
|
+
this._lastExposureTimeMap = {};
|
|
138
130
|
}
|
|
139
|
-
this.
|
|
131
|
+
this._lastExposureTimeMap[key] = now;
|
|
140
132
|
return true;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
this.
|
|
133
|
+
}
|
|
134
|
+
_flushAndForget() {
|
|
135
|
+
this.flush().catch(() => {
|
|
144
136
|
// noop
|
|
145
137
|
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
};
|
|
166
|
-
EventLogger.prototype._sendEvents = function (events) {
|
|
167
|
-
var _a, _b;
|
|
168
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
169
|
-
var isInForeground, api, response, _c, _d;
|
|
170
|
-
return __generator(this, function (_e) {
|
|
171
|
-
switch (_e.label) {
|
|
172
|
-
case 0:
|
|
173
|
-
_e.trys.push([0, 4, , 5]);
|
|
174
|
-
isInForeground = VisibilityChangeObserver_1.VisibilityChangeObserver.isCurrentlyVisible();
|
|
175
|
-
api = (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.api) !== null && _b !== void 0 ? _b : DEFAULT_API;
|
|
176
|
-
if (!(!isInForeground && this._isBeaconSupported())) return [3 /*break*/, 1];
|
|
177
|
-
_c = this._sendEventsViaBeacon(api, events);
|
|
178
|
-
return [3 /*break*/, 3];
|
|
179
|
-
case 1: return [4 /*yield*/, this._sendEventsViaPost(api, events)];
|
|
180
|
-
case 2:
|
|
181
|
-
_c = _e.sent();
|
|
182
|
-
_e.label = 3;
|
|
183
|
-
case 3:
|
|
184
|
-
response = _c;
|
|
185
|
-
if (response.success) {
|
|
186
|
-
this._emitter({
|
|
187
|
-
event: 'logs_flushed',
|
|
188
|
-
events: events,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
this._saveFailedLogsToStorage(events);
|
|
193
|
-
}
|
|
194
|
-
return [3 /*break*/, 5];
|
|
195
|
-
case 4:
|
|
196
|
-
_d = _e.sent();
|
|
197
|
-
Log_1.Log.warn('Failed to flush events.');
|
|
198
|
-
return [3 /*break*/, 5];
|
|
199
|
-
case 5: return [2 /*return*/];
|
|
138
|
+
}
|
|
139
|
+
_sendEvents(events) {
|
|
140
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
+
if (this._isLoggingDisabled) {
|
|
142
|
+
this._saveFailedLogsToStorage(events);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const isInForeground = VisibilityChangeObserver_1.VisibilityChangeObserver.isCurrentlyVisible();
|
|
147
|
+
const response = !isInForeground && this._network.isBeaconSupported()
|
|
148
|
+
? yield this._sendEventsViaBeacon(events)
|
|
149
|
+
: yield this._sendEventsViaPost(events);
|
|
150
|
+
if (response.success) {
|
|
151
|
+
this._emitter({
|
|
152
|
+
name: 'logs_flushed',
|
|
153
|
+
events,
|
|
154
|
+
});
|
|
200
155
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
};
|
|
204
|
-
EventLogger.prototype._sendEventsViaPost = function (api, events) {
|
|
205
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
206
|
-
var result;
|
|
207
|
-
return __generator(this, function (_a) {
|
|
208
|
-
switch (_a.label) {
|
|
209
|
-
case 0: return [4 /*yield*/, this._network.post({
|
|
210
|
-
sdkKey: this._sdkKey,
|
|
211
|
-
data: {
|
|
212
|
-
events: events,
|
|
213
|
-
},
|
|
214
|
-
url: "".concat(api, "/rgstr"),
|
|
215
|
-
retries: 3,
|
|
216
|
-
headers: {
|
|
217
|
-
'Content-Type': 'application/json',
|
|
218
|
-
'STATSIG-EVENT-COUNT': String(events.length),
|
|
219
|
-
},
|
|
220
|
-
})];
|
|
221
|
-
case 1:
|
|
222
|
-
result = _a.sent();
|
|
223
|
-
if (result) {
|
|
224
|
-
return [2 /*return*/, JSON.parse(result)];
|
|
225
|
-
}
|
|
226
|
-
return [2 /*return*/, { success: false }];
|
|
156
|
+
else {
|
|
157
|
+
this._saveFailedLogsToStorage(events);
|
|
227
158
|
}
|
|
228
|
-
}
|
|
159
|
+
}
|
|
160
|
+
catch (_a) {
|
|
161
|
+
Log_1.Log.warn('Failed to flush events.');
|
|
162
|
+
}
|
|
229
163
|
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
|
|
164
|
+
}
|
|
165
|
+
_sendEventsViaPost(events) {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
167
|
+
const result = yield this._network.post({
|
|
234
168
|
sdkKey: this._sdkKey,
|
|
235
169
|
data: {
|
|
236
|
-
events
|
|
170
|
+
events,
|
|
237
171
|
},
|
|
238
|
-
url:
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
172
|
+
url: this._logEventUrl,
|
|
173
|
+
retries: 3,
|
|
174
|
+
params: {
|
|
175
|
+
// ec = Event Count
|
|
176
|
+
ec: String(events.length),
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
const response = (result === null || result === void 0 ? void 0 : result.body)
|
|
180
|
+
? (0, TypedJsonParse_1.typedJsonParse)(result.body, 'success', 'Failed to parse SendEventsResponse')
|
|
181
|
+
: null;
|
|
182
|
+
return { success: (response === null || response === void 0 ? void 0 : response.success) === true };
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
_sendEventsViaBeacon(events) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
return {
|
|
188
|
+
success: yield this._network.beacon({
|
|
189
|
+
sdkKey: this._sdkKey,
|
|
190
|
+
data: {
|
|
191
|
+
events,
|
|
192
|
+
},
|
|
193
|
+
url: this._logEventBeaconUrl,
|
|
194
|
+
}),
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
_saveFailedLogsToStorage(events) {
|
|
199
|
+
while (events.length > MAX_FAILED_LOGS) {
|
|
200
|
+
events.shift();
|
|
251
201
|
}
|
|
252
|
-
|
|
253
|
-
(0, StorageProvider_1.setObjectInStorage)(storageKey,
|
|
202
|
+
const storageKey = this._getStorageKey();
|
|
203
|
+
(0, StorageProvider_1.setObjectInStorage)(storageKey, events).catch(() => {
|
|
254
204
|
Log_1.Log.warn('Unable to save failed logs to storage');
|
|
255
205
|
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
return [2 /*return*/];
|
|
269
|
-
}
|
|
270
|
-
return [4 /*yield*/, this._sendEvents(events)];
|
|
271
|
-
case 2:
|
|
272
|
-
_a.sent();
|
|
273
|
-
return [2 /*return*/];
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
}); })().catch(function () {
|
|
277
|
-
Log_1.Log.warn('Unable to flush stored logs');
|
|
206
|
+
}
|
|
207
|
+
_retryFailedLogs() {
|
|
208
|
+
const storageKey = this._getStorageKey();
|
|
209
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
210
|
+
const events = yield (0, StorageProvider_1.getObjectFromStorage)(storageKey);
|
|
211
|
+
if (!events) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
yield StorageProvider_1.Storage.removeItem(storageKey);
|
|
215
|
+
yield this._sendEvents(events);
|
|
216
|
+
}))().catch(() => {
|
|
217
|
+
Log_1.Log.warn('Failed to flush stored logs');
|
|
278
218
|
});
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
219
|
+
}
|
|
220
|
+
_getStorageKey() {
|
|
221
|
+
return `statsig.failed_logs.${(0, Hashing_1.DJB2)(this._sdkKey)}`;
|
|
222
|
+
}
|
|
223
|
+
_normalizeAndAppendEvent(event) {
|
|
224
|
+
if (event.user) {
|
|
225
|
+
event.user = Object.assign({}, event.user);
|
|
226
|
+
delete event.user.privateAttributes;
|
|
227
|
+
}
|
|
228
|
+
const { sdkType, sdkVersion } = StatsigMetadata_1.StatsigMetadataProvider.get();
|
|
229
|
+
this._queue.push(Object.assign(Object.assign({}, event), { statsigMetadata: { sdkType, sdkVersion } }));
|
|
230
|
+
}
|
|
231
|
+
_appendAndResetNonExposedChecks() {
|
|
232
|
+
if (Object.keys(this._nonExposedChecks).length === 0) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this._normalizeAndAppendEvent({
|
|
236
|
+
eventName: 'statsig::non_exposed_checks',
|
|
237
|
+
user: null,
|
|
238
|
+
time: Date.now(),
|
|
239
|
+
metadata: {
|
|
240
|
+
checks: Object.assign({}, this._nonExposedChecks),
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
this._nonExposedChecks = {};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
285
246
|
exports.EventLogger = EventLogger;
|
package/src/Hashing.d.ts
CHANGED
package/src/Hashing.js
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DJB2 = void 0;
|
|
3
|
+
exports.DJB2Object = exports.DJB2 = void 0;
|
|
4
4
|
function DJB2(value) {
|
|
5
|
-
|
|
6
|
-
for (
|
|
7
|
-
|
|
5
|
+
let hash = 0;
|
|
6
|
+
for (let i = 0; i < value.length; i++) {
|
|
7
|
+
const character = value.charCodeAt(i);
|
|
8
8
|
hash = (hash << 5) - hash + character;
|
|
9
9
|
hash = hash & hash; // Convert to 32bit integer
|
|
10
10
|
}
|
|
11
11
|
return String(hash >>> 0);
|
|
12
12
|
}
|
|
13
13
|
exports.DJB2 = DJB2;
|
|
14
|
+
function DJB2Object(value) {
|
|
15
|
+
return DJB2(JSON.stringify(_getSortedObject(value)));
|
|
16
|
+
}
|
|
17
|
+
exports.DJB2Object = DJB2Object;
|
|
18
|
+
function _getSortedObject(object) {
|
|
19
|
+
if (object == null) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const keys = Object.keys(object).sort();
|
|
23
|
+
const sortedObject = {};
|
|
24
|
+
keys.forEach((key) => {
|
|
25
|
+
let value = object[key];
|
|
26
|
+
if (value instanceof Object) {
|
|
27
|
+
value = _getSortedObject(value);
|
|
28
|
+
}
|
|
29
|
+
sortedObject[key] = value;
|
|
30
|
+
});
|
|
31
|
+
return sortedObject;
|
|
32
|
+
}
|
package/src/Log.js
CHANGED
|
@@ -14,46 +14,27 @@ var LogLevel;
|
|
|
14
14
|
LogLevel[LogLevel["Info"] = 3] = "Info";
|
|
15
15
|
LogLevel[LogLevel["Debug"] = 4] = "Debug";
|
|
16
16
|
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
Log.info = function () {
|
|
21
|
-
var args = [];
|
|
22
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
23
|
-
args[_i] = arguments[_i];
|
|
24
|
-
}
|
|
17
|
+
class Log {
|
|
18
|
+
static info(...args) {
|
|
25
19
|
if (this.level >= LogLevel.Info) {
|
|
26
|
-
console.info
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
Log.debug = function () {
|
|
30
|
-
var args = [];
|
|
31
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
32
|
-
args[_i] = arguments[_i];
|
|
20
|
+
console.info(...addTag(args));
|
|
33
21
|
}
|
|
22
|
+
}
|
|
23
|
+
static debug(...args) {
|
|
34
24
|
if (this.level >= LogLevel.Debug) {
|
|
35
|
-
console.debug
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Log.warn = function () {
|
|
39
|
-
var args = [];
|
|
40
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
41
|
-
args[_i] = arguments[_i];
|
|
25
|
+
console.debug(...addTag(args));
|
|
42
26
|
}
|
|
27
|
+
}
|
|
28
|
+
static warn(...args) {
|
|
43
29
|
if (this.level >= LogLevel.Warn) {
|
|
44
|
-
console.warn
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
Log.error = function () {
|
|
48
|
-
var args = [];
|
|
49
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
50
|
-
args[_i] = arguments[_i];
|
|
30
|
+
console.warn(...addTag(args));
|
|
51
31
|
}
|
|
32
|
+
}
|
|
33
|
+
static error(...args) {
|
|
52
34
|
if (this.level >= LogLevel.Error) {
|
|
53
|
-
console.error
|
|
35
|
+
console.error(...addTag(args));
|
|
54
36
|
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return Log;
|
|
58
|
-
}());
|
|
37
|
+
}
|
|
38
|
+
}
|
|
59
39
|
exports.Log = Log;
|
|
40
|
+
Log.level = LogLevel.Error;
|
package/src/Monitoring.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
2
|
-
export declare function monitorClass
|
|
3
|
-
export declare function monitorFunction<T>(errorBoundary: ErrorBoundary, tag: string, func: () => T, instance: unknown): T;
|
|
2
|
+
export declare function monitorClass(errorBoundary: ErrorBoundary, instance: object): void;
|