@statsig/client-core 1.7.0 → 2.0.0

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": "1.7.0",
3
+ "version": "2.0.0",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -21,18 +21,14 @@ export type CommonContext = {
21
21
  sdkKey: string;
22
22
  options: AnyStatsigOptions;
23
23
  errorBoundary: ErrorBoundary;
24
- };
25
- export type AsyncCommonContext = {
26
24
  session: StatsigSession;
27
25
  stableID: string;
28
26
  };
29
27
  export type OnDeviceEvaluationsContext = CommonContext & {
30
28
  values: DownloadConfigSpecsResponse | null;
31
29
  };
32
- export type OnDeviceEvaluationsAsyncContext = OnDeviceEvaluationsContext & AsyncCommonContext;
33
30
  export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterface {
34
31
  readonly dataAdapter: SpecsDataAdapter;
35
- getAsyncContext(): Promise<OnDeviceEvaluationsAsyncContext>;
36
32
  getContext(): OnDeviceEvaluationsContext;
37
33
  checkGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): boolean;
38
34
  getFeatureGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): FeatureGate;
@@ -46,10 +42,8 @@ export type PrecomputedEvaluationsContext = Flatten<CommonContext & {
46
42
  values: InitializeResponseWithUpdates | null;
47
43
  user: StatsigUser;
48
44
  }>;
49
- export type PrecomputedEvaluationsAsyncContext = Flatten<AsyncCommonContext & PrecomputedEvaluationsContext>;
50
45
  export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
51
46
  readonly dataAdapter: EvaluationsDataAdapter;
52
- getAsyncContext(): Promise<PrecomputedEvaluationsAsyncContext>;
53
47
  getContext(): PrecomputedEvaluationsContext;
54
48
  updateUserSync(user: StatsigUser): void;
55
49
  updateUserAsync(user: StatsigUser): Promise<void>;
@@ -118,7 +118,7 @@ class DataAdapterCore {
118
118
  }
