@statsig/client-core 0.0.1-beta.29 → 0.0.1-beta.30

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.
Files changed (46) hide show
  1. package/package.json +1 -1
  2. package/src/$_StatsigGlobal.d.ts +2 -0
  3. package/src/$_StatsigGlobal.js +10 -4
  4. package/src/ClientInterfaces.d.ts +20 -9
  5. package/src/DataAdapterCore.d.ts +2 -2
  6. package/src/DataAdapterCore.js +6 -6
  7. package/src/Diagnostics.js +4 -1
  8. package/src/DownloadConfigSpecsResponse.d.ts +41 -0
  9. package/src/DownloadConfigSpecsResponse.js +2 -0
  10. package/src/ErrorBoundary.js +4 -2
  11. package/src/EventLogger.d.ts +3 -4
  12. package/src/EventLogger.js +18 -19
  13. package/src/Hashing.d.ts +2 -2
  14. package/src/Hashing.js +7 -7
  15. package/src/NetworkCore.d.ts +5 -2
  16. package/src/NetworkCore.js +27 -12
  17. package/src/NetworkDefaults.d.ts +5 -0
  18. package/src/NetworkDefaults.js +8 -0
  19. package/src/NetworkParams.d.ts +9 -0
  20. package/src/NetworkParams.js +13 -0
  21. package/src/OverrideAdapter.d.ts +0 -7
  22. package/src/OverrideAdapter.js +0 -22
  23. package/src/SDKType.d.ts +8 -0
  24. package/src/SDKType.js +19 -0
  25. package/src/SafeJs.d.ts +4 -0
  26. package/src/SafeJs.js +27 -0
  27. package/src/SessionID.js +4 -4
  28. package/src/StableID.js +2 -2
  29. package/src/StatsigClientBase.d.ts +4 -4
  30. package/src/StatsigClientBase.js +7 -6
  31. package/src/StatsigClientEventEmitter.d.ts +1 -0
  32. package/src/StatsigDataAdapter.d.ts +2 -2
  33. package/src/StatsigEvent.d.ts +4 -4
  34. package/src/StatsigEvent.js +20 -20
  35. package/src/StatsigMetadata.d.ts +1 -2
  36. package/src/StatsigMetadata.js +1 -1
  37. package/src/StatsigOptionsCommon.d.ts +27 -12
  38. package/src/StatsigTypeFactories.js +9 -22
  39. package/src/StorageProvider.d.ts +10 -10
  40. package/src/StorageProvider.js +27 -27
  41. package/src/VisibilityObserving.d.ts +8 -0
  42. package/src/VisibilityObserving.js +30 -0
  43. package/src/index.d.ts +6 -1
  44. package/src/index.js +6 -1
  45. package/src/VisibilityChangeObserver.d.ts +0 -13
  46. package/src/VisibilityChangeObserver.js +0 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statsig/client-core",
3
- "version": "0.0.1-beta.29",
3
+ "version": "0.0.1-beta.30",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -5,6 +5,7 @@ export type StatsigGlobal = {
5
5
  lastInstance?: StatsigClientInterface;
6
6
  acInstances?: Record<string, unknown>;
7
7
  srInstances?: Record<string, unknown>;
8
+ instance?: (sdkKey: string) => StatsigClientInterface | undefined;
8
9
  };
9
10
  declare global {
10
11
  let __STATSIG__: StatsigGlobal | undefined;
@@ -12,3 +13,4 @@ declare global {
12
13
  __STATSIG__: StatsigGlobal | undefined;
13
14
  }
14
15
  }
16
+ export declare const _getStatsigGlobal: () => StatsigGlobal;
@@ -2,10 +2,16 @@
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
3
  var _a, _b, _c;
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports._getStatsigGlobal = void 0;
6
+ const GLOBAL_KEY = '__STATSIG__';
5
7
  const _window = typeof window !== 'undefined' ? window : {};
6
8
  const _global = typeof global !== 'undefined' ? global : {};
7
9
  const _globalThis = typeof globalThis !== 'undefined' ? globalThis : {};
