@statsig/client-core 0.0.1-beta.40 → 0.0.1-beta.41

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": "0.0.1-beta.40",
3
+ "version": "0.0.1-beta.41",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -0,0 +1,4 @@
1
+ import { StatsigUser } from './StatsigUser';
2
+ export type CustomCacheKeyGenerator = (sdkKey: string, user: StatsigUser) => string;
3
+ export declare function _getUserStorageKey(sdkKey: string, user: StatsigUser, customKeyGenerator?: CustomCacheKeyGenerator): string;
4
+ export declare function _getStorageKey(sdkKey: string, user?: StatsigUser, customKeyGenerator?: CustomCacheKeyGenerator): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._getStorageKey = exports._getUserStorageKey = void 0;
4
+ const Hashing_1 = require("./Hashing");
5
+ function _getUserStorageKey(sdkKey, user, customKeyGenerator) {
6
+ var _a, _b;
7
+ if (customKeyGenerator) {
8
+ return customKeyGenerator(sdkKey, user);
9
+ }
10
+ const parts = [
11
+ `uid:${(_a = user === null || user === void 0 ? void 0 : user.userID) !== null && _a !== void 0 ? _a : ''}`,
12
+ `cids:${Object.entries((_b = user === null || user === void 0 ? void 0 : user.customIDs) !== null && _b !== void 0 ? _b : {})
13
+ .sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))
14
+ .map(([key, value]) => `${key}-${value}`)
15
+ .join(',')}`,
16
+ `k:${sdkKey}`,
17
+ ];
18
+ return (0, Hashing_1.DJB2)(parts.join('|'));
19
+ }
20
+ exports._getUserStorageKey = _getUserStorageKey;
21
+ function _getStorageKey(sdkKey, user, customKeyGenerator) {
22
+ if (user) {
23
+ return _getUserStorageKey(sdkKey, user, customKeyGenerator);
24
+ }
25
+ return (0, Hashing_1.DJB2)(`k:${sdkKey}`);
26
+ }
27
+ exports._getStorageKey = _getStorageKey;
@@ -3,12 +3,13 @@ import { AnyStatsigOptions } from './StatsigOptionsCommon';
3
3
  import { StatsigUser } from './StatsigUser';