119
119
  _loadFromCache(cacheKey) {
120
120
  var _a;
121
- const cache = (_a = StorageProvider_1.Storage._getItemSync) === null || _a === void 0 ? void 0 : _a.call(StorageProvider_1.Storage, cacheKey);
121
+ const cache = (_a = StorageProvider_1.Storage._getItem) === null || _a === void 0 ? void 0 : _a.call(StorageProvider_1.Storage, cacheKey);
122
122
  if (cache == null) {
123
123
  return null;
124
124
  }
@@ -1,3 +1,67 @@
1
- export declare abstract class Diagnostics {
2
- static mark(): void;
1
+ import { EvaluationDetails } from './EvaluationTypes';
2
+ import { EventLogger } from './EventLogger';
3
+ import { NetworkConfigCommon, StatsigOptionsCommon } from './StatsigOptionsCommon';
4
+ import { StatsigUserInternal } from './StatsigUser';
5
+ export type KeyType = 'initialize' | 'overall';
6
+ export type StepType = 'process' | 'network_request';
7
+ export type ActionType = 'start' | 'end';
8
+ export interface Marker {
9
+ key: KeyType;
10
+ action: ActionType;
11
+ timestamp: number;
12
+ step?: StepType;
13
+ statusCode?: number;
14
+ success?: boolean;
15
+ url?: string;
16
+ idListCount?: number;
17
+ sdkRegion?: string | null;
18
+ markerID?: string;
19
+ attempt?: number;
20
+ isRetry?: boolean;
21
+ configName?: string;
22
+ message?: string | null;
23
+ evaluationDetails?: EvaluationDetails;
24
+ error?: Record<string, unknown>;
25
+ isDelta?: boolean;
3
26
  }
27
+ export declare const Diagnostics: {
28
+ _getMarkers: (sdkKey: string) => Marker[] | undefined;
29
+ _markInitOverallStart: (sdkKey: string) => void;
30
+ _markInitOverallEnd: (sdkKey: string, success: boolean, evaluationDetails?: EvaluationDetails) => void;
31
+ _markInitNetworkReqStart: (sdkKey: string, data: InitializeDataType['networkRequest']['start']) => void;
32
+ _markInitNetworkReqEnd: (sdkKey: string, data: InitializeDataType['networkRequest']['end']) => void;
33
+ _markInitProcessStart: (sdkKey: string) => void;
34
+ _markInitProcessEnd: (sdkKey: string, data: InitializeDataType['process']['end']) => void;
35
+ _clearMarkers: (sdkKey: string) => void;
36
+ _formatError(e: unknown): Record<string, unknown> | undefined;
37
+ _getDiagnosticsData(res: Response | null, attempt: number, body: string, e?: unknown): {
38
+ success: boolean;
39
+ isDelta?: boolean | undefined;
40
+ sdkRegion?: string | null | undefined;
41
+ statusCode?: number | undefined;
42
+ attempt: number;
43
+ error?: Record<string, unknown> | undefined;
44
+ };
45
+ _enqueueDiagnosticsEvent(user: StatsigUserInternal | null, logger: EventLogger, sdk: string, options: StatsigOptionsCommon<NetworkConfigCommon> | null): void;
46
+ };
47
+ interface InitializeDataType {
48
+ process: {
49
+ end: {
50
+ success: boolean;
51
+ };
52
+ };
53
+ networkRequest: {
54
+ start: {
55
+ attempt: number;
56
+ };
57
+ end: {
58
+ success: boolean;
59
+ attempt: number;
60
+ isDelta?: boolean;
61
+ sdkRegion?: string | null;
62
+ statusCode?: number;
63
+ error?: Record<string, unknown>;
64
+ };
65
+ };
66
+ }
67
+ export {};
@@ -1,9 +1,98 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Diagnostics = void 0;
4
- class Diagnostics {
5
- static mark() {
6
- //
4
+ const MARKER_MAP = new Map();
5
+ const ACT_START = 'start';
6
+ const ACT_END = 'end';
7
+ const DIAGNOSTICS_EVENT = 'statsig::diagnostics';
8
+ exports.Diagnostics = {
9
+ _getMarkers: (sdkKey) => {
10
+ return MARKER_MAP.get(sdkKey);
11
+ },
12
+ _markInitOverallStart: (sdkKey) => {
13
+ _addMarker(sdkKey, _createMarker({}, ACT_START));
14
+ },
15
+ _markInitOverallEnd: (sdkKey, success, evaluationDetails) => {
16
+ _addMarker(sdkKey, _createMarker({
17
+ success,
18
+ error: success
19
+ ? undefined
20
+ : { name: 'InitializeError', message: 'Failed to initialize' },
21
+ evaluationDetails,
22
+ }, ACT_END));
23
+ },
24
+ _markInitNetworkReqStart: (sdkKey, data) => {
25
+ _addMarker(sdkKey, _createMarker(data, ACT_START));
26
+ },
27
+ _markInitNetworkReqEnd: (sdkKey, data) => {
28
+ _addMarker(sdkKey, _createMarker(data, ACT_END));
29
+ },
30
+ _markInitProcessStart: (sdkKey) => {
31
+ _addMarker(sdkKey, _createMarker({}, ACT_START));
32
+ },
33
+ _markInitProcessEnd: (sdkKey, data) => {
34
+ _addMarker(sdkKey, _createMarker(data, ACT_END));
35
+ },
36
+ _clearMarkers: (sdkKey) => {
37
+ MARKER_MAP.delete(sdkKey);
38
+ },
39
+ _formatError(e) {
40
+ if (!(e && typeof e === 'object')) {
41
+ return;
42
+ }
43
+ return {
44
+ code: _safeGetField(e, 'code'),
45
+ name: _safeGetField(e, 'name'),
46
+ message: _safeGetField(e, 'message'),
47
+ };
48
+ },
49
+ _getDiagnosticsData(res, attempt, body, e) {
50
+ var _a;
51
+ return {
52
+ success: (res === null || res === void 0 ? void 0 : res.ok) === true,
53
+ statusCode: res === null || res === void 0 ? void 0 : res.status,
54
+ sdkRegion: (_a = res === null || res === void 0 ? void 0 : res.headers) === null || _a === void 0 ? void 0 : _a.get('x-statsig-region'),
55
+ isDelta: body.includes('"is_delta":true') === true ? true : undefined,
56
+ attempt,
57
+ error: exports.Diagnostics._formatError(e),
58
+ };
59
+ },
60
+ _enqueueDiagnosticsEvent(user, logger, sdk, options) {
61
+ const markers = exports.Diagnostics._getMarkers(sdk);
62
+ if (markers == null || markers.length <= 0) {
63
+ return;
64
+ }
65
+ exports.Diagnostics._clearMarkers(sdk);
66
+ const event = _makeDiagnosticsEvent(user, {
67
+ context: 'initialize',
68
+ markers: markers.slice(),
69
+ statsigOptions: options,
70
+ });
71
+ logger.enqueue(event);
72
+ },
73
+ };
74
+ function _createMarker(data, action) {
75
+ return Object.assign({ key: 'initialize', action: action, timestamp: Date.now() }, data);
76
+ }
77
+ function _makeDiagnosticsEvent(user, data) {
78
+ const latencyEvent = {
79
+ eventName: DIAGNOSTICS_EVENT,
80
+ user,
81
+ value: null,
82
+ metadata: data,
83
+ time: Date.now(),
84
+ };
85
+ return latencyEvent;
86
+ }
87
+ function _addMarker(sdkKey, marker) {
88
+ var _a;
89
+ const markers = (_a = MARKER_MAP.get(sdkKey)) !== null && _a !== void 0 ? _a : [];
90
+ markers.push(marker);
91
+ MARKER_MAP.set(sdkKey, markers);
92
+ }
93
+ function _safeGetField(data, field) {
94
+ if (field in data) {
95
+ return data[field];
7
96
  }
97
+ return undefined;
8
98
  }
9
- exports.Diagnostics = Diagnostics;
@@ -118,6 +118,9 @@ class EventLogger {
118
118
  setTimeout(() => _safeFlushAndForget(this._sdkKey), QUICK_FLUSH_WINDOW_MS);
119
119
  }
120
120
  _shouldLogEvent(event) {
121
+ if ((0, SafeJs_1._isServerEnv)()) {
122
+ return false; // do not run in server environments
123
+ }
121
124
  if (!(0, StatsigEvent_1._isExposureEvent)(event)) {
122
125
  return true;
123
126
  }
@@ -206,18 +209,21 @@ class EventLogger {
206
209
  events.shift();
207
210
  }
208
211
  const storageKey = this._getStorageKey();
209
- (0, StorageProvider_1._setObjectInStorage)(storageKey, events).catch(() => {
212
+ try {
213
+ (0, StorageProvider_1._setObjectInStorage)(storageKey, events);
214
+ }
215
+ catch (_a) {
210
216
  Log_1.Log.warn('Unable to save failed logs to storage');
211
- });
217
+ }
212
218
  }
213
219
  _retryFailedLogs() {
214
220
  const storageKey = this._getStorageKey();
215
221
  (() => __awaiter(this, void 0, void 0, function* () {
216
- const events = yield (0, StorageProvider_1._getObjectFromStorage)(storageKey);
222
+ const events = (0, StorageProvider_1._getObjectFromStorage)(storageKey);
217
223
  if (!events) {
218
224
  return;
219
225
  }
220
- yield StorageProvider_1.Storage._removeItem(storageKey);
226
+ StorageProvider_1.Storage._removeItem(storageKey);
221
227
  yield this._sendEvents(events);
222
228
  }))().catch(() => {
223
229
  Log_1.Log.warn('Failed to flush stored logs');
@@ -5,7 +5,12 @@ type SessionReplayFields = {
5
5
  can_record_session?: boolean;
6
6
  session_recording_rate?: number;
7
7
  };
8
- export type InitializeResponseWithUpdates = SessionReplayFields & {
8
+ type AutoCaptureFields = {
9
+ auto_capture_settings?: {
10
+ disabled_events: Record<string, boolean>;
11
+ };
12
+ };
13
+ export type InitializeResponseWithUpdates = SessionReplayFields & AutoCaptureFields & {
9
14
  feature_gates: Record<string, GateEvaluation>;
10
15
  dynamic_configs: Record<string, DynamicConfigEvaluation>;
11
16
  layer_configs: Record<string, LayerEvaluation>;
package/src/Log.js CHANGED
@@ -2,6 +2,11 @@
2
2
  /* eslint-disable no-console */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.Log = exports.LogLevel = void 0;
5
+ // intentionally spaced for formatting
6
+ const DEBUG = ' DEBUG ';
7
+ const _INFO = ' INFO ';
8
+ const _WARN = ' WARN ';
9
+ const ERROR = ' ERROR ';
5
10
  function addTag(args) {
6
11
  args.unshift('[Statsig]');
7
12
  return args; // ['[Statsig]', ...args];
@@ -17,24 +22,24 @@ var LogLevel;
17
22
  class Log {
18
23
  static info(...args) {
19
24
  if (this.level >= LogLevel.Info) {
20
- console.info(...addTag(args));
25
+ console.info('\x1b[34m%s\x1b[0m', _INFO, ...addTag(args));
21
26
  }
22
27
  }
23
28
  static debug(...args) {
24
29
  if (this.level >= LogLevel.Debug) {
25
- console.debug(...addTag(args));
30
+ console.debug('\x1b[32m%s\x1b[0m', DEBUG, ...addTag(args));
26
31
  }
27
32
  }
28
33
  static warn(...args) {
29
34
  if (this.level >= LogLevel.Warn) {
30
- console.warn(...addTag(args));
35
+ console.warn('\x1b[33m%s\x1b[0m', _WARN, ...addTag(args));
31
36
  }
32
37
  }
33
38
  static error(...args) {
34
39
  if (this.level >= LogLevel.Error) {
35
- console.error(...addTag(args));
40
+ console.error('\x1b[31m%s\x1b[0m', ERROR, ...addTag(args));
36
41
  }
37
42
  }
38
43
  }
39
44
  exports.Log = Log;
40
- Log.level = LogLevel.Error;
45
+ Log.level = LogLevel.Warn;
@@ -8,6 +8,8 @@ type RequestArgs = {
8
8
  url: string;
9
9
  priority?: NetworkPriority;
10
10
  retries?: number;
11
+ attempt?: number;
12
+ isInitialize?: boolean;
11
13
  params?: Record<string, string>;
12
14
  headers?: Record<string, string>;
13
15
  };
@@ -16,7 +18,7 @@ export type RequestArgsWithData = Flatten<RequestArgs & {
16
18
  isStatsigEncodable?: boolean;
17
19
  isCompressable?: boolean;
18
20
  }>;
19
- type BeaconRequestArgs = Pick<RequestArgsWithData, 'data' | 'sdkKey' | 'url' | 'params' | 'isCompressable'>;
21
+ type BeaconRequestArgs = Pick<RequestArgsWithData, 'data' | 'sdkKey' | 'url' | 'params' | 'isCompressable' | 'attempt'>;
20
22
  type NetworkResponse = {
21
23
  body: string | null;
22
24
  code: number;
@@ -22,6 +22,7 @@ const StableID_1 = require("./StableID");
22
22
  const StatsigMetadata_1 = require("./StatsigMetadata");
23
23
  const VisibilityObserving_1 = require("./VisibilityObserving");
24
24
  const DEFAULT_TIMEOUT_MS = 10000;
25
+ const RETRYABLE_CODES = new Set([408, 500, 502, 503, 504, 522, 524, 599]);
25
26
  class NetworkCore {
26
27
  constructor(options, _emitter) {
27
28
  this._emitter = _emitter;
@@ -66,7 +67,7 @@ class NetworkCore {
66
67
  });
67
68
  }
68
69
  _sendRequest(args) {
69
- var _a, _b;
70
+ var _a, _b, _c;
70
71
  return __awaiter(this, void 0, void 0, function* () {
71
72
  if (!_ensureValidSdkKey(args)) {
72
73
  return null;
@@ -74,7 +75,8 @@ class NetworkCore {
74
75
  if (this._netConfig.preventAllNetworkTraffic) {
75
76
  return null;
76
77
  }
77
- const { method, body, retries } = args;
78
+ const { method, body, retries, attempt } = args;
79
+ const currentAttempt = attempt !== null && attempt !== void 0 ? attempt : 1;
78
80
  const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
79
81
  const handle = setTimeout(() => controller === null || controller === void 0 ? void 0 : controller.abort(`Timeout of ${this._timeout}ms expired.`), this._timeout);
80
82
  const url = yield this._getPopulatedURL(args);
@@ -89,6 +91,11 @@ class NetworkCore {
89
91
  priority: args.priority,
90
92
  keepalive,
91
93
  };
94
+ if (args.isInitialize) {
95
+ Diagnostics_1.Diagnostics._markInitNetworkReqStart(args.sdkKey, {
96
+ attempt: currentAttempt,
97
+ });
98
+ }
92
99
  const func = (_a = this._netConfig.networkOverrideFunc) !== null && _a !== void 0 ? _a : fetch;
93
100
  response = yield func(url, config);
94
101
  clearTimeout(handle);
@@ -99,7 +106,9 @@ class NetworkCore {
99
106
  throw err;
100
107
  }
101
108
  const text = yield response.text();
102
- Diagnostics_1.Diagnostics.mark();
109
+ if (args.isInitialize) {
110
+ Diagnostics_1.Diagnostics._markInitNetworkReqEnd(args.sdkKey, Diagnostics_1.Diagnostics._getDiagnosticsData(response, currentAttempt, text));
111
+ }
103
112
  return {
104
113
  body: text,
105
114
  code: response.status,
@@ -107,13 +116,17 @@ class NetworkCore {
107
116
  }
108
117
  catch (error) {
109
118
  const errorMessage = _getErrorMessage(controller, error);
110
- Diagnostics_1.Diagnostics.mark();
111
- if (!retries || retries <= 0) {
112
- (_b = this._emitter) === null || _b === void 0 ? void 0 : _b.call(this, { name: 'error', error });
119
+ if (args.isInitialize) {
120
+ Diagnostics_1.Diagnostics._markInitNetworkReqEnd(args.sdkKey, Diagnostics_1.Diagnostics._getDiagnosticsData(response, currentAttempt, '', error));
121
+ }
122
+ if (!retries ||
123
+ currentAttempt > retries ||
124
+ !RETRYABLE_CODES.has((_b = response === null || response === void 0 ? void 0 : response.status) !== null && _b !== void 0 ? _b : 500)) {
125
+ (_c = this._emitter) === null || _c === void 0 ? void 0 : _c.call(this, { name: 'error', error });
113
126
  Log_1.Log.error(`A networking error occured during ${method} request to ${url}.`, errorMessage, error);
114
127
  return null;
115
128
  }
116
- return this._sendRequest(Object.assign(Object.assign({}, args), { retries: retries - 1 }));
129
+ return this._sendRequest(Object.assign(Object.assign({}, args), { retries: retries, attempt: currentAttempt + 1 }));
117
130
  }
118
131
  });
119
132
  }
@@ -11,10 +11,10 @@ export type StatsigSession = {
11
11
  idleTimeoutID?: SessionTimeoutID;
12
12
  };
13
13
  export declare const SessionID: {
14
- get: (sdkKey: string) => Promise<string>;
14
+ get: (sdkKey: string) => string;
15
15
  };
16
16
  export declare const StatsigSession: {
17
- get: (sdkKey: string) => Promise<StatsigSession>;
17
+ get: (sdkKey: string) => StatsigSession;
18
18
  overrideInitialSessionID: (override: string, sdkKey: string) => void;
19
19
  };
20
20
  export {};
package/src/SessionID.js CHANGED
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.StatsigSession = exports.SessionID = void 0;
13
4
  const CacheKey_1 = require("./CacheKey");
@@ -18,49 +9,47 @@ const MAX_SESSION_IDLE_TIME = 30 * 60 * 1000; // 30 minutes
18
9
  const MAX_SESSION_AGE = 4 * 60 * 60 * 1000; // 4 hours
19
10
  const PROMISE_MAP = {};
20
11
  exports.SessionID = {
21
- get: (sdkKey) => __awaiter(void 0, void 0, void 0, function* () {
22
- return exports.StatsigSession.get(sdkKey).then((x) => x.data.sessionID);
23
- }),
12
+ get: (sdkKey) => {
13
+ return exports.StatsigSession.get(sdkKey).data.sessionID;
14
+ },
24
15
  };
25
16
  exports.StatsigSession = {
26
- get: (sdkKey) => __awaiter(void 0, void 0, void 0, function* () {
17
+ get: (sdkKey) => {
27
18
  if (PROMISE_MAP[sdkKey] == null) {
28
19
  PROMISE_MAP[sdkKey] = _loadSession(sdkKey);
29
20
  }
30
- const session = yield PROMISE_MAP[sdkKey];
21
+ const session = PROMISE_MAP[sdkKey];
31
22
  return _bumpSession(session);
32
- }),
23
+ },
33
24
  overrideInitialSessionID: (override, sdkKey) => {
34
25
  PROMISE_MAP[sdkKey] = _overrideSessionId(override, sdkKey);
35
26
  },
36
27
  };
37
28
  function _loadSession(sdkKey) {
38
- return __awaiter(this, void 0, void 0, function* () {
39
- let data = yield _loadFromStorage(sdkKey);
40
- const now = Date.now();
41
- if (!data) {
42
- data = {
43
- sessionID: (0, UUID_1.getUUID)(),
44
- startTime: now,
45
- lastUpdate: now,
46
- };
47
- }
48
- return {
49
- data,
50
- sdkKey,
29
+ let data = _loadFromStorage(sdkKey);
30
+ const now = Date.now();
31
+ if (!data) {
32
+ data = {
33
+ sessionID: (0, UUID_1.getUUID)(),
34
+ startTime: now,
35
+ lastUpdate: now,
51
36
  };
52
- });
37
+ }
38
+ return {
39
+ data,
40
+ sdkKey,
41
+ };
53
42
  }
54
43
  function _overrideSessionId(override, sdkKey) {
55
44
  const now = Date.now();
56
- return Promise.resolve({
45
+ return {
57
46
  data: {
58
47
  sessionID: override,
59
48
  startTime: now,
60
49
  lastUpdate: now,
61
50
  },
62
51
  sdkKey,
63
- });
52
+ };
64
53
  }
65
54
  function _bumpSession(session) {
66
55
  const now = Date.now();
@@ -98,9 +87,12 @@ function _getSessionIDStorageKey(sdkKey) {
98
87
  }
99
88
  function _persistToStorage(session, sdkKey) {
100
89
  const storageKey = _getSessionIDStorageKey(sdkKey);
101
- (0, StorageProvider_1._setObjectInStorage)(storageKey, session).catch(() => {
90
+ try {
91
+ (0, StorageProvider_1._setObjectInStorage)(storageKey, session);
92
+ }
93
+ catch (e) {
102
94
  Log_1.Log.warn('Failed to save SessionID');
103
- });
95
+ }
104
96
  }
105
97
  function _loadFromStorage(sdkKey) {
106
98
  const storageKey = _getSessionIDStorageKey(sdkKey);
package/src/StableID.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export declare const StableID: {
2
- get: (sdkKey: string) => Promise<string>;
2
+ get: (sdkKey: string) => string;
3
3
  setOverride: (override: string, sdkKey: string) => void;
4
4
  };
package/src/StableID.js CHANGED
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.StableID = void 0;
13
4
  const CacheKey_1 = require("./CacheKey");
@@ -16,21 +7,19 @@ const StorageProvider_1 = require("./StorageProvider");
16
7
  const UUID_1 = require("./UUID");
17
8
  const PROMISE_MAP = {};
18
9
  exports.StableID = {
19
- get: (sdkKey) => __awaiter(void 0, void 0, void 0, function* () {
10
+ get: (sdkKey) => {
20
11
  if (PROMISE_MAP[sdkKey] == null) {
21
- PROMISE_MAP[sdkKey] = _loadFromStorage(sdkKey).then((stableID) => {
22
- if (stableID != null) {
23
- return stableID;
24
- }
25
- const newStableID = (0, UUID_1.getUUID)();
26
- _persistToStorage(newStableID, sdkKey);
27
- return newStableID;
28
- });
12
+ let stableID = _loadFromStorage(sdkKey);
13
+ if (stableID == null) {
14
+ stableID = (0, UUID_1.getUUID)();
15
+ _persistToStorage(stableID, sdkKey);
16
+ }
17
+ PROMISE_MAP[sdkKey] = stableID;
29
18
  }
30
19
  return PROMISE_MAP[sdkKey];
31
- }),
20
+ },
32
21
  setOverride: (override, sdkKey) => {
33
- PROMISE_MAP[sdkKey] = Promise.resolve(override);
22
+ PROMISE_MAP[sdkKey] = override;
34
23
  _persistToStorage(override, sdkKey);
35
24
  },
36
25
  };
@@ -39,9 +28,12 @@ function _getStableIDStorageKey(sdkKey) {
39
28
  }
40
29
  function _persistToStorage(stableID, sdkKey) {
41
30
  const storageKey = _getStableIDStorageKey(sdkKey);
42
- (0, StorageProvider_1._setObjectInStorage)(storageKey, stableID).catch(() => {
31
+ try {
32
+ (0, StorageProvider_1._setObjectInStorage)(storageKey, stableID);
33
+ }
34
+ catch (e) {
43
35
  Log_1.Log.warn('Failed to save StableID');
44
- });
36
+ }
45
37
  }
46
38
  function _loadFromStorage(sdkKey) {
47
39
  const storageKey = _getStableIDStorageKey(sdkKey);
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "1.7.0";
1
+ export declare const SDK_VERSION = "2.0.0";
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 = '1.7.0';
4
+ exports.SDK_VERSION = '2.0.0';
5
5
  let metadata = {
6
6
  sdkVersion: exports.SDK_VERSION,
7
7
  sdkType: 'js-mono', // js-mono is overwritten by Precomp and OnDevice clients
@@ -1,16 +1,15 @@
1
1
  export type StorageProvider = {
2
2
  _getProviderName: () => string;
3
- _getItem: (key: string) => Promise<string | null>;
4
- _setItem: (key: string, value: string) => Promise<void>;
5
- _removeItem: (key: string) => Promise<void>;
6
- _getAllKeys: () => Promise<readonly string[]>;
7
- _getItemSync?: (key: string) => string | null;
3
+ _getItem: (key: string) => string | null;
4
+ _setItem: (key: string, value: string) => void;
5
+ _removeItem: (key: string) => void;
6
+ _getAllKeys: () => readonly string[];
8
7
  };
9
8
  type StorageProviderManagment = {
10
9
  _setProvider: (newProvider: StorageProvider) => void;
11
10
  _setDisabled: (isDisabled: boolean) => void;
12
11
  };
13
12
  export declare const Storage: StorageProvider & StorageProviderManagment;
14
- export declare function _getObjectFromStorage<T>(key: string): Promise<T | null>;
15
- export declare function _setObjectInStorage(key: string, obj: unknown): Promise<void>;
13
+ export declare function _getObjectFromStorage<T>(key: string): T | null;
14
+ export declare function _setObjectInStorage(key: string, obj: unknown): void;
16
15
  export {};
@@ -1,26 +1,19 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports._setObjectInStorage = exports._getObjectFromStorage = exports.Storage = void 0;
13
4
  const Log_1 = require("./Log");
14
5
  const SafeJs_1 = require("./SafeJs");
15
6
  const inMemoryStore = {};
16
- const _resolve = (input) => Promise.resolve(input);
17
7
  const _inMemoryProvider = {
18
8
  _getProviderName: () => 'InMemory',
19
- _getItemSync: (key) => inMemoryStore[key] ? inMemoryStore[key] : null,
20
- _getItem: (key) => _resolve(inMemoryStore[key] ? inMemoryStore[key] : null),
21
- _setItem: (key, value) => ((inMemoryStore[key] = value), _resolve()),
22
- _removeItem: (key) => (delete inMemoryStore[key], _resolve()),
23
- _getAllKeys: () => _resolve(Object.keys(inMemoryStore)),
9
+ _getItem: (key) => inMemoryStore[key] ? inMemoryStore[key] : null,
10
+ _setItem: (key, value) => {
11
+ inMemoryStore[key] = value;
12
+ },
13
+ _removeItem: (key) => {
14
+ delete inMemoryStore[key];
15
+ },
16
+ _getAllKeys: () => Object.keys(inMemoryStore),
24
17
  };
25
18
  let _localStorageProvider = null;
26
19
  try {
@@ -30,11 +23,10 @@ try {
30
23
  typeof win.localStorage.getItem === 'function') {
31
24
  _localStorageProvider = {
32
25
  _getProviderName: () => 'LocalStorage',
33
- _getItemSync: (key) => win.localStorage.getItem(key),
34
- _getItem: (key) => _resolve(win.localStorage.getItem(key)),
35
- _setItem: (key, value) => (win.localStorage.setItem(key, value), _resolve()),
36
- _removeItem: (key) => (win.localStorage.removeItem(key), _resolve()),
37
- _getAllKeys: () => _resolve(Object.keys(win.localStorage)),
26
+ _getItem: (key) => win.localStorage.getItem(key),
27
+ _setItem: (key, value) => win.localStorage.setItem(key, value),
28
+ _removeItem: (key) => win.localStorage.removeItem(key),
29
+ _getAllKeys: () => Object.keys(win.localStorage),
38
30
  };
39
31
  }
40
32
  }
@@ -57,8 +49,7 @@ function _inMemoryBreaker(get) {
57
49
  }
58
50
  exports.Storage = {
59
51
  _getProviderName: () => _current._getProviderName(),
60
- _getItem: (key) => __awaiter(void 0, void 0, void 0, function* () { return _inMemoryBreaker(() => _current._getItem(key)); }),
61
- _getItemSync: (key) => _inMemoryBreaker(() => _current._getItemSync ? _current._getItemSync(key) : null),
52
+ _getItem: (key) => _inMemoryBreaker(() => _current._getItem(key)),
62
53
  _setItem: (key, value) => _current._setItem(key, value),
63
54
  _removeItem: (key) => _current._removeItem(key),
64
55
  _getAllKeys: () => _current._getAllKeys(),
@@ -77,15 +68,11 @@ exports.Storage = {
77
68
  },
78
69
  };
79
70
  function _getObjectFromStorage(key) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- const value = yield exports.Storage._getItem(key);
82
- return JSON.parse(value !== null && value !== void 0 ? value : 'null');
83
- });
71
+ const value = exports.Storage._getItem(key);
72
+ return JSON.parse(value !== null && value !== void 0 ? value : 'null');
84
73
  }
85
74
  exports._getObjectFromStorage = _getObjectFromStorage;
86
75
  function _setObjectInStorage(key, obj) {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- yield exports.Storage._setItem(key, JSON.stringify(obj));
89
- });
76
+ exports.Storage._setItem(key, JSON.stringify(obj));
90
77
  }
91
78
  exports._setObjectInStorage = _setObjectInStorage;
package/src/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /** Statsig Global should go first */
2
2
  import './$_StatsigGlobal';
3
+ import { Diagnostics } from './Diagnostics';
3
4
  import { EventLogger } from './EventLogger';
4
5
  import { Log } from './Log';
5
6
  import { Storage } from './StorageProvider';
@@ -7,6 +8,7 @@ export * from './$_StatsigGlobal';
7
8
  export * from './CacheKey';
8
9
  export * from './ClientInterfaces';
9
10
  export * from './DataAdapterCore';
11
+ export * from './Diagnostics';
10
12
  export * from './DownloadConfigSpecsResponse';
11
13
  export * from './ErrorBoundary';
12
14
  export * from './EvaluationOptions';
@@ -37,4 +39,4 @@ export * from './TypingUtils';
37
39
  export * from './UrlOverrides';
38
40
  export * from './UUID';
39
41
  export * from './VisibilityObserving';
40
- export { EventLogger, Storage, Log };
42
+ export { EventLogger, Storage, Log, Diagnostics };
package/src/index.js CHANGED
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Log = exports.Storage = exports.EventLogger = void 0;
17
+ exports.Diagnostics = exports.Log = exports.Storage = exports.EventLogger = void 0;
18
18
  /** Statsig Global should go first */
19
19
  require("./$_StatsigGlobal");
20
+ const Diagnostics_1 = require("./Diagnostics");
21
+ Object.defineProperty(exports, "Diagnostics", { enumerable: true, get: function () { return Diagnostics_1.Diagnostics; } });
20
22
  const EventLogger_1 = require("./EventLogger");
21
23
  Object.defineProperty(exports, "EventLogger", { enumerable: true, get: function () { return EventLogger_1.EventLogger; } });
22
24
  const Log_1 = require("./Log");
@@ -28,6 +30,7 @@ __exportStar(require("./$_StatsigGlobal"), exports);
28
30
  __exportStar(require("./CacheKey"), exports);
29
31
  __exportStar(require("./ClientInterfaces"), exports);
30
32
  __exportStar(require("./DataAdapterCore"), exports);
33
+ __exportStar(require("./Diagnostics"), exports);
31
34
  __exportStar(require("./DownloadConfigSpecsResponse"), exports);
32
35
  __exportStar(require("./ErrorBoundary"), exports);
33
36
  __exportStar(require("./EvaluationOptions"), exports);