8
- const statsigGlobal = (_c = (_b = (_a = _window.__STATSIG__) !== null && _a !== void 0 ? _a : _global.__STATSIG__) !== null && _b !== void 0 ? _b : _globalThis.__STATSIG__) !== null && _c !== void 0 ? _c : {};
9
- _window.__STATSIG__ = statsigGlobal;
10
- _global.__STATSIG__ = statsigGlobal;
11
- _globalThis.__STATSIG__ = statsigGlobal;
10
+ const statsigGlobal = (_c = (_b = (_a = _window[GLOBAL_KEY]) !== null && _a !== void 0 ? _a : _global[GLOBAL_KEY]) !== null && _b !== void 0 ? _b : _globalThis[GLOBAL_KEY]) !== null && _c !== void 0 ? _c : {};
11
+ _window[GLOBAL_KEY] = statsigGlobal;
12
+ _global[GLOBAL_KEY] = statsigGlobal;
13
+ _globalThis[GLOBAL_KEY] = statsigGlobal;
14
+ const _getStatsigGlobal = () => {
15
+ return __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : statsigGlobal;
16
+ };
17
+ exports._getStatsigGlobal = _getStatsigGlobal;
@@ -1,11 +1,13 @@
1
+ import { DownloadConfigSpecsResponse } from './DownloadConfigSpecsResponse';
1
2
  import { DynamicConfigEvaluationOptions, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, LayerEvaluationOptions } from './EvaluationOptions';
2
3
  import { InitializeResponseWithUpdates } from './InitializeResponse';
3
4
  import { StatsigClientEventEmitterInterface } from './StatsigClientEventEmitter';
