@statsig/client-core 3.31.1-beta.2 → 3.31.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statsig/client-core",
3
- "version": "3.31.1-beta.2",
3
+ "version": "3.31.2",
4
4
  "license": "ISC",
5
5
  "homepage": "https://github.com/statsig-io/js-client-monorepo",
6
6
  "repository": {
@@ -10,8 +10,6 @@ export declare class ErrorBoundary {
10
10
  constructor(_sdkKey: string, _options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined, _lastSeenError?: Error | undefined);
11
11
  wrap(instance: unknown, namePrefix?: string): void;
12
12
  logError(tag: string, error: unknown): void;
13
- logDroppedEvents(count: number, reason: string, metadata?: Record<string, unknown>): void;
14
- logEventRequestFailure(count: number, reason: string, flushType: string, statusCode: number): void;
15
13
  getLastSeenErrorAndReset(): Error | null;
16
14
  attachErrorIfNoneExists(error: unknown): void;
17
15
  private _capture;
@@ -44,25 +44,6 @@ class ErrorBoundary {
44
44
  logError(tag, error) {
45
45
  this._onError(tag, error);
46
46
  }
47
- logDroppedEvents(count, reason, metadata) {
48
- const extra = {
49
- eventCount: String(count),
50
- };
51
- if (metadata) {
52
- Object.entries(metadata).forEach(([key, value]) => {
53
- extra[key] = String(value);
54
- });
55
- }
56
- this._onError(`statsig::log_event_dropped_event_count`, new Error(reason), true, extra);
57
- }
58
- logEventRequestFailure(count, reason, flushType, statusCode) {
59
- const extra = {
60
- eventCount: String(count),
61
- flushType: flushType,
62
- statusCode: String(statusCode),
63
- };
64
- this._onError(`statsig::log_event_failed`, new Error(reason), true, extra);
65
- }
66
47
  getLastSeenErrorAndReset() {
67
48
  const tempError = this._lastSeenError;
68
49
  this._lastSeenError = undefined;
@@ -87,7 +68,7 @@ class ErrorBoundary {
87
68
  return null;
88
69
  }
89
70
  }
90
- _onError(tag, error, bypassDedupe = false, extra) {
71
+ _onError(tag, error) {
91
72
  try {
92
73
  Log_1.Log.warn(`Caught error in ${tag}`, { error });
93
74
  const impl = () => __awaiter(this, void 0, void 0, function* () {
@@ -97,7 +78,7 @@ class ErrorBoundary {
97
78
  const name = isError ? unwrapped.name : 'No Name';
98
79
  const resolvedError = _resolveError(unwrapped);
99
80
  this._lastSeenError = resolvedError;
100
- if (!bypassDedupe && this._seen.has(name)) {
81
+ if (this._seen.has(name)) {
101
82
  return;
102
83
  }
103
84
  this._seen.add(name);
@@ -112,8 +93,7 @@ class ErrorBoundary {
112
93
  const sdkType = SDKType_1.SDKType._get(this._sdkKey);
113
94
  const statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
114
95
  const info = isError ? unwrapped.stack : _getDescription(unwrapped);
115
- const body = Object.assign({ tag, exception: name, info,
116
- extra, statsigOptions: _getStatsigOptionLoggingCopy(this._options) }, Object.assign(Object.assign({}, statsigMetadata), { sdkType }));
96
+ const body = Object.assign({ tag, exception: name, info, statsigOptions: _getStatsigOptionLoggingCopy(this._options) }, Object.assign(Object.assign({}, statsigMetadata), { sdkType }));
117
97
  const func = (_f = (_e = (_d = this._options) === null || _d === void 0 ? void 0 : _d.networkConfig) === null || _e === void 0 ? void 0 : _e.networkOverrideFunc) !== null && _f !== void 0 ? _f : fetch;
118
98
  yield func(exports.EXCEPTION_ENDPOINT, {
119
99
  method: 'POST',
@@ -1,4 +1,3 @@
1
- import { ErrorBoundary } from './ErrorBoundary';
2
1
  import { NetworkCore } from './NetworkCore';
3
2
  import { StatsigClientEmitEventFunc } from './StatsigClientBase';
4
3
  import { StatsigEventInternal } from './StatsigEvent';
@@ -8,18 +7,18 @@ export declare class EventLogger {
8
7
  private _emitter;
9
8
  private _network;
10
9
  private _options;
11
- private _errorBoundary;
12
- private _pendingEvents;
13
- private _batchQueue;
14
- private _flushCoordinator;
10
+ private _queue;
11
+ private _flushIntervalId;
15
12
  private _lastExposureTimeMap;
16
13
  private _nonExposedChecks;
14
+ private _maxQueueSize;
15
+ private _hasRunQuickFlush;
16
+ private _creationTime;
17
17
  private _loggingEnabled;
18
18
  private _logEventUrlConfig;
19
- private _isShuttingDown;
20
- private _storageKey;
21
19
  private static _safeFlushAndForget;
22
- constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon<NetworkConfigCommon> | null, _errorBoundary: ErrorBoundary);
20
+ private static _safeRetryFailedLogs;
21
+ constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon<NetworkConfigCommon> | null);
23
22
  setLogEventCompressionMode(mode: LogEventCompressionMode): void;
24
23
  setLoggingEnabled(loggingEnabled: LoggingEnabledOption): void;
25
24
  enqueue(event: StatsigEventInternal): void;
@@ -28,12 +27,22 @@ export declare class EventLogger {
28
27
  start(): void;
29
28
  stop(): Promise<void>;
30
29
  flush(): Promise<void>;
31
- appendAndResetNonExposedChecks(): void;
30
+ /**
31
+ * We 'Quick Flush' following the very first event enqueued
32
+ * within the quick flush window
33
+ */
34
+ private _quickFlushIfNeeded;
32
35
  private _shouldLogEvent;
33
- private _getCurrentPageUrl;
36
+ private _sendEvents;
37
+ private _sendEventsViaPost;
38
+ private _sendEventsViaBeacon;
39
+ private _getRequestData;
40
+ private _saveFailedLogsToStorage;
41
+ private _getFailedLogsFromStorage;
42
+ private _retryFailedLogs;
34
43
  private _getStorageKey;
35
- private _storeEventToStorage;
36
- private _getEventsFromStorage;
37
- private _loadStoredEvents;
38
- private _normalizeEvent;
44
+ private _normalizeAndAppendEvent;
45
+ private _appendAndResetNonExposedChecks;
46
+ private _getCurrentPageUrl;
47
+ private _startBackgroundFlushInterval;
39
48
  }
@@ -10,22 +10,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EventLogger = void 0;
13
- const BatchedEventsQueue_1 = require("./BatchedEventsQueue");
14
13
  const CacheKey_1 = require("./CacheKey");
15
- const EventRetryConstants_1 = require("./EventRetryConstants");
16
- const FlushCoordinator_1 = require("./FlushCoordinator");
17
14
  const Hashing_1 = require("./Hashing");
18
15
  const Log_1 = require("./Log");
19
16
  const NetworkConfig_1 = require("./NetworkConfig");
20
- const PendingEvents_1 = require("./PendingEvents");
21
17
  const SafeJs_1 = require("./SafeJs");
18
+ const SessionID_1 = require("./SessionID");
22
19
  const StatsigEvent_1 = require("./StatsigEvent");
23
20
  const StatsigOptionsCommon_1 = require("./StatsigOptionsCommon");
24
21
  const StorageProvider_1 = require("./StorageProvider");
25
22
  const UrlConfiguration_1 = require("./UrlConfiguration");
26
23
  const VisibilityObserving_1 = require("./VisibilityObserving");
24
+ const DEFAULT_QUEUE_SIZE = 100;
25
+ const DEFAULT_FLUSH_INTERVAL_MS = 10000;
27
26
  const MAX_DEDUPER_KEYS = 1000;
28
27
  const DEDUPER_WINDOW_DURATION_MS = 600000;
28
+ const MAX_FAILED_LOGS = 500;
29
+ const QUICK_FLUSH_WINDOW_MS = 200;
29
30
  const EVENT_LOGGER_MAP = {};
30
31
  class EventLogger {
31
32
  static _safeFlushAndForget(sdkKey) {
@@ -34,17 +35,21 @@ class EventLogger {
34
35
  // noop
35
36
  });
36
37
  }
37
- constructor(_sdkKey, _emitter, _network, _options, _errorBoundary) {
38
+ static _safeRetryFailedLogs(sdkKey) {
39
+ var _a;
40
+ (_a = EVENT_LOGGER_MAP[sdkKey]) === null || _a === void 0 ? void 0 : _a._retryFailedLogs();
41
+ }
42
+ constructor(_sdkKey, _emitter, _network, _options) {
38
43
  var _a, _b;
39
44
  this._sdkKey = _sdkKey;
40
45
  this._emitter = _emitter;
41
46
  this._network = _network;
42
47
  this._options = _options;
43
- this._errorBoundary = _errorBoundary;
48
+ this._queue = [];
44
49
  this._lastExposureTimeMap = {};
45
50
  this._nonExposedChecks = {};
46
- this._isShuttingDown = false;
47
- this._storageKey = null;
51
+ this._hasRunQuickFlush = false;
52
+ this._creationTime = Date.now();
48
53
  this._loggingEnabled =
49
54
  (_a = _options === null || _options === void 0 ? void 0 : _options.loggingEnabled) !== null && _a !== void 0 ? _a : ((_options === null || _options === void 0 ? void 0 : _options.disableLogging) === true
50
55
  ? StatsigOptionsCommon_1.LoggingEnabledOption.disabled
@@ -52,45 +57,34 @@ class EventLogger {
52
57
  if ((_options === null || _options === void 0 ? void 0 : _options.loggingEnabled) && _options.disableLogging !== undefined) {
53
58
  Log_1.Log.warn('Detected both loggingEnabled and disableLogging options. loggingEnabled takes precedence - please remove disableLogging.');
54
59
  }
60
+ this._maxQueueSize = (_b = _options === null || _options === void 0 ? void 0 : _options.loggingBufferMaxSize) !== null && _b !== void 0 ? _b : DEFAULT_QUEUE_SIZE;
55
61
  const config = _options === null || _options === void 0 ? void 0 : _options.networkConfig;
56
62
  this._logEventUrlConfig = new UrlConfiguration_1.UrlConfiguration(NetworkConfig_1.Endpoint._rgstr, config === null || config === void 0 ? void 0 : config.logEventUrl, config === null || config === void 0 ? void 0 : config.api, config === null || config === void 0 ? void 0 : config.logEventFallbackUrls);
57
- const batchSize = (_b = _options === null || _options === void 0 ? void 0 : _options.loggingBufferMaxSize) !== null && _b !== void 0 ? _b : EventRetryConstants_1.EventRetryConstants.DEFAULT_BATCH_SIZE;
58
- this._pendingEvents = new PendingEvents_1.PendingEvents(batchSize);
59
- this._batchQueue = new BatchedEventsQueue_1.BatchQueue(batchSize);
60
- this._flushCoordinator = new FlushCoordinator_1.FlushCoordinator(this._batchQueue, this._pendingEvents, () => this.appendAndResetNonExposedChecks(), this._sdkKey, this._network, this._emitter, this._logEventUrlConfig, this._options, this._loggingEnabled, this._errorBoundary);
61
63
  }
62
64
  setLogEventCompressionMode(mode) {
63
- this._flushCoordinator.setLogEventCompressionMode(mode);
65
+ this._network.setLogEventCompressionMode(mode);
64
66
  }
65
67
  setLoggingEnabled(loggingEnabled) {
66
- const wasDisabled = this._loggingEnabled === 'disabled';
67
- const isNowEnabled = loggingEnabled !== 'disabled';
68
- this._loggingEnabled = loggingEnabled;
69
- this._flushCoordinator.setLoggingEnabled(loggingEnabled);
70
- if (wasDisabled && isNowEnabled) {
71
- const events = this._loadStoredEvents();
72
- Log_1.Log.debug(`Loaded ${events.length} stored event(s) from storage`);
73
- if (events.length > 0) {
74
- events.forEach((event) => {
75
- this._flushCoordinator.addEvent(event);
76
- });
77
- this.flush().catch((error) => {
78
- Log_1.Log.warn('Failed to flush events after enabling logging:', error);
79
- });
68
+ if (this._loggingEnabled === 'disabled' && loggingEnabled !== 'disabled') {
69
+ // load any pre consented events into memory
70
+ const storageKey = this._getStorageKey();
71
+ const events = (0, StorageProvider_1._getObjectFromStorage)(storageKey);
72
+ if (events) {
73
+ this._queue.push(...events);
80
74
  }
75
+ StorageProvider_1.Storage.removeItem(storageKey);
81
76
  }
77
+ this._loggingEnabled = loggingEnabled;
82
78
  }
83
79
  enqueue(event) {
84
80
  if (!this._shouldLogEvent(event)) {
85
81
  return;
86
82
  }
87
- const normalizedEvent = this._normalizeEvent(event);
88
- if (this._loggingEnabled === 'disabled') {
89
- this._storeEventToStorage(normalizedEvent);
90
- return;
83
+ this._normalizeAndAppendEvent(event);
84
+ this._quickFlushIfNeeded();
85
+ if (this._queue.length > this._maxQueueSize) {
86
+ EventLogger._safeFlushAndForget(this._sdkKey);
91
87
  }
92
- this._flushCoordinator.addEvent(normalizedEvent);
93
- this._flushCoordinator.checkQuickFlush();
94
88
  }
95
89
  incrementNonExposureCount(name) {
96
90
  var _a;
@@ -117,41 +111,47 @@ class EventLogger {
117
111
  EventLogger._safeFlushAndForget(this._sdkKey);
118
112
  }
119
113
  else if (visibility === 'foreground') {
120
- this._flushCoordinator.startScheduledFlushCycle();
114
+ EventLogger._safeRetryFailedLogs(this._sdkKey);
121
115
  }
122
116
  });
123
117
  }
124
- this._flushCoordinator.loadAndRetryShutdownFailedEvents().catch((error) => {
125
- Log_1.Log.warn('Failed to load failed shutdown events:', error);
126
- });
127
- this._flushCoordinator.startScheduledFlushCycle();
118
+ this._retryFailedLogs();
119
+ this._startBackgroundFlushInterval();
128
120
  }
129
121
  stop() {
130
122
  return __awaiter(this, void 0, void 0, function* () {
131
- this._isShuttingDown = true;
132
- yield this._flushCoordinator.processShutdown();
123
+ if (this._flushIntervalId) {
124
+ clearInterval(this._flushIntervalId);
125
+ this._flushIntervalId = null;
126
+ }
133
127
  delete EVENT_LOGGER_MAP[this._sdkKey];
128
+ yield this.flush();
134
129
  });
135
130
  }
136
131
  flush() {
137
132
  return __awaiter(this, void 0, void 0, function* () {
138
- return this._flushCoordinator.processManualFlush();
133
+ this._appendAndResetNonExposedChecks();
134
+ if (this._queue.length === 0) {
135
+ return;
136
+ }
137
+ const events = this._queue;
138
+ this._queue = [];
139
+ yield this._sendEvents(events);
139
140
  });
140
141
  }
141
- appendAndResetNonExposedChecks() {
142
- if (Object.keys(this._nonExposedChecks).length === 0) {
142
+ /**
143
+ * We 'Quick Flush' following the very first event enqueued
144
+ * within the quick flush window
145
+ */
146
+ _quickFlushIfNeeded() {
147
+ if (this._hasRunQuickFlush) {
143
148
  return;
144
149
  }
145
- const event = this._normalizeEvent({
146
- eventName: 'statsig::non_exposed_checks',
147
- user: null,
148
- time: Date.now(),
149
- metadata: {
150
- checks: Object.assign({}, this._nonExposedChecks),
151
- },
152
- });
153
- this._flushCoordinator.addEvent(event);
154
- this._nonExposedChecks = {};
150
+ this._hasRunQuickFlush = true;
151
+ if (Date.now() - this._creationTime > QUICK_FLUSH_WINDOW_MS) {
152
+ return;
153
+ }
154
+ setTimeout(() => EventLogger._safeFlushAndForget(this._sdkKey), QUICK_FLUSH_WINDOW_MS);
155
155
  }
156
156
  _shouldLogEvent(event) {
157
157
  var _a;
@@ -186,54 +186,118 @@ class EventLogger {
186
186
  this._lastExposureTimeMap[key] = now;
187
187
  return true;
188
188
  }
189
- _getCurrentPageUrl() {
190
- var _a;
191
- if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.includeCurrentPageUrlWithEvents) === false) {
192
- return;
193
- }
194
- return (0, SafeJs_1._getCurrentPageUrlSafe)();
189
+ _sendEvents(events) {
190
+ return __awaiter(this, void 0, void 0, function* () {
191
+ var _a, _b;
192
+ if (this._loggingEnabled === 'disabled') {
193
+ this._saveFailedLogsToStorage(events);
194
+ return false;
195
+ }
196
+ try {
197
+ const isClosing = (0, VisibilityObserving_1._isUnloading)();
198
+ const shouldUseBeacon = isClosing &&
199
+ this._network.isBeaconSupported() &&
200
+ ((_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.networkConfig) === null || _b === void 0 ? void 0 : _b.networkOverrideFunc) == null;
201
+ this._emitter({
202
+ name: 'pre_logs_flushed',
203
+ events,
204
+ });
205
+ const response = shouldUseBeacon
206
+ ? this._sendEventsViaBeacon(events)
207
+ : yield this._sendEventsViaPost(events);
208
+ if (response.success) {
209
+ this._emitter({
210
+ name: 'logs_flushed',
211
+ events,
212
+ });
213
+ return true;
214
+ }
215
+ else {
216
+ Log_1.Log.warn('Failed to flush events.');
217
+ this._saveFailedLogsToStorage(events);
218
+ return false;
219
+ }
220
+ }
221
+ catch (_c) {
222
+ Log_1.Log.warn('Failed to flush events.');
223
+ return false;
224
+ }
225
+ });
195
226
  }
196
- _getStorageKey() {
197
- if (!this._storageKey) {
198
- this._storageKey = `statsig.pending_events.${(0, Hashing_1._DJB2)(this._sdkKey)}`;
199
- }
200
- return this._storageKey;
227
+ _sendEventsViaPost(events) {
228
+ return __awaiter(this, void 0, void 0, function* () {
229
+ var _a;
230
+ const result = yield this._network.post(this._getRequestData(events));
231
+ const code = (_a = result === null || result === void 0 ? void 0 : result.code) !== null && _a !== void 0 ? _a : -1;
232
+ return { success: code >= 200 && code < 300 };
233
+ });
234
+ }
235
+ _sendEventsViaBeacon(events) {
236
+ return {
237
+ success: this._network.beacon(this._getRequestData(events)),
238
+ };
239
+ }
240
+ _getRequestData(events) {
241
+ return {
242
+ sdkKey: this._sdkKey,
243
+ data: {
244
+ events,
245
+ },
246
+ urlConfig: this._logEventUrlConfig,
247
+ retries: 3,
248
+ isCompressable: true,
249
+ params: {
250
+ [NetworkConfig_1.NetworkParam.EventCount]: String(events.length),
251
+ },
252
+ credentials: 'same-origin',
253
+ };
201
254
  }
202
- _storeEventToStorage(event) {
255
+ _saveFailedLogsToStorage(events) {
256
+ while (events.length > MAX_FAILED_LOGS) {
257
+ events.shift();
258
+ }
203
259
  const storageKey = this._getStorageKey();
204
260
  try {
205
- let existingEvents = this._getEventsFromStorage(storageKey);
206
- existingEvents.push(event);
207
- if (existingEvents.length > EventRetryConstants_1.EventRetryConstants.MAX_LOCAL_STORAGE) {
208
- existingEvents = existingEvents.slice(-EventRetryConstants_1.EventRetryConstants.MAX_LOCAL_STORAGE);
209
- }
210
- (0, StorageProvider_1._setObjectInStorage)(storageKey, existingEvents);
261
+ const savedEvents = this._getFailedLogsFromStorage(storageKey);
262
+ (0, StorageProvider_1._setObjectInStorage)(storageKey, [...savedEvents, ...events]);
211
263
  }
212
- catch (error) {
213
- Log_1.Log.warn('Unable to save events to storage');
264
+ catch (_a) {
265
+ Log_1.Log.warn('Unable to save failed logs to storage');
214
266
  }
215
267
  }
216
- _getEventsFromStorage(storageKey) {
268
+ _getFailedLogsFromStorage(storageKey) {
269
+ let savedEvents = [];
217
270
  try {
218
- const events = (0, StorageProvider_1._getObjectFromStorage)(storageKey);
219
- if (Array.isArray(events)) {
220
- return events;
271
+ const retrieved = (0, StorageProvider_1._getObjectFromStorage)(storageKey);
272
+ if (Array.isArray(retrieved)) {
273
+ savedEvents = retrieved;
221
274
  }
222
- return [];
275
+ return savedEvents;
223
276
  }
224
277
  catch (_a) {
225
278
  return [];
226
279
  }
227
280
  }
228
- _loadStoredEvents() {
281
+ _retryFailedLogs() {
229
282
  const storageKey = this._getStorageKey();
230
- const events = this._getEventsFromStorage(storageKey);
231
- if (events.length > 0) {
283
+ (() => __awaiter(this, void 0, void 0, function* () {
284
+ if (!StorageProvider_1.Storage.isReady()) {
285
+ yield StorageProvider_1.Storage.isReadyResolver();
286
+ }
287
+ const events = (0, StorageProvider_1._getObjectFromStorage)(storageKey);
288
+ if (!events) {
289
+ return;
290
+ }
232
291
  StorageProvider_1.Storage.removeItem(storageKey);
233
- }
234
- return events;
292
+ yield this._sendEvents(events);
293
+ }))().catch(() => {
294
+ Log_1.Log.warn('Failed to flush stored logs');
295
+ });
235
296
  }
236
- _normalizeEvent(event) {
297
+ _getStorageKey() {
298
+ return `statsig.failed_logs.${(0, Hashing_1._DJB2)(this._sdkKey)}`;
299
+ }
300
+ _normalizeAndAppendEvent(event) {
237
301
  if (event.user) {
238
302
  event.user = Object.assign({}, event.user);
239
303
  delete event.user.privateAttributes;
@@ -243,7 +307,45 @@ class EventLogger {
243
307
  if (currentPage) {
244
308
  extras.statsigMetadata = { currentPage };
245
309
  }
246
- return Object.assign(Object.assign({}, event), extras);
310
+ const final = Object.assign(Object.assign({}, event), extras);
311
+ Log_1.Log.debug('Enqueued Event:', final);
312
+ this._queue.push(final);
313
+ }
314
+ _appendAndResetNonExposedChecks() {
315
+ if (Object.keys(this._nonExposedChecks).length === 0) {
316
+ return;
317
+ }
318
+ this._normalizeAndAppendEvent({
319
+ eventName: 'statsig::non_exposed_checks',
320
+ user: null,
321
+ time: Date.now(),
322
+ metadata: {
323
+ checks: Object.assign({}, this._nonExposedChecks),
324
+ },
325
+ });
326
+ this._nonExposedChecks = {};
327
+ }
328
+ _getCurrentPageUrl() {
329
+ var _a;
330
+ if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.includeCurrentPageUrlWithEvents) === false) {
331
+ return;
332
+ }
333
+ return (0, SafeJs_1._getCurrentPageUrlSafe)();
334
+ }
335
+ _startBackgroundFlushInterval() {
336
+ var _a, _b;
337
+ const flushInterval = (_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.loggingIntervalMs) !== null && _b !== void 0 ? _b : DEFAULT_FLUSH_INTERVAL_MS;
338
+ const intervalId = setInterval(() => {
339
+ const logger = EVENT_LOGGER_MAP[this._sdkKey];
340
+ if (!logger || logger._flushIntervalId !== intervalId) {
341
+ clearInterval(intervalId);
342
+ }
343
+ else {
344
+ EventLogger._safeFlushAndForget(this._sdkKey);
345
+ SessionID_1.StatsigSession.checkForIdleSession(this._sdkKey);
346
+ }
347
+ }, flushInterval);
348
+ this._flushIntervalId = intervalId;
247
349
  }
248
350
  }
249
351
  exports.EventLogger = EventLogger;
@@ -1,9 +1,7 @@
1
1
  export declare const EventRetryConstants: {
2
2
  readonly MAX_RETRY_ATTEMPTS: 5;
3
3
  readonly DEFAULT_BATCH_SIZE: 100;
4
- readonly MAX_PENDING_BATCHES: 30;
4
+ readonly MAX_PENDING_BATCHES: 10;
5
5
  readonly TICK_INTERVAL_MS: 1000;
6
- readonly QUICK_FLUSH_WINDOW_MS: 200;
7
- readonly MAX_LOCAL_STORAGE: 500;
8
6
  readonly MAX_QUEUED_EVENTS: number;
9
7
  };
@@ -4,10 +4,8 @@ exports.EventRetryConstants = void 0;
4
4
  exports.EventRetryConstants = {
5
5
  MAX_RETRY_ATTEMPTS: 5,
6
6
  DEFAULT_BATCH_SIZE: 100,
7
- MAX_PENDING_BATCHES: 30,
7
+ MAX_PENDING_BATCHES: 10,
8
8
  TICK_INTERVAL_MS: 1000,
9
- QUICK_FLUSH_WINDOW_MS: 200,
10
- MAX_LOCAL_STORAGE: 500,
11
9
  get MAX_QUEUED_EVENTS() {
12
10
  return this.DEFAULT_BATCH_SIZE * this.MAX_PENDING_BATCHES;
13
11
  },
@@ -5,7 +5,6 @@ import { StatsigClientEmitEventFunc } from './StatsigClientBase';
5
5
  import { AnyStatsigOptions, LogEventCompressionMode } from './StatsigOptionsCommon';
6
6
  import { Flatten } from './TypingUtils';
7
7
  import { UrlConfiguration } from './UrlConfiguration';
8
- export declare const RETRYABLE_CODES: Set<number>;
9
8
  type RequestArgs = {
10
9
  sdkKey: string;
11
10
  urlConfig: UrlConfiguration;
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.NetworkCore = exports.RETRYABLE_CODES = void 0;
12
+ exports.NetworkCore = void 0;
13
13
  require("./$_StatsigGlobal");
14
14
  const __StatsigGlobal_1 = require("./$_StatsigGlobal");
15
15
  const Diagnostics_1 = require("./Diagnostics");
@@ -31,9 +31,7 @@ const BACKOFF_MAX_MS = 30000;
31
31
  const RATE_LIMIT_WINDOW_MS = 1000;
32
32
  const RATE_LIMIT_MAX_REQ_COUNT = 50;
33
33
  const LEAK_RATE = RATE_LIMIT_MAX_REQ_COUNT / RATE_LIMIT_WINDOW_MS;
34
- exports.RETRYABLE_CODES = new Set([
35
- 408, 500, 502, 503, 504, 522, 524, 599,
36
- ]);
34
+ const RETRYABLE_CODES = new Set([408, 500, 502, 503, 504, 522, 524, 599]);
37
35
  class NetworkCore {
38
36
  constructor(options, _emitter) {
39
37
  this._emitter = _emitter;
@@ -163,7 +161,7 @@ class NetworkCore {
163
161
  }
164
162
  if (!retries ||
165
163
  currentAttempt > retries ||
166
- !exports.RETRYABLE_CODES.has((_b = response === null || response === void 0 ? void 0 : response.status) !== null && _b !== void 0 ? _b : 500)) {
164
+ !RETRYABLE_CODES.has((_b = response === null || response === void 0 ? void 0 : response.status) !== null && _b !== void 0 ? _b : 500)) {
167
165
  (_c = this._emitter) === null || _c === void 0 ? void 0 : _c.call(this, {
168
166
  name: 'error',
169
167
  error,
@@ -1,4 +1,3 @@
1
- type SessionTimeoutID = ReturnType<typeof setTimeout>;
2
1
  type SessionData = {
3
2
  sessionID: string;
4
3
  startTime: number;
@@ -7,8 +6,8 @@ type SessionData = {
7
6
  export type StatsigSession = {
8
7
  data: SessionData;
9
8
  sdkKey: string;
10
- ageTimeoutID?: SessionTimeoutID;
11
- idleTimeoutID?: SessionTimeoutID;
9
+ lastPersistedAt: number;
10
+ storageKey: string;
12
11
  };
13
12
  export declare const SessionID: {
14
13
  get: (sdkKey: string) => string;
@@ -16,5 +15,6 @@ export declare const SessionID: {
16
15
  export declare const StatsigSession: {
17
16
  get: (sdkKey: string, bumpSession?: boolean) => StatsigSession;
18
17
  overrideInitialSessionID: (override: string, sdkKey: string) => void;
18
+ checkForIdleSession: (sdkKey: string) => void;
19
19
  };
20
20
  export {};