4
4
  export declare abstract class DataAdapterCore {
5
5
  private _adapterName;
6
- private _cacheSuffix;
6
+ protected _cacheSuffix: string;
7
+ protected _options: AnyStatsigOptions | null;
7
8
  private _sdkKey;
8
9
  private _inMemoryCache;
9
10
  private _lastModifiedStoreKey;
10
11
  protected constructor(_adapterName: string, _cacheSuffix: string);
11
- attach(sdkKey: string, _options: AnyStatsigOptions | null): void;
12
+ attach(sdkKey: string, options: AnyStatsigOptions | null): void;
12
13
  getDataSync(user?: StatsigUser | undefined): DataAdapterResult | null;
13
14
  setData(data: string, user?: StatsigUser): void;
14
15
  /**
@@ -20,9 +21,9 @@ export declare abstract class DataAdapterCore {
20
21
  protected _getDataAsyncImpl(current: DataAdapterResult | null, user?: StatsigUser, options?: DataAdapterAsyncOptions): Promise<DataAdapterResult | null>;
21
22
  protected _prefetchDataImpl(user?: StatsigUser, options?: DataAdapterAsyncOptions): Promise<void>;
22
23
  protected abstract _fetchFromNetwork(current: string | null, user?: StatsigUser, options?: DataAdapterAsyncOptions): Promise<string | null>;
24
+ protected abstract _getCacheKey(user?: StatsigUser): string;
23
25
  private _fetchAndPrepFromNetwork;
24
26
  protected _getSdkKey(): string;
25
- protected _getCacheKey(user?: StatsigUser): string;
26
27
  protected _addToInMemoryCache(cacheKey: string, result: DataAdapterResult): void;
27
28
  private _loadFromCache;
28
29
  private _writeToCache;
@@ -11,7 +11,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.DataAdapterCore = void 0;
13
13
  const Log_1 = require("./Log");
14
- const StatsigDataAdapter_1 = require("./StatsigDataAdapter");
15
14
  const StatsigUser_1 = require("./StatsigUser");
16
15
  const StorageProvider_1 = require("./StorageProvider");
17
16
  const TypedJsonParse_1 = require("./TypedJsonParse");
@@ -20,12 +19,14 @@ class DataAdapterCore {
20
19
  constructor(_adapterName, _cacheSuffix) {
21
20
  this._adapterName = _adapterName;
22
21
  this._cacheSuffix = _cacheSuffix;
22
+ this._options = null;
23
23
  this._sdkKey = null;
24
24
  this._inMemoryCache = {};
25
25
  this._lastModifiedStoreKey = `statsig.last_modified_time.${_cacheSuffix}`;
26
26
  }
27
- attach(sdkKey, _options) {
27
+ attach(sdkKey, options) {
28
28
  this._sdkKey = sdkKey;
29
+ this._options = options;
29
30
  }
30
31
  getDataSync(user) {
31
32
  const cacheKey = this._getCacheKey(user);
@@ -41,7 +42,9 @@ class DataAdapterCore {
41
42
  return null;
42
43
  }
43
44
  setData(data, user) {
44
- const cacheKey = this._getCacheKey(user);
45
+ var _a;
46
+ const normalized = user && (0, StatsigUser_1._normalizeUser)(user, (_a = this._options) === null || _a === void 0 ? void 0 : _a.environment);
47
+ const cacheKey = this._getCacheKey(normalized);
45
48
  this._addToInMemoryCache(cacheKey, {
46
49
  source: 'Bootstrap',
47
50
  data,
@@ -116,10 +119,6 @@ class DataAdapterCore {
116
119
  Log_1.Log.error(`${this._adapterName} is not attached to a Client`);
117
120
  return '';
118
121
  }
119
- _getCacheKey(user) {
120
- const key = (0, StatsigUser_1.getUserStorageKey)(this._getSdkKey(), user);
121
- return `${StatsigDataAdapter_1.DataAdapterCachePrefix}.${this._cacheSuffix}.${key}`;
122
- }
123
122
  _addToInMemoryCache(cacheKey, result) {
124
123
  const entries = Object.entries(this._inMemoryCache);
125
124
  if (entries.length < CACHE_LIMIT) {
@@ -8,7 +8,7 @@ export declare class EventLogger {
8
8
  private _network;
9
9
  private _options;
10
10
  private _queue;
11
- private _flushTimer;
11
+ private _flushIntervalId;
12
12
  private _lastExposureTimeMap;
13
13
  private _nonExposedChecks;
14
14
  private _maxQueueSize;
@@ -16,7 +16,6 @@ const NetworkConfig_1 = require("./NetworkConfig");
16
16
  const SafeJs_1 = require("./SafeJs");
17
17
  const StatsigEvent_1 = require("./StatsigEvent");
18
18
  const StorageProvider_1 = require("./StorageProvider");
19
- const TypedJsonParse_1 = require("./TypedJsonParse");
20
19
  const UrlOverrides_1 = require("./UrlOverrides");
21
20
  const VisibilityObserving_1 = require("./VisibilityObserving");
22
21
  const DEFAULT_QUEUE_SIZE = 50;
@@ -50,13 +49,14 @@ class EventLogger {
50
49
  const flushInterval = (_b = _options === null || _options === void 0 ? void 0 : _options.loggingIntervalMs) !== null && _b !== void 0 ? _b : DEFAULT_FLUSH_INTERVAL_MS;
51
50
  const intervalId = setInterval(() => {
52
51
  const logger = EVENT_LOGGER_MAP[_sdkKey];
53
- if (!logger) {
52
+ if (logger._flushIntervalId !== intervalId) {
54
53
  clearInterval(intervalId);
55
- return;
56
54
  }
57
- _safeFlushAndForget(_sdkKey);
55
+ else {
56
+ _safeFlushAndForget(_sdkKey);
57
+ }
58
58
  }, flushInterval);
59
- this._flushTimer = intervalId;
59
+ this._flushIntervalId = intervalId;
60
60
  const config = _options === null || _options === void 0 ? void 0 : _options.networkConfig;
61
61
  this._logEventUrl = (0, UrlOverrides_1._getOverridableUrl)(config === null || config === void 0 ? void 0 : config.logEventUrl, config === null || config === void 0 ? void 0 : config.api, '/rgstr', NetworkConfig_1.NetworkDefault.eventsApi);
62
62
  this._logEventBeaconUrl = (0, UrlOverrides_1._getOverridableUrl)(config === null || config === void 0 ? void 0 : config.logEventBeaconUrl, config === null || config === void 0 ? void 0 : config.api, '/log_event_beacon', NetworkConfig_1.NetworkDefault.eventsApi);
@@ -90,9 +90,9 @@ class EventLogger {
90
90
  }
91
91
  shutdown() {
92
92
  return __awaiter(this, void 0, void 0, function* () {
93
- if (this._flushTimer) {
94
- clearInterval(this._flushTimer);
95
- this._flushTimer = null;
93
+ if (this._flushIntervalId) {
94
+ clearInterval(this._flushIntervalId);
95
+ this._flushIntervalId = null;
96
96
  }
97
97
  yield this.flush();
98
98
  });
@@ -176,6 +176,7 @@ class EventLogger {
176
176
  });
177
177
  }
178
178
  _sendEventsViaPost(events) {
179
+ var _a;
179
180
  return __awaiter(this, void 0, void 0, function* () {
180
181
  const result = yield this._network.post({
181
182
  sdkKey: this._sdkKey,
@@ -188,10 +189,8 @@ class EventLogger {
188
189
  [NetworkConfig_1.NetworkParam.EventCount]: String(events.length),
189
190
  },
190
191
  });
191
- const response = (result === null || result === void 0 ? void 0 : result.body)
192
- ? (0, TypedJsonParse_1.typedJsonParse)(result.body, 'success', 'Failed to parse SendEventsResponse')
193
- : null;
194
- return { success: (response === null || response === void 0 ? void 0 : response.success) === true };
192
+ const code = (_a = result === null || result === void 0 ? void 0 : result.code) !== null && _a !== void 0 ? _a : -1;
193
+ return { success: code >= 200 && code < 300 };
195
194
  });
196
195
  }
197
196
  _sendEventsViaBeacon(events) {
@@ -19,6 +19,7 @@ const SafeJs_1 = require("./SafeJs");
19
19
  const SessionID_1 = require("./SessionID");
20
20
  const StableID_1 = require("./StableID");
21
21
  const StatsigMetadata_1 = require("./StatsigMetadata");
22
+ const VisibilityObserving_1 = require("./VisibilityObserving");
22
23
  const DEFAULT_TIMEOUT_MS = 10000;
23
24
  class NetworkCore {
24
25
  constructor(_options, _emitter) {
@@ -65,6 +66,7 @@ class NetworkCore {
65
66
  const handle = setTimeout(() => controller.abort(`Timeout of ${this._timeout}ms expired.`), this._timeout);
66
67
  const url = yield this._getPopulatedURL(args);
67
68
  let response = null;
69
+ const keepalive = (0, VisibilityObserving_1._isUnloading)();
68
70
  try {
69
71
  const config = {
70
72
  method,
@@ -72,14 +74,14 @@ class NetworkCore {
72
74
  headers: Object.assign({}, args.headers),
73
75
  signal: controller.signal,
74
76
  priority: args.priority,
75
- keepalive: true,
77
+ keepalive,
76
78
  };
77
79
  const func = (_e = (_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.networkConfig) === null || _d === void 0 ? void 0 : _d.networkOverrideFunc) !== null && _e !== void 0 ? _e : fetch;
78
80
  response = yield func(url, config);
79
81
  clearTimeout(handle);
80
82
  if (!response.ok) {
81
83
  const text = yield response.text().catch(() => 'No Text');
82
- const err = new Error(`Failed to fetch: ${url} ${text}`);
84
+ const err = new Error(`NetworkError: ${url} ${text}`);
83
85
  err.name = 'NetworkError';
84
86
  throw err;
85
87
  }
package/src/SessionID.js CHANGED
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.StatsigSession = exports.SessionID = void 0;
13
- const Hashing_1 = require("./Hashing");
13
+ const CacheKey_1 = require("./CacheKey");
14
14
  const Log_1 = require("./Log");
15
15
  const StorageProvider_1 = require("./StorageProvider");
16
16
  const UUID_1 = require("./UUID");
@@ -80,7 +80,7 @@ function _hasRunTooLong({ startTime }) {
80
80
  return Date.now() - startTime > MAX_SESSION_AGE;
81
81
  }
82
82
  function _getSessionIDStorageKey(sdkKey) {
83
- return `statsig.session_id.${(0, Hashing_1.DJB2)(sdkKey)}`;
83
+ return `statsig.session_id.${(0, CacheKey_1._getStorageKey)(sdkKey)}`;
84
84
  }
85
85
  function _persistToStorage(session, sdkKey) {
86
86
  const storageKey = _getSessionIDStorageKey(sdkKey);
package/src/StableID.js CHANGED
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.StableID = void 0;
13
- const Hashing_1 = require("./Hashing");
13
+ const CacheKey_1 = require("./CacheKey");
14
14
  const Log_1 = require("./Log");
15
15
  const StorageProvider_1 = require("./StorageProvider");
16
16
  const UUID_1 = require("./UUID");
@@ -35,7 +35,7 @@ exports.StableID = {
35
35
  },
36
36
  };
37
37
  function _getStableIDStorageKey(sdkKey) {
38
- return `statsig.stable_id.${(0, Hashing_1.DJB2)(sdkKey)}`;
38
+ return `statsig.stable_id.${(0, CacheKey_1._getStorageKey)(sdkKey)}`;
39
39
  }
40
40
  function _persistToStorage(stableID, sdkKey) {
41
41
  const storageKey = _getStableIDStorageKey(sdkKey);
@@ -63,4 +63,5 @@ export declare abstract class StatsigClientBase<TAdapter extends EvaluationsData
63
63
  $emt(event: AnyStatsigClientEvent): void;
64
64
  protected _setStatus(newStatus: StatsigLoadingStatus, values: DataAdapterResult | null): void;
65
65
  protected _enqueueExposure(name: string, exposure: StatsigEventInternal, options?: EvaluationOptionsCommon): void;
66
+ protected abstract _primeReadyRipcord(): void;
66
67
  }
@@ -24,10 +24,7 @@ class StatsigClientBase {
24
24
  this.loadingStatus = 'Uninitialized';
25
25
  this._listeners = {};
26
26
  const emitter = this.$emt.bind(this);
27
- const statsigGlobal = (0, __StatsigGlobal_1._getStatsigGlobal)();
28
- const instances = (_a = statsigGlobal.instances) !== null && _a !== void 0 ? _a : {};
29
- const inst = this;
30
- (options === null || options === void 0 ? void 0 : options.logLevel) && (Log_1.Log.level = options === null || options === void 0 ? void 0 : options.logLevel);
27
+ (options === null || options === void 0 ? void 0 : options.logLevel) != null && (Log_1.Log.level = options.logLevel);
31
28
  (options === null || options === void 0 ? void 0 : options.disableStorage) && StorageProvider_1.Storage._setDisabled(true);
32
29
  (options === null || options === void 0 ? void 0 : options.overrideStableID) &&
33
30
  StableID_1.StableID.setOverride(options.overrideStableID, sdkKey);
@@ -37,17 +34,23 @@ class StatsigClientBase {
37
34
  this._errorBoundary.wrap(adapter);
38
35
  this._sdkKey = sdkKey;
39
36
  this._options = options !== null && options !== void 0 ? options : {};
40
- this._overrideAdapter = (_b = options === null || options === void 0 ? void 0 : options.overrideAdapter) !== null && _b !== void 0 ? _b : null;
37
+ this._overrideAdapter = (_a = options === null || options === void 0 ? void 0 : options.overrideAdapter) !== null && _a !== void 0 ? _a : null;
41
38
  this._logger = new EventLogger_1.EventLogger(sdkKey, emitter, network, options);
42
- if (instances[sdkKey] != null && (0, SafeJs_1._isBrowserEnv)()) {
43
- Log_1.Log.warn('Creating multiple Statsig clients with the same SDK key can lead to unexpected behavior. Multi-instance support requires different SDK keys.');
39
+ if ((0, SafeJs_1._isBrowserEnv)()) {
40
+ const statsigGlobal = (0, __StatsigGlobal_1._getStatsigGlobal)();
41
+ const instances = (_b = statsigGlobal.instances) !== null && _b !== void 0 ? _b : {};
42
+ const inst = this;
43
+ if (instances[sdkKey] != null) {
44
+ Log_1.Log.warn('Creating multiple Statsig clients with the same SDK key can lead to unexpected behavior. Multi-instance support requires different SDK keys.');
45
+ }
46
+ instances[sdkKey] = inst;
47
+ statsigGlobal.lastInstance = inst;
48
+ statsigGlobal.instances = instances;
49
+ __STATSIG__ = statsigGlobal;
44
50
  }
45
- instances[sdkKey] = inst;
46
- statsigGlobal.lastInstance = inst;
47
- statsigGlobal.instances = instances;
48
- __STATSIG__ = statsigGlobal;
49
51
  this.dataAdapter = adapter;
50
52
  this.dataAdapter.attach(sdkKey, options);
53
+ this._primeReadyRipcord();
51
54
  }
52
55
  /**
53
56
  * Updates runtime configuration options for the SDK, allowing toggling of certain behaviors such as logging and storage to comply with user preferences or regulations such as GDPR.
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "0.0.1-beta.40";
1
+ export declare const SDK_VERSION = "0.0.1-beta.41";
2
2
  export type StatsigMetadata = {
3
3
  readonly [key: string]: string | undefined;
4
4
  readonly appVersion?: string;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StatsigMetadataProvider = exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = '0.0.1-beta.40';
4
+ exports.SDK_VERSION = '0.0.1-beta.41';
5
5
  let metadata = {
6
6
  sdkVersion: exports.SDK_VERSION,
7
7
  sdkType: 'js-mono', // js-mono is overwritten by Precomp and OnDevice clients
@@ -15,7 +15,6 @@ export type StatsigUser = {
15
15
  export type StatsigUserInternal = StatsigUser & {
16
16
  statsigEnvironment?: StatsigEnvironment;
17
17
  };
18
- export declare function normalizeUser(original: StatsigUser, environment?: StatsigEnvironment): StatsigUser;
19
- export declare function getUserStorageKey(sdkKey: string, user?: StatsigUser): string;
18
+ export declare function _normalizeUser(original: StatsigUser, environment?: StatsigEnvironment): StatsigUser;
20
19
  export declare function getUnitIDFromUser(user: StatsigUser, idType: string): string | undefined;
21
20
  export {};
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUnitIDFromUser = exports.getUserStorageKey = exports.normalizeUser = void 0;
4
- const Hashing_1 = require("./Hashing");
5
- function normalizeUser(original, environment) {
3
+ exports.getUnitIDFromUser = exports._normalizeUser = void 0;
4
+ function _normalizeUser(original, environment) {
6
5
  try {
7
6
  const copy = JSON.parse(JSON.stringify(original));
8
7
  if (environment != null) {
@@ -14,11 +13,7 @@ function normalizeUser(original, environment) {
14
13
  throw new Error('User object must be convertable to JSON string.');
15
14
  }
16
15
  }
17
- exports.normalizeUser = normalizeUser;
18
- function getUserStorageKey(sdkKey, user) {
19
- return (0, Hashing_1.DJB2Object)({ sdkKey, user });
20
- }
21
- exports.getUserStorageKey = getUserStorageKey;
16
+ exports._normalizeUser = _normalizeUser;
22
17
  function getUnitIDFromUser(user, idType) {
23
18
  var _a, _b, _c;
24
19
  if (typeof idType === 'string' && idType.toLowerCase() !== 'userid') {
@@ -8,9 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var _a;
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
13
  exports._setObjectInStorage = exports._getObjectFromStorage = exports.Storage = void 0;
13
14
  const Log_1 = require("./Log");
15
+ const SafeJs_1 = require("./SafeJs");
14
16
  const inMemoryStore = {};
15
17
  const _resolve = (input) => Promise.resolve(input);
16
18
  const _inMemoryProvider = {
@@ -37,25 +39,26 @@ const _inMemoryProvider = {
37
39
  };
38
40
  let _localStorageProvider = null;
39
41
  try {
40
- if (typeof window !== 'undefined' && 'localStorage' in window) {
42
+ const win = (0, SafeJs_1._getWindowSafe)();
43
+ if (typeof ((_a = win === null || win === void 0 ? void 0 : win.localStorage) === null || _a === void 0 ? void 0 : _a.getItem) === 'function') {
41
44
  _localStorageProvider = {
42
45
  _getProviderName: () => 'LocalStorage',
43
46
  _getItemSync(key) {
44
- return localStorage.getItem(key);
47
+ return win.localStorage.getItem(key);
45
48
  },
46
49
  _getItem(key) {
47
- return _resolve(localStorage.getItem(key));
50
+ return _resolve(win.localStorage.getItem(key));
48
51
  },
49
52
  _setItem(key, value) {
50
- localStorage.setItem(key, value);
53
+ win.localStorage.setItem(key, value);
51
54
  return _resolve();
52
55
  },
53
56
  _removeItem(key) {
54
- localStorage.removeItem(key);
57
+ win.localStorage.removeItem(key);
55
58
  return _resolve();
56
59
  },
57
60
  _getAllKeys() {
58
- const keys = Object.keys(localStorage);
61
+ const keys = Object.keys(win.localStorage);
59
62
  return _resolve(keys);
60
63
  },
61
64
  };
@@ -3,6 +3,7 @@ declare const BACKGROUND = "background";
3
3
  export type Visibility = typeof FOREGROUND | typeof BACKGROUND;
4
4
  type VisibilityChangedCallback = (visibility: Visibility) => void;
5
5
  export declare const _isCurrentlyVisible: () => boolean;
6
+ export declare const _isUnloading: () => boolean;
6
7
  export declare const _subscribeToVisiblityChanged: (listener: VisibilityChangedCallback) => void;
7
8
  export declare const _notifyVisibilityChanged: (visibility: Visibility) => void;
8
9
  export {};
@@ -1,15 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._notifyVisibilityChanged = exports._subscribeToVisiblityChanged = exports._isCurrentlyVisible = void 0;
3
+ exports._notifyVisibilityChanged = exports._subscribeToVisiblityChanged = exports._isUnloading = exports._isCurrentlyVisible = void 0;
4
4
  const SafeJs_1 = require("./SafeJs");
5
5
  const FOREGROUND = 'foreground';
6
6
  const BACKGROUND = 'background';
7
7
  const LISTENERS = [];
8
8
  let current = FOREGROUND;
9
+ let isUnloading = false;
9
10
  const _isCurrentlyVisible = () => {
10
11
  return current === FOREGROUND;
11
12
  };
12
13
  exports._isCurrentlyVisible = _isCurrentlyVisible;
14
+ const _isUnloading = () => isUnloading;
15
+ exports._isUnloading = _isUnloading;
13
16
  const _subscribeToVisiblityChanged = (listener) => {
14
17
  LISTENERS.unshift(listener);
15
18
  };
@@ -22,9 +25,15 @@ const _notifyVisibilityChanged = (visibility) => {
22
25
  LISTENERS.forEach((l) => l(visibility));
23
26
  };
24
27
  exports._notifyVisibilityChanged = _notifyVisibilityChanged;
25
- (0, SafeJs_1._addWindowEventListenerSafe)('focus', () => (0, exports._notifyVisibilityChanged)(FOREGROUND));
28
+ (0, SafeJs_1._addWindowEventListenerSafe)('focus', () => {
29
+ isUnloading = false;
30
+ (0, exports._notifyVisibilityChanged)(FOREGROUND);
31
+ });
26
32
  (0, SafeJs_1._addWindowEventListenerSafe)('blur', () => (0, exports._notifyVisibilityChanged)(BACKGROUND));
27
- (0, SafeJs_1._addWindowEventListenerSafe)('beforeunload', () => (0, exports._notifyVisibilityChanged)(BACKGROUND));
33
+ (0, SafeJs_1._addWindowEventListenerSafe)('beforeunload', () => {
34
+ isUnloading = true;
35
+ (0, exports._notifyVisibilityChanged)(BACKGROUND);
36
+ });
28
37
  (0, SafeJs_1._addDocumentEventListenerSafe)('visibilitychange', () => {
29
38
  (0, exports._notifyVisibilityChanged)(document.visibilityState === 'visible' ? FOREGROUND : BACKGROUND);
30
39
  });
package/src/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { EventLogger } from './EventLogger';
4
4
  import { Log } from './Log';
5
5
  import { Storage } from './StorageProvider';
6
6
  export * from './$_StatsigGlobal';
7
+ export * from './CacheKey';
7
8
  export * from './ClientInterfaces';
8
9
  export * from './DataAdapterCore';
9
10
  export * from './DownloadConfigSpecsResponse';
package/src/index.js CHANGED
@@ -26,6 +26,7 @@ const StorageProvider_1 = require("./StorageProvider");
26
26
  Object.defineProperty(exports, "Storage", { enumerable: true, get: function () { return StorageProvider_1.Storage; } });
27
27
  const UUID_1 = require("./UUID");
28
28
  __exportStar(require("./$_StatsigGlobal"), exports);
29
+ __exportStar(require("./CacheKey"), exports);
29
30
  __exportStar(require("./ClientInterfaces"), exports);
30
31
  __exportStar(require("./DataAdapterCore"), exports);
31
32
  __exportStar(require("./DownloadConfigSpecsResponse"), exports);