4
5
  import { EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
5
6
  import { StatsigEvent } from './StatsigEvent';
6
- import { StatsigOptionsCommon, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
7
+ import { AnyStatsigOptions, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
7
8
  import { DynamicConfig, Experiment, FeatureGate, Layer } from './StatsigTypes';
8
9
  import { StatsigUser } from './StatsigUser';
10
+ import { Flatten } from './UtitlityTypes';
9
11
  export interface StatsigClientCommonInterface extends StatsigClientEventEmitterInterface {
10
12
  initializeSync(): void;
11
13
  initializeAsync(): Promise<void>;
@@ -13,8 +15,22 @@ export interface StatsigClientCommonInterface extends StatsigClientEventEmitterI
13
15
  flush(): Promise<void>;
14
16
  updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
15
17
  }
18
+ export type CommonContext = {
19
+ sdkKey: string;
20
+ options: AnyStatsigOptions;
21
+ };
22
+ export type AsyncCommonContext = {
23
+ sessionID: string;
24
+ stableID: string;
25
+ };
26
+ export type OnDeviceEvaluationsContext = CommonContext & {
27
+ values: DownloadConfigSpecsResponse | null;
28
+ };
29
+ export type OnDeviceEvaluationsAsyncContext = OnDeviceEvaluationsContext & AsyncCommonContext;
16
30
  export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterface {
17
31
  readonly dataAdapter: SpecsDataAdapter;
32
+ getAsyncContext(): Promise<OnDeviceEvaluationsAsyncContext>;
33
+ getContext(): OnDeviceEvaluationsContext;
18
34
  checkGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): boolean;
19
35
  getFeatureGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): FeatureGate;
20
36
  getDynamicConfig(name: string, user: StatsigUser, options?: DynamicConfigEvaluationOptions): DynamicConfig;
@@ -23,16 +39,11 @@ export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterfa
23
39
  logEvent(event: StatsigEvent, user: StatsigUser): void;
24
40
  logEvent(eventName: string, user: StatsigUser, value?: string | number, metadata?: Record<string, string>): void;
25
41
  }
26
- export type PrecomputedEvaluationsContext = {
27
- sdkKey: string;
28
- options: StatsigOptionsCommon;
42
+ export type PrecomputedEvaluationsContext = Flatten<CommonContext & {
29
43
  values: InitializeResponseWithUpdates | null;
30
44
  user: StatsigUser;
31
- };
32
- export type PrecomputedEvaluationsAsyncContext = {
33
- sessionID: string;
34
- stableID: string;
35
- } & PrecomputedEvaluationsContext;
45
+ }>;
46
+ export type PrecomputedEvaluationsAsyncContext = Flatten<AsyncCommonContext & PrecomputedEvaluationsContext>;
36
47
  export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
37
48
  readonly dataAdapter: EvaluationsDataAdapter;
38
49
  getAsyncContext(): Promise<PrecomputedEvaluationsAsyncContext>;
@@ -1,6 +1,6 @@
1
1
  import { ErrorBoundary } from './ErrorBoundary';
2
2
  import { DataAdapterResult } from './StatsigDataAdapter';
3
- import { StatsigOptionsCommon } from './StatsigOptionsCommon';
3
+ import { AnyStatsigOptions } from './StatsigOptionsCommon';
4
4
  import { StatsigUser } from './StatsigUser';
5
5
  export declare abstract class DataAdapterCore {
6
6
  private _adapterName;
@@ -10,7 +10,7 @@ export declare abstract class DataAdapterCore {
10
10
  private _inMemoryCache;
11
11
  private _lastModifiedStoreKey;
12
12
  protected constructor(_adapterName: string, _cacheSuffix: string);
13
- attach(sdkKey: string, _options: StatsigOptionsCommon | null): void;
13
+ attach(sdkKey: string, _options: AnyStatsigOptions | null): void;
14
14
  getDataSync(user?: StatsigUser | undefined): DataAdapterResult | null;
15
15
  getDataAsync(current: DataAdapterResult | null, user?: StatsigUser): Promise<DataAdapterResult | null>;
16
16
  prefetchData(user?: StatsigUser | undefined): Promise<void>;
@@ -132,7 +132,7 @@ class DataAdapterCore {
132
132
  }
133
133
  _loadFromCache(cacheKey) {
134
134
  var _a;
135
- const cache = (_a = StorageProvider_1.Storage.getItemSync) === null || _a === void 0 ? void 0 : _a.call(StorageProvider_1.Storage, cacheKey);
135
+ const cache = (_a = StorageProvider_1.Storage._getItemSync) === null || _a === void 0 ? void 0 : _a.call(StorageProvider_1.Storage, cacheKey);
136
136
  if (cache == null) {
137
137
  return null;
138
138
  }
@@ -141,26 +141,26 @@ class DataAdapterCore {
141
141
  }
142
142
  _writeToCache(cacheKey, result) {
143
143
  return __awaiter(this, void 0, void 0, function* () {
144
- yield StorageProvider_1.Storage.setItem(cacheKey, JSON.stringify(result));
144
+ yield StorageProvider_1.Storage._setItem(cacheKey, JSON.stringify(result));
145
145
  yield this._runLocalStorageCacheEviction(cacheKey);
146
146
  });
147
147
  }
148
148
  _runLocalStorageCacheEviction(cacheKey) {
149
149
  var _a;
150
150
  return __awaiter(this, void 0, void 0, function* () {
151
- const lastModifiedTimeMap = (_a = (yield (0, StorageProvider_1.getObjectFromStorage)(this._lastModifiedStoreKey))) !== null && _a !== void 0 ? _a : {};
151
+ const lastModifiedTimeMap = (_a = (yield (0, StorageProvider_1._getObjectFromStorage)(this._lastModifiedStoreKey))) !== null && _a !== void 0 ? _a : {};
152
152
  lastModifiedTimeMap[cacheKey] = Date.now();
153
153
  const entries = Object.entries(lastModifiedTimeMap);
154
154
  if (entries.length <= CACHE_LIMIT) {
155
- yield (0, StorageProvider_1.setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
155
+ yield (0, StorageProvider_1._setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
156
156
  return;
157
157
  }
158
158
  const oldest = entries.reduce((acc, current) => {
159
159
  return current[1] < acc[1] ? current : acc;
160
160
  });
161
161
  delete lastModifiedTimeMap[oldest[0]];
162
- yield StorageProvider_1.Storage.removeItem(oldest[0]);
163
- yield (0, StorageProvider_1.setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
162
+ yield StorageProvider_1.Storage._removeItem(oldest[0]);
163
+ yield (0, StorageProvider_1._setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
164
164
  });
165
165
  }
166
166
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Diagnostics = exports.captureDiagnostics = void 0;
4
4
  const Log_1 = require("./Log");
5
+ const NetworkDefaults_1 = require("./NetworkDefaults");
5
6
  const SUPPORTS_PERFORMANCE_API = typeof performance !== 'undefined' && typeof performance.mark !== 'undefined';
6
7
  let markers = [];
7
8
  function captureDiagnostics(func, task) {
@@ -31,7 +32,9 @@ class Diagnostics {
31
32
  static flush() {
32
33
  const resources = performance
33
34
  .getEntriesByType('resource')
34
- .filter((resource) => resource.name.startsWith('https://api.statsig.com'));
35
+ .filter((resource) => resource.name.startsWith(NetworkDefaults_1.NetworkDefault.initializeApi) ||
36
+ resource.name.startsWith(NetworkDefaults_1.NetworkDefault.specsApi) ||
37
+ resource.name.startsWith(NetworkDefaults_1.NetworkDefault.eventsApi));
35
38
  const payload = {
36
39
  markers,
37
40
  resources,
@@ -0,0 +1,41 @@
1
+ export type SpecCondition = {
2
+ type: string;
3
+ targetValue: unknown;
4
+ operator: string | null;
5
+ field: string | null;
6
+ additionalValues: Record<string, unknown> | null;
7
+ idType: string;
8
+ };
9
+ export type SpecRule = {
10
+ name: string;
11
+ passPercentage: number;
12
+ conditions: SpecCondition[];
13
+ returnValue: unknown;
14
+ id: string;
15
+ salt: string;
16
+ idType: string;
17
+ configDelegate: string | null;
18
+ isExperimentGroup?: boolean;
19
+ groupName?: string;
20
+ };
21
+ export type Spec = {
22
+ name: string;
23
+ type: string;
24
+ salt: string;
25
+ defaultValue: unknown;
26
+ enabled: boolean;
27
+ idType: string;
28
+ rules: SpecRule[];
29
+ entity: string;
30
+ explicitParameters: string[] | null;
31
+ hasSharedParams: boolean;
32
+ isActive?: boolean;
33
+ targetAppIDs?: string[];
34
+ };
35
+ export type DownloadConfigSpecsResponse = {
36
+ feature_gates: Spec[];
37
+ dynamic_configs: Spec[];
38
+ layer_configs: Spec[];
39
+ time: number;
40
+ has_updates: boolean;
41
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ErrorBoundary = exports.EXCEPTION_ENDPOINT = void 0;
13
13
  const Log_1 = require("./Log");
14
+ const SDKType_1 = require("./SDKType");
14
15
  const StatsigMetadata_1 = require("./StatsigMetadata");
15
16
  exports.EXCEPTION_ENDPOINT = 'https://statsigapi.net/v1/sdk_exception';
16
17
  class ErrorBoundary {
@@ -45,14 +46,15 @@ class ErrorBoundary {
45
46
  return;
46
47
  }
47
48
  this._seen.add(name);
49
+ const sdkType = SDKType_1.SDKType._get(this._sdkKey);
48
50
  const statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
49
51
  const info = isError ? unwrapped.stack : _getDescription(unwrapped);
50
- const body = JSON.stringify(Object.assign({ tag, exception: name, info }, statsigMetadata));
52
+ const body = JSON.stringify(Object.assign({ tag, exception: name, info }, Object.assign(Object.assign({}, statsigMetadata), { sdkType })));
51
53
  yield fetch(exports.EXCEPTION_ENDPOINT, {
52
54
  method: 'POST',
53
55
  headers: {
54
56
  'STATSIG-API-KEY': this._sdkKey,
55
- 'STATSIG-SDK-TYPE': String(statsigMetadata.sdkType),
57
+ 'STATSIG-SDK-TYPE': String(sdkType),
56
58
  'STATSIG-SDK-VERSION': String(statsigMetadata.sdkVersion),
57
59
  'Content-Type': 'application/json',
58
60
  },
@@ -1,8 +1,7 @@
1
1
  import { NetworkCore } from './NetworkCore';
2
2
  import { StatsigClientEmitEventFunc } from './StatsigClientBase';
3
3
  import { StatsigEventInternal } from './StatsigEvent';
4
- import { StatsigOptionsCommon } from './StatsigOptionsCommon';
5
- import { Visibility } from './VisibilityChangeObserver';
4
+ import { NetworkConfigCommon, StatsigOptionsCommon } from './StatsigOptionsCommon';
6
5
  export declare class EventLogger {
7
6
  private _sdkKey;
8
7
  private _emitter;
@@ -18,14 +17,14 @@ export declare class EventLogger {
18
17
  private _isLoggingDisabled;
19
18
  private _logEventUrl;
20
19
  private _logEventBeaconUrl;
21
- constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon | null);
20
+ constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon<NetworkConfigCommon> | null);
22
21
  setLoggingDisabled(isDisabled: boolean): void;
23
22
  enqueue(event: StatsigEventInternal): void;
24
23
  incrementNonExposureCount(name: string): void;
25
24
  reset(): void;
26
- onVisibilityChanged(visibility: Visibility): void;
27
25
  shutdown(): Promise<void>;
28
26
  flush(): Promise<void>;
27
+ private _onVisibilityChanged;
29
28
  /**
30
29
  * We 'Quick Flush' following the very first event enqueued
31
30
  * within the quick flush window
@@ -12,19 +12,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EventLogger = void 0;
13
13
  const Hashing_1 = require("./Hashing");
14
14
  const Log_1 = require("./Log");
15
+ const NetworkDefaults_1 = require("./NetworkDefaults");
16
+ const NetworkParams_1 = require("./NetworkParams");
15
17
  const StatsigEvent_1 = require("./StatsigEvent");
16
18
  const StorageProvider_1 = require("./StorageProvider");
17
19
  const TypedJsonParse_1 = require("./TypedJsonParse");
18
20
  const UrlOverrides_1 = require("./UrlOverrides");
19
- const VisibilityChangeObserver_1 = require("./VisibilityChangeObserver");
21
+ const VisibilityObserving_1 = require("./VisibilityObserving");
20
22
  const DEFAULT_QUEUE_SIZE = 50;
21
23
  const DEFAULT_FLUSH_INTERVAL_MS = 10000;
22
24
  const MAX_DEDUPER_KEYS = 1000;
23
25
  const DEDUPER_WINDOW_DURATION_MS = 60000;
24
26
  const MAX_FAILED_LOGS = 500;
25
- const DEFAULT_API = 'https://api.statsig.com/v1';
26
- const DEFAULT_ENDPOINT = '/rgstr';
27
- const DEFAULT_BEACON_ENDPOINT = '/log_event_beacon';
28
27
  const QUICK_FLUSH_WINDOW_MS = 200;
29
28
  class EventLogger {
30
29
  constructor(_sdkKey, _emitter, _network, _options) {
@@ -42,9 +41,10 @@ class EventLogger {
42
41
  this._maxQueueSize = (_a = _options === null || _options === void 0 ? void 0 : _options.loggingBufferMaxSize) !== null && _a !== void 0 ? _a : DEFAULT_QUEUE_SIZE;
43
42
  const flushInterval = (_b = _options === null || _options === void 0 ? void 0 : _options.loggingIntervalMs) !== null && _b !== void 0 ? _b : DEFAULT_FLUSH_INTERVAL_MS;
44
43
  this._flushTimer = setInterval(() => this._flushAndForget(), flushInterval);
45
- 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);
46
- 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);
47
- VisibilityChangeObserver_1.VisibilityChangeObserver.add(this);
44
+ const config = _options === null || _options === void 0 ? void 0 : _options.networkConfig;
45
+ 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', NetworkDefaults_1.NetworkDefault.eventsApi);
46
+ 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', NetworkDefaults_1.NetworkDefault.eventsApi);
47
+ (0, VisibilityObserving_1._subscribeToVisiblityChanged)(this._onVisibilityChanged.bind(this));
48
48
  this._retryFailedLogs();
49
49
  }
50
50
  setLoggingDisabled(isDisabled) {
@@ -68,11 +68,6 @@ class EventLogger {
68
68
  reset() {
69
69
  this._lastExposureTimeMap = {};
70
70
  }
71
- onVisibilityChanged(visibility) {
72
- if (visibility === 'background') {
73
- this._flushAndForget();
74
- }
75
- }
76
71
  shutdown() {
77
72
  return __awaiter(this, void 0, void 0, function* () {
78
73
  if (this._flushTimer) {
@@ -93,6 +88,11 @@ class EventLogger {
93
88
  yield this._sendEvents(events);
94
89
  });
95
90
  }
91
+ _onVisibilityChanged(visibility) {
92
+ if (visibility === 'background') {
93
+ this._flushAndForget();
94
+ }
95
+ }
96
96
  /**
97
97
  * We 'Quick Flush' following the very first event enqueued
98
98
  * within the quick flush window
@@ -109,7 +109,7 @@ class EventLogger {
109
109
  }
110
110
  _shouldLogEvent(event) {
111
111
  var _a, _b, _c, _d;
112
- if (!(0, StatsigEvent_1.isExposureEvent)(event)) {
112
+ if (!(0, StatsigEvent_1._isExposureEvent)(event)) {
113
113
  return true;
114
114
  }
115
115
  const key = [
@@ -142,7 +142,7 @@ class EventLogger {
142
142
  return;
143
143
  }
144
144
  try {
145
- const isInForeground = VisibilityChangeObserver_1.VisibilityChangeObserver.isCurrentlyVisible();
145
+ const isInForeground = (0, VisibilityObserving_1._isCurrentlyVisible)();
146
146
  const response = !isInForeground && this._network.isBeaconSupported()
147
147
  ? yield this._sendEventsViaBeacon(events)
148
148
  : yield this._sendEventsViaPost(events);
@@ -171,8 +171,7 @@ class EventLogger {
171
171
  url: this._logEventUrl,
172
172
  retries: 3,
173
173
  params: {
174
- // ec = Event Count
175
- ec: String(events.length),
174
+ [NetworkParams_1.NetworkParam.EventCount]: String(events.length),
176
175
  },
177
176
  });
178
177
  const response = (result === null || result === void 0 ? void 0 : result.body)
@@ -199,18 +198,18 @@ class EventLogger {
199
198
  events.shift();
200
199
  }
201
200
  const storageKey = this._getStorageKey();
202
- (0, StorageProvider_1.setObjectInStorage)(storageKey, events).catch(() => {
201
+ (0, StorageProvider_1._setObjectInStorage)(storageKey, events).catch(() => {
203
202
  Log_1.Log.warn('Unable to save failed logs to storage');
204
203
  });
205
204
  }
206
205
  _retryFailedLogs() {
207
206
  const storageKey = this._getStorageKey();
208
207
  (() => __awaiter(this, void 0, void 0, function* () {
209
- const events = yield (0, StorageProvider_1.getObjectFromStorage)(storageKey);
208
+ const events = yield (0, StorageProvider_1._getObjectFromStorage)(storageKey);
210
209
  if (!events) {
211
210
  return;
212
211
  }
213
- yield StorageProvider_1.Storage.removeItem(storageKey);
212
+ yield StorageProvider_1.Storage._removeItem(storageKey);
214
213
  yield this._sendEvents(events);
215
214
  }))().catch(() => {
216
215
  Log_1.Log.warn('Failed to flush stored logs');
package/src/Hashing.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare function DJB2(value: string): string;
2
- export declare function DJB2Object(value: Record<string, unknown> | null): string;
1
+ export declare const DJB2: (value: string) => string;
2
+ export declare const DJB2Object: (value: Record<string, unknown> | null) => string;
package/src/Hashing.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DJB2Object = exports.DJB2 = void 0;
4
- function DJB2(value) {
4
+ const DJB2 = (value) => {
5
5
  let hash = 0;
6
6
  for (let i = 0; i < value.length; i++) {
7
7
  const character = value.charCodeAt(i);
@@ -9,13 +9,13 @@ function DJB2(value) {
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
- }
14
+ const DJB2Object = (value) => {
15
+ return (0, exports.DJB2)(JSON.stringify(_getSortedObject(value)));
16
+ };
17
17
  exports.DJB2Object = DJB2Object;
18
- function _getSortedObject(object) {
18
+ const _getSortedObject = (object) => {
19
19
  if (object == null) {
20
20
  return null;
21
21
  }
@@ -29,4 +29,4 @@ function _getSortedObject(object) {
29
29
  sortedObject[key] = value;
30
30
  });
31
31
  return sortedObject;
32
- }
32
+ };
@@ -1,5 +1,6 @@
1
+ import './$_StatsigGlobal';
1
2
  import { StatsigClientEmitEventFunc } from './StatsigClientBase';
2
- import { StatsigOptionsCommon } from './StatsigOptionsCommon';
3
+ import { AnyStatsigOptions } from './StatsigOptionsCommon';
3
4
  type RequestArgs = {
4
5
  sdkKey: string;
5
6
  url: string;
@@ -9,6 +10,7 @@ type RequestArgs = {
9
10
  };
10
11
  type RequestArgsWithData = RequestArgs & {
11
12
  data: Record<string, unknown>;
13
+ isStatsigEncodable?: boolean;
12
14
  };
13
15
  type NetworkResponse = {
14
16
  body: string | null;
@@ -18,7 +20,7 @@ export declare class NetworkCore {
18
20
  private _options;
19
21
  private _emitter?;
20
22
  private readonly _timeout;
21
- constructor(_options: StatsigOptionsCommon | null, _emitter?: StatsigClientEmitEventFunc | undefined);
23
+ constructor(_options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
22
24
  post(args: RequestArgsWithData): Promise<NetworkResponse | null>;
23
25
  get(args: RequestArgs): Promise<NetworkResponse | null>;
24
26
  isBeaconSupported(): boolean;
@@ -26,5 +28,6 @@ export declare class NetworkCore {
26
28
  private _sendRequest;
27
29
  private _getPopulatedURL;
28
30
  private _getPopulatedBody;
31
+ private _attemptToEncodeString;
29
32
  }
30
33
  export {};
@@ -10,29 +10,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.NetworkCore = void 0;
13
+ require("./$_StatsigGlobal");
13
14
  const Diagnostics_1 = require("./Diagnostics");
14
15
  const Log_1 = require("./Log");
16
+ const NetworkParams_1 = require("./NetworkParams");
17
+ const SDKType_1 = require("./SDKType");
15
18
  const SessionID_1 = require("./SessionID");
16
19
  const StableID_1 = require("./StableID");
17
20
  const StatsigMetadata_1 = require("./StatsigMetadata");
18
21
  const DEFAULT_TIMEOUT_MS = 10000;
19
22
  class NetworkCore {
20
23
  constructor(_options, _emitter) {
21
- var _a;
24
+ var _a, _b;
22
25
  this._options = _options;
23
26
  this._emitter = _emitter;
24
- this._timeout = (_a = _options === null || _options === void 0 ? void 0 : _options.networkTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
27
+ this._timeout =
28
+ (_b = (_a = _options === null || _options === void 0 ? void 0 : _options.networkConfig) === null || _a === void 0 ? void 0 : _a.networkTimeoutMs) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT_MS;
25
29
  }
26
30
  post(args) {
27
31
  return __awaiter(this, void 0, void 0, function* () {
28
32
  const body = yield this._getPopulatedBody(args);
29
- return this._sendRequest(Object.assign({ method: 'POST', body }, args));
33
+ return this._sendRequest(Object.assign({ method: 'POST', body: this._attemptToEncodeString(args, body) }, args));
30
34
  });
31
35
  }
32
36
  get(args) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- return this._sendRequest(Object.assign({ method: 'GET' }, args));
35
- });
37
+ return this._sendRequest(Object.assign({ method: 'GET' }, args));
36
38
  }
37
39
  isBeaconSupported() {
38
40
  return (typeof navigator !== 'undefined' &&
@@ -95,8 +97,7 @@ class NetworkCore {
95
97
  }
96
98
  _getPopulatedURL(args) {
97
99
  return __awaiter(this, void 0, void 0, function* () {
98
- const metadata = StatsigMetadata_1.StatsigMetadataProvider.get();
99
- const params = Object.assign({ k: args.sdkKey, st: metadata.sdkType, sv: metadata.sdkVersion, t: String(Date.now()), sid: yield SessionID_1.SessionID.get(args.sdkKey) }, args.params);
100
+ const params = Object.assign({ [NetworkParams_1.NetworkParam.SdkKey]: args.sdkKey, [NetworkParams_1.NetworkParam.SdkType]: SDKType_1.SDKType._get(args.sdkKey), [NetworkParams_1.NetworkParam.SdkVersion]: StatsigMetadata_1.SDK_VERSION, [NetworkParams_1.NetworkParam.Time]: String(Date.now()), [NetworkParams_1.NetworkParam.SessionID]: yield SessionID_1.SessionID.get(args.sdkKey) }, args.params);
100
101
  const query = Object.entries(params)
101
102
  .map(([key, value]) => {
102
103
  return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
@@ -107,13 +108,27 @@ class NetworkCore {
107
108
  }
108
109
  _getPopulatedBody(args) {
109
110
  return __awaiter(this, void 0, void 0, function* () {
110
- const { data } = args;
111
- const stableID = yield StableID_1.StableID.get(args.sdkKey);
112
- const sessionID = yield SessionID_1.SessionID.get(args.sdkKey);
111
+ const { data, sdkKey } = args;
112
+ const stableID = yield StableID_1.StableID.get(sdkKey);
113
+ const sessionID = yield SessionID_1.SessionID.get(sdkKey);
114
+ const sdkType = SDKType_1.SDKType._get(sdkKey);
113
115
  return JSON.stringify(Object.assign(Object.assign({}, data), { statsigMetadata: Object.assign(Object.assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID,
114
- sessionID }) }));
116
+ sessionID,
117
+ sdkType }) }));
115
118
  });
116
119
  }
120
+ _attemptToEncodeString(args, input) {
121
+ var _a, _b, _c;
122
+ if ((__STATSIG__ === null || __STATSIG__ === void 0 ? void 0 : __STATSIG__['no-encode']) != null ||
123
+ ((_a = this._options) === null || _a === void 0 ? void 0 : _a.disableStatsigEncoding) ||
124
+ !args.isStatsigEncodable ||
125
+ typeof window === 'undefined' ||
126
+ !window.btoa) {
127
+ return input;
128
+ }
129
+ args.params = Object.assign(Object.assign({}, ((_b = args.params) !== null && _b !== void 0 ? _b : {})), { [NetworkParams_1.NetworkParam.StatsigEncoded]: '1' });
130
+ return (_c = window.btoa(input).split('').reverse().join('')) !== null && _c !== void 0 ? _c : input;
131
+ }
117
132
  }
118
133
  exports.NetworkCore = NetworkCore;
119
134
  function _getErrorMessage(controller, error) {
@@ -0,0 +1,5 @@
1
+ export declare const NetworkDefault: {
2
+ eventsApi: "https://events.statsigapi.net/v1";
3
+ initializeApi: "https://featuregates.org/v1";
4
+ specsApi: "https://api.statsigcdn.com/v1";
5
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkDefault = void 0;
4
+ exports.NetworkDefault = {
5
+ eventsApi: 'https://events.statsigapi.net/v1',
6
+ initializeApi: 'https://featuregates.org/v1',
7
+ specsApi: 'https://api.statsigcdn.com/v1',
8
+ };
@@ -0,0 +1,9 @@
1
+ export declare enum NetworkParam {
2
+ EventCount = "ec",
3
+ SdkKey = "k",
4
+ SdkType = "st",
5
+ SdkVersion = "sv",
6
+ Time = "t",
7
+ SessionID = "sid",
8
+ StatsigEncoded = "se"
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkParam = void 0;
4
+ var NetworkParam;
5
+ (function (NetworkParam) {
6
+ NetworkParam["EventCount"] = "ec";
7
+ NetworkParam["SdkKey"] = "k";
8
+ NetworkParam["SdkType"] = "st";
9
+ NetworkParam["SdkVersion"] = "sv";
10
+ NetworkParam["Time"] = "t";
11
+ NetworkParam["SessionID"] = "sid";
12
+ NetworkParam["StatsigEncoded"] = "se";
13
+ })(NetworkParam || (exports.NetworkParam = NetworkParam = {}));
@@ -7,10 +7,3 @@ export type OverrideAdapter = {
7
7
  getExperimentOverride?(current: Experiment, user: StatsigUser, options?: ExperimentEvaluationOptions): Experiment | null;
8
8
  getLayerOverride?(current: Layer, user: StatsigUser, options?: LayerEvaluationOptions): Layer | null;
9
9
  };
10
- export declare class CombinationOverrideAdapter implements OverrideAdapter {
11
- readonly providers: OverrideAdapter[];
12
- constructor(providers: OverrideAdapter[]);
13
- getGateOverride(current: FeatureGate, user: StatsigUser): FeatureGate | null;
14
- getDynamicConfigOverride(current: DynamicConfig, user: StatsigUser): DynamicConfig | null;
15
- private _getOverride;
16
- }
@@ -1,24 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CombinationOverrideAdapter = void 0;
4
- class CombinationOverrideAdapter {
5
- constructor(providers) {
6
- this.providers = providers;
7
- }
8
- getGateOverride(current, user) {
9
- return this._getOverride((provider) => { var _a, _b; return (_b = (_a = provider.getGateOverride) === null || _a === void 0 ? void 0 : _a.call(provider, current, user)) !== null && _b !== void 0 ? _b : null; });
10
- }
11
- getDynamicConfigOverride(current, user) {
12
- return this._getOverride((provider) => { var _a, _b; return (_b = (_a = provider.getDynamicConfigOverride) === null || _a === void 0 ? void 0 : _a.call(provider, current, user)) !== null && _b !== void 0 ? _b : null; });
13
- }
14
- _getOverride(fn) {
15
- for (const provider of this.providers) {
16
- const override = fn(provider);
17
- if (override) {
18
- return override;
19
- }
20
- }
21
- return null;
22
- }
23
- }
24
- exports.CombinationOverrideAdapter = CombinationOverrideAdapter;
@@ -0,0 +1,8 @@
1
+ type ClientType = 'javascript-client' | 'js-on-device-eval-client';
2
+ type BindingType = 'expo' | 'rn' | 'react';
3
+ export declare const SDKType: {
4
+ _get: (sdkKey: string) => string;
5
+ _setClientType(sdkKey: string, client: ClientType): void;
6
+ _setBindingType(binding: BindingType): void;
7
+ };
8
+ export {};