@statsig/client-core 0.0.1-beta.3 → 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 (74) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/$_StatsigGlobal.d.ts +7 -1
  4. package/src/$_StatsigGlobal.js +15 -12
  5. package/src/ClientInterfaces.d.ts +47 -14
  6. package/src/DataAdapterCore.d.ts +32 -0
  7. package/src/DataAdapterCore.js +167 -0
  8. package/src/Diagnostics.js +24 -26
  9. package/src/DownloadConfigSpecsResponse.d.ts +41 -0
  10. package/src/ErrorBoundary.d.ts +1 -0
  11. package/src/ErrorBoundary.js +41 -86
  12. package/src/EvaluationOptions.d.ts +20 -0
  13. package/src/EvaluationOptions.js +2 -0
  14. package/src/EvaluationTypes.d.ts +39 -0
  15. package/src/EvaluationTypes.js +2 -0
  16. package/src/EventLogger.d.ts +21 -8
  17. package/src/EventLogger.js +206 -228
  18. package/src/Hashing.d.ts +2 -1
  19. package/src/Hashing.js +25 -6
  20. package/src/InitializeResponse.d.ts +18 -0
  21. package/src/InitializeResponse.js +2 -0
  22. package/src/Log.js +15 -34
  23. package/src/Monitoring.d.ts +1 -2
  24. package/src/Monitoring.js +68 -27
  25. package/src/NetworkCore.d.ts +17 -6
  26. package/src/NetworkCore.js +115 -166
  27. package/src/NetworkDefaults.d.ts +5 -0
  28. package/src/NetworkDefaults.js +8 -0
  29. package/src/NetworkParams.d.ts +9 -0
  30. package/src/NetworkParams.js +13 -0
  31. package/src/OverrideAdapter.d.ts +9 -0
  32. package/src/OverrideAdapter.js +2 -0
  33. package/src/SDKType.d.ts +8 -0
  34. package/src/SDKType.js +19 -0
  35. package/src/SafeJs.d.ts +4 -0
  36. package/src/SafeJs.js +27 -0
  37. package/src/SessionID.d.ts +10 -1
  38. package/src/SessionID.js +86 -6
  39. package/src/StableID.js +24 -53
  40. package/src/StatsigClientBase.d.ts +57 -28
  41. package/src/StatsigClientBase.js +110 -238
  42. package/src/StatsigClientEventEmitter.d.ts +64 -28
  43. package/src/StatsigDataAdapter.d.ts +89 -0
  44. package/src/StatsigDataAdapter.js +4 -0
  45. package/src/StatsigEvent.d.ts +10 -19
  46. package/src/StatsigEvent.js +50 -41
  47. package/src/StatsigMetadata.d.ts +1 -1
  48. package/src/StatsigMetadata.js +7 -18
  49. package/src/StatsigOptionsCommon.d.ts +68 -17
  50. package/src/StatsigTypeFactories.d.ts +6 -0
  51. package/src/StatsigTypeFactories.js +50 -0
  52. package/src/StatsigTypes.d.ts +29 -18
  53. package/src/StatsigTypes.js +0 -29
  54. package/src/StatsigUser.d.ts +2 -5
  55. package/src/StatsigUser.js +10 -18
  56. package/src/StorageProvider.d.ts +12 -7
  57. package/src/StorageProvider.js +58 -67
  58. package/src/TypedJsonParse.d.ts +8 -0
  59. package/src/TypedJsonParse.js +27 -0
  60. package/src/UUID.js +9 -5
  61. package/src/UrlOverrides.d.ts +1 -0
  62. package/src/UrlOverrides.js +15 -0
  63. package/src/UtitlityTypes.d.ts +3 -0
  64. package/src/UtitlityTypes.js +2 -0
  65. package/src/VisibilityObserving.d.ts +8 -0
  66. package/src/VisibilityObserving.js +30 -0
  67. package/src/index.d.ts +21 -4
  68. package/src/index.js +31 -17
  69. package/src/StatsigDataProvider.d.ts +0 -9
  70. package/src/VisibilityChangeObserver.d.ts +0 -13
  71. package/src/VisibilityChangeObserver.js +0 -48
  72. package/src/__tests__/MockLocalStorage.d.ts +0 -9
  73. package/src/__tests__/MockLocalStorage.js +0 -37
  74. /package/src/{StatsigDataProvider.js → DownloadConfigSpecsResponse.js} +0 -0
package/README.md CHANGED
@@ -5,4 +5,4 @@
5
5
 
6
6
  The package that contains all the common logic shared by the various Statsig Javascript packages.
7
7
 
8
- Learn more by visiting: https://docs.statsig.com/client/jsClientSDK
8
+ Learn more by visiting: https://docs.statsig.com/client/javascript-sdk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statsig/client-core",
3
- "version": "0.0.1-beta.3",
3
+ "version": "0.0.1-beta.30",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -1,6 +1,11 @@
1
+ import { StatsigClientInterface } from './ClientInterfaces';
1
2
  export type StatsigGlobal = {
2
3
  [key: string]: unknown;
3
- instances?: Set<unknown>;
4
+ instances?: Record<string, StatsigClientInterface>;
5
+ lastInstance?: StatsigClientInterface;
6
+ acInstances?: Record<string, unknown>;
7
+ srInstances?: Record<string, unknown>;
8
+ instance?: (sdkKey: string) => StatsigClientInterface | undefined;
4
9
  };
5
10
  declare global {
6
11
  let __STATSIG__: StatsigGlobal | undefined;
@@ -8,3 +13,4 @@ declare global {
8
13
  __STATSIG__: StatsigGlobal | undefined;
9
14
  }
10
15
  }
16
+ export declare const _getStatsigGlobal: () => StatsigGlobal;
@@ -1,14 +1,17 @@
1
1
  "use strict";
2
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
+ var _a, _b, _c;
2
4
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var statsigGlobal = {};
4
- if (typeof window !== 'undefined') {
5
- window.__STATSIG__ = statsigGlobal;
6
- }
7
- if (typeof global !== 'undefined') {
8
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
9
- global.__STATSIG__ = statsigGlobal;
10
- }
11
- if (typeof globalThis !== 'undefined') {
12
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
13
- globalThis.__STATSIG__ = statsigGlobal;
14
- }
5
+ exports._getStatsigGlobal = void 0;
6
+ const GLOBAL_KEY = '__STATSIG__';
7
+ const _window = typeof window !== 'undefined' ? window : {};
8
+ const _global = typeof global !== 'undefined' ? global : {};
9
+ const _globalThis = typeof globalThis !== 'undefined' ? globalThis : {};
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,28 +1,61 @@
1
- import { EvaluationOptions } from './StatsigClientBase';
1
+ import { DownloadConfigSpecsResponse } from './DownloadConfigSpecsResponse';
2
+ import { DynamicConfigEvaluationOptions, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, LayerEvaluationOptions } from './EvaluationOptions';
3
+ import { InitializeResponseWithUpdates } from './InitializeResponse';
2
4
  import { StatsigClientEventEmitterInterface } from './StatsigClientEventEmitter';
5
+ import { EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
3
6
  import { StatsigEvent } from './StatsigEvent';
7
+ import { AnyStatsigOptions, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
4
8
  import { DynamicConfig, Experiment, FeatureGate, Layer } from './StatsigTypes';
5
9
  import { StatsigUser } from './StatsigUser';
10
+ import { Flatten } from './UtitlityTypes';
6
11
  export interface StatsigClientCommonInterface extends StatsigClientEventEmitterInterface {
7
- initialize(): Promise<void>;
12
+ initializeSync(): void;
13
+ initializeAsync(): Promise<void>;
8
14
  shutdown(): Promise<void>;
15
+ flush(): Promise<void>;
16
+ updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
9
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;
10
30
  export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterface {
11
- checkGate(name: string, user: StatsigUser, options: EvaluationOptions): boolean;
12
- getFeatureGate(name: string, user: StatsigUser, options: EvaluationOptions): FeatureGate;
13
- getDynamicConfig(name: string, user: StatsigUser, options: EvaluationOptions): DynamicConfig;
14
- getExperiment(name: string, user: StatsigUser, options: EvaluationOptions): Experiment;
15
- getLayer(name: string, user: StatsigUser, options: EvaluationOptions): Layer;
31
+ readonly dataAdapter: SpecsDataAdapter;
32
+ getAsyncContext(): Promise<OnDeviceEvaluationsAsyncContext>;
33
+ getContext(): OnDeviceEvaluationsContext;
34
+ checkGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): boolean;
35
+ getFeatureGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): FeatureGate;
36
+ getDynamicConfig(name: string, user: StatsigUser, options?: DynamicConfigEvaluationOptions): DynamicConfig;
37
+ getExperiment(name: string, user: StatsigUser, options?: ExperimentEvaluationOptions): Experiment;
38
+ getLayer(name: string, user: StatsigUser, options?: LayerEvaluationOptions): Layer;
16
39
  logEvent(event: StatsigEvent, user: StatsigUser): void;
40
+ logEvent(eventName: string, user: StatsigUser, value?: string | number, metadata?: Record<string, string>): void;
17
41
  }
42
+ export type PrecomputedEvaluationsContext = Flatten<CommonContext & {
43
+ values: InitializeResponseWithUpdates | null;
44
+ user: StatsigUser;
45
+ }>;
46
+ export type PrecomputedEvaluationsAsyncContext = Flatten<AsyncCommonContext & PrecomputedEvaluationsContext>;
18
47
  export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
19
- getCurrentUser(): StatsigUser;
20
- updateUser(user: StatsigUser): Promise<void>;
21
- checkGate(name: string, options: EvaluationOptions): boolean;
22
- getFeatureGate(name: string, options: EvaluationOptions): FeatureGate;
23
- getDynamicConfig(name: string, options: EvaluationOptions): DynamicConfig;
24
- getExperiment(name: string, options: EvaluationOptions): Experiment;
25
- getLayer(name: string, options: EvaluationOptions): Layer;
48
+ readonly dataAdapter: EvaluationsDataAdapter;
49
+ getAsyncContext(): Promise<PrecomputedEvaluationsAsyncContext>;
50
+ getContext(): PrecomputedEvaluationsContext;
51
+ updateUserSync(user: StatsigUser): void;
52
+ updateUserAsync(user: StatsigUser): Promise<void>;
53
+ checkGate(name: string, options?: FeatureGateEvaluationOptions): boolean;
54
+ getFeatureGate(name: string, options?: FeatureGateEvaluationOptions): FeatureGate;
55
+ getDynamicConfig(name: string, options?: DynamicConfigEvaluationOptions): DynamicConfig;
56
+ getExperiment(name: string, options?: ExperimentEvaluationOptions): Experiment;
57
+ getLayer(name: string, options?: LayerEvaluationOptions): Layer;
26
58
  logEvent(event: StatsigEvent): void;
59
+ logEvent(eventName: string, value?: string | number, metadata?: Record<string, string>): void;
27
60
  }
28
61
  export type StatsigClientInterface = OnDeviceEvaluationsInterface | PrecomputedEvaluationsInterface;
@@ -0,0 +1,32 @@
1
+ import { ErrorBoundary } from './ErrorBoundary';
2
+ import { DataAdapterResult } from './StatsigDataAdapter';
3
+ import { AnyStatsigOptions } from './StatsigOptionsCommon';
4
+ import { StatsigUser } from './StatsigUser';
5
+ export declare abstract class DataAdapterCore {
6
+ private _adapterName;
7
+ private _cacheSuffix;
8
+ protected _errorBoundary: ErrorBoundary | null;
9
+ private _sdkKey;
10
+ private _inMemoryCache;
11
+ private _lastModifiedStoreKey;
12
+ protected constructor(_adapterName: string, _cacheSuffix: string);
13
+ attach(sdkKey: string, _options: AnyStatsigOptions | null): void;
14
+ getDataSync(user?: StatsigUser | undefined): DataAdapterResult | null;
15
+ getDataAsync(current: DataAdapterResult | null, user?: StatsigUser): Promise<DataAdapterResult | null>;
16
+ prefetchData(user?: StatsigUser | undefined): Promise<void>;
17
+ setData(data: string, user?: StatsigUser): void;
18
+ /**
19
+ * (Internal Use Only) - Used by \@statsig/react-native-bindings to prime the cache from AsyncStorage
20
+ *
21
+ * @param {Record<string, DataAdapterResult>} cache The values to merge into _inMemoryCache
22
+ */
23
+ __primeInMemoryCache(cache: Record<string, DataAdapterResult>): void;
24
+ protected abstract _fetchFromNetwork(current: string | null, user?: StatsigUser): Promise<string | null>;
25
+ private _fetchLatest;
26
+ protected _getSdkKey(): string;
27
+ protected _getCacheKey(user?: StatsigUser): string;
28
+ protected _addToInMemoryCache(cacheKey: string, result: DataAdapterResult): void;
29
+ private _loadFromCache;
30
+ private _writeToCache;
31
+ private _runLocalStorageCacheEviction;
32
+ }
@@ -0,0 +1,167 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DataAdapterCore = void 0;
13
+ const ErrorBoundary_1 = require("./ErrorBoundary");
14
+ const Log_1 = require("./Log");
15
+ const Monitoring_1 = require("./Monitoring");
16
+ const StatsigDataAdapter_1 = require("./StatsigDataAdapter");
17
+ const StatsigUser_1 = require("./StatsigUser");
18
+ const StorageProvider_1 = require("./StorageProvider");
19
+ const TypedJsonParse_1 = require("./TypedJsonParse");
20
+ const CACHE_LIMIT = 10;
21
+ class DataAdapterCore {
22
+ constructor(_adapterName, _cacheSuffix) {
23
+ this._adapterName = _adapterName;
24
+ this._cacheSuffix = _cacheSuffix;
25
+ this._errorBoundary = null;
26
+ this._sdkKey = null;
27
+ this._inMemoryCache = {};
28
+ this._lastModifiedStoreKey = `statsig.last_modified_time.${_cacheSuffix}`;
29
+ }
30
+ attach(sdkKey, _options) {
31
+ this._sdkKey = sdkKey;
32
+ this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(sdkKey);
33
+ (0, Monitoring_1.monitorClass)(this._errorBoundary, this);
34
+ }
35
+ getDataSync(user) {
36
+ const cacheKey = this._getCacheKey(user);
37
+ const result = this._inMemoryCache[cacheKey];
38
+ if (result) {
39
+ return result;
40
+ }
41
+ const cache = this._loadFromCache(cacheKey);
42
+ if (cache) {
43
+ this._addToInMemoryCache(cacheKey, cache);
44
+ return this._inMemoryCache[cacheKey];
45
+ }
46
+ return null;
47
+ }
48
+ getDataAsync(current, user) {
49
+ var _a;
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const cache = current !== null && current !== void 0 ? current : this.getDataSync(user);
52
+ const latest = yield this._fetchLatest((_a = cache === null || cache === void 0 ? void 0 : cache.data) !== null && _a !== void 0 ? _a : null, user);
53
+ const cacheKey = this._getCacheKey(user);
54
+ if (latest) {
55
+ this._addToInMemoryCache(cacheKey, latest);
56
+ }
57
+ if ((latest === null || latest === void 0 ? void 0 : latest.source) === 'Network' ||
58
+ (latest === null || latest === void 0 ? void 0 : latest.source) === 'NetworkNotModified') {
59
+ yield this._writeToCache(cacheKey, latest);
60
+ }
61
+ return latest;
62
+ });
63
+ }
64
+ prefetchData(user) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ const cacheKey = this._getCacheKey(user);
67
+ const result = yield this.getDataAsync(null, user);
68
+ if (result) {
69
+ this._addToInMemoryCache(cacheKey, Object.assign(Object.assign({}, result), { source: 'Prefetch' }));
70
+ }
71
+ });
72
+ }
73
+ setData(data, user) {
74
+ const cacheKey = this._getCacheKey(user);
75
+ this._addToInMemoryCache(cacheKey, {
76
+ source: 'Bootstrap',
77
+ data,
78
+ receivedAt: Date.now(),
79
+ });
80
+ }
81
+ /**
82
+ * (Internal Use Only) - Used by \@statsig/react-native-bindings to prime the cache from AsyncStorage
83
+ *
84
+ * @param {Record<string, DataAdapterResult>} cache The values to merge into _inMemoryCache
85
+ */
86
+ __primeInMemoryCache(cache) {
87
+ this._inMemoryCache = Object.assign(Object.assign({}, this._inMemoryCache), cache);
88
+ }
89
+ _fetchLatest(current, user) {
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ const latest = yield this._fetchFromNetwork(current, user);
92
+ if (!latest) {
93
+ Log_1.Log.debug('No response returned for latest value');
94
+ return null;
95
+ }
96
+ const response = (0, TypedJsonParse_1.typedJsonParse)(latest, 'has_updates', 'Failure while attempting to persist latest value');
97
+ if (current && (response === null || response === void 0 ? void 0 : response.has_updates) === false) {
98
+ return {
99
+ source: 'NetworkNotModified',
100
+ data: current,
101
+ receivedAt: Date.now(),
102
+ };
103
+ }
104
+ if ((response === null || response === void 0 ? void 0 : response.has_updates) !== true) {
105
+ return null;
106
+ }
107
+ return { source: 'Network', data: latest, receivedAt: Date.now() };
108
+ });
109
+ }
110
+ _getSdkKey() {
111
+ if (this._sdkKey != null) {
112
+ return this._sdkKey;
113
+ }
114
+ Log_1.Log.error(`${this._adapterName} is not attached to a Client`);
115
+ return '';
116
+ }
117
+ _getCacheKey(user) {
118
+ const key = (0, StatsigUser_1.getUserStorageKey)(this._getSdkKey(), user);
119
+ return `${StatsigDataAdapter_1.DataAdapterCachePrefix}.${this._cacheSuffix}.${key}`;
120
+ }
121
+ _addToInMemoryCache(cacheKey, result) {
122
+ const entries = Object.entries(this._inMemoryCache);
123
+ if (entries.length < CACHE_LIMIT) {
124
+ this._inMemoryCache[cacheKey] = result;
125
+ return;
126
+ }
127
+ const [oldest] = entries.reduce((acc, curr) => {
128
+ return curr[1] < acc[1] ? curr : acc;
129
+ });
130
+ delete this._inMemoryCache[oldest];
131
+ this._inMemoryCache[cacheKey] = result;
132
+ }
133
+ _loadFromCache(cacheKey) {
134
+ var _a;
135
+ const cache = (_a = StorageProvider_1.Storage._getItemSync) === null || _a === void 0 ? void 0 : _a.call(StorageProvider_1.Storage, cacheKey);
136
+ if (cache == null) {
137
+ return null;
138
+ }
139
+ const result = (0, TypedJsonParse_1.typedJsonParse)(cache, 'source', 'Failed to parse cached result');
140
+ return result ? Object.assign(Object.assign({}, result), { source: 'Cache' }) : null;
141
+ }
142
+ _writeToCache(cacheKey, result) {
143
+ return __awaiter(this, void 0, void 0, function* () {
144
+ yield StorageProvider_1.Storage._setItem(cacheKey, JSON.stringify(result));
145
+ yield this._runLocalStorageCacheEviction(cacheKey);
146
+ });
147
+ }
148
+ _runLocalStorageCacheEviction(cacheKey) {
149
+ var _a;
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 : {};
152
+ lastModifiedTimeMap[cacheKey] = Date.now();
153
+ const entries = Object.entries(lastModifiedTimeMap);
154
+ if (entries.length <= CACHE_LIMIT) {
155
+ yield (0, StorageProvider_1._setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
156
+ return;
157
+ }
158
+ const oldest = entries.reduce((acc, current) => {
159
+ return current[1] < acc[1] ? current : acc;
160
+ });
161
+ delete lastModifiedTimeMap[oldest[0]];
162
+ yield StorageProvider_1.Storage._removeItem(oldest[0]);
163
+ yield (0, StorageProvider_1._setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
164
+ });
165
+ }
166
+ }
167
+ exports.DataAdapterCore = DataAdapterCore;
@@ -1,18 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Diagnostics = exports.captureDiagnostics = void 0;
4
- var Log_1 = require("./Log");
5
- var SUPPORTS_PERFORMANCE_API = typeof performance !== 'undefined' && typeof performance.mark !== 'undefined';
6
- var markers = [];
4
+ const Log_1 = require("./Log");
5
+ const NetworkDefaults_1 = require("./NetworkDefaults");
6
+ const SUPPORTS_PERFORMANCE_API = typeof performance !== 'undefined' && typeof performance.mark !== 'undefined';
7
+ let markers = [];
7
8
  function captureDiagnostics(func, task) {
8
- Diagnostics.mark("".concat(func, ":start"));
9
- var result = task();
10
- var markEnd = function () {
11
- Diagnostics.mark("".concat(func, ":end"));
12
- maybeFlush("".concat(func, ":end"));
9
+ Diagnostics.mark(`${func}:start`);
10
+ const result = task();
11
+ const markEnd = () => {
12
+ Diagnostics.mark(`${func}:end`);
13
+ maybeFlush(`${func}:end`);
13
14
  };
14
15
  if (result && result instanceof Promise) {
15
- return result.finally(function () { return markEnd(); });
16
+ return result.finally(() => markEnd());
16
17
  }
17
18
  else {
18
19
  markEnd();
@@ -20,32 +21,29 @@ function captureDiagnostics(func, task) {
20
21
  return result;
21
22
  }
22
23
  exports.captureDiagnostics = captureDiagnostics;
23
- var Diagnostics = /** @class */ (function () {
24
- function Diagnostics() {
25
- }
26
- Diagnostics.mark = function (tag, metadata) {
24
+ class Diagnostics {
25
+ static mark(tag, metadata) {
27
26
  if (!SUPPORTS_PERFORMANCE_API) {
28
27
  return;
29
28
  }
30
- var marker = performance.mark(tag, { detail: metadata });
29
+ const marker = performance.mark(tag, { detail: metadata });
31
30
  markers.push(marker);
32
- };
33
- Diagnostics.flush = function () {
34
- var resources = performance
31
+ }
32
+ static flush() {
33
+ const resources = performance
35
34
  .getEntriesByType('resource')
36
- .filter(function (resource) {
37
- return resource.name.startsWith('https://api.statsig.com');
38
- });
39
- var payload = {
40
- markers: markers,
41
- resources: resources,
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));
38
+ const payload = {
39
+ markers,
40
+ resources,
42
41
  };
43
42
  // TODO: Send as log to Statsig
44
43
  Log_1.Log.debug('Diagnostics', payload, JSON.stringify(payload));
45
44
  markers = [];
46
- };
47
- return Diagnostics;
48
- }());
45
+ }
46
+ }
49
47
  exports.Diagnostics = Diagnostics;
50
48
  function maybeFlush(tag) {
51
49
  if (tag.startsWith('initialize:')) {
@@ -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
+ };
@@ -5,5 +5,6 @@ export declare class ErrorBoundary {
5
5
  private _seen;
6
6
  constructor(_sdkKey: string);
7
7
  capture(tag: string, task: () => unknown, emitter?: StatsigClientEmitEventFunc): unknown;
8
+ logError(tag: string, error: unknown): void;
8
9
  private _onError;
9
10
  }
@@ -1,15 +1,4 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
3
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
4
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -19,49 +8,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
19
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
20
9
  });
21
10
  };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
11
  Object.defineProperty(exports, "__esModule", { value: true });
50
12
  exports.ErrorBoundary = exports.EXCEPTION_ENDPOINT = void 0;
51
- var Log_1 = require("./Log");
52
- var StatsigMetadata_1 = require("./StatsigMetadata");
13
+ const Log_1 = require("./Log");
14
+ const SDKType_1 = require("./SDKType");
15
+ const StatsigMetadata_1 = require("./StatsigMetadata");
53
16
  exports.EXCEPTION_ENDPOINT = 'https://statsigapi.net/v1/sdk_exception';
54
- var ErrorBoundary = /** @class */ (function () {
55
- function ErrorBoundary(_sdkKey) {
17
+ class ErrorBoundary {
18
+ constructor(_sdkKey) {
56
19
  this._sdkKey = _sdkKey;
57
20
  this._seen = new Set();
58
21
  }
59
- ErrorBoundary.prototype.capture = function (tag, task, emitter) {
60
- var _this = this;
22
+ capture(tag, task, emitter) {
61
23
  try {
62
- var res = task();
24
+ const res = task();
63
25
  if (res && res instanceof Promise) {
64
- return res.catch(function (err) { return _this._onError(tag, err, emitter); });
26
+ return res.catch((err) => this._onError(tag, err, emitter));
65
27
  }
66
28
  return res;
67
29
  }
@@ -69,57 +31,50 @@ var ErrorBoundary = /** @class */ (function () {
69
31
  this._onError(tag, error, emitter);
70
32
  return null;
71
33
  }
72
- };
73
- ErrorBoundary.prototype._onError = function (tag, error, emitter) {
74
- var _this = this;
34
+ }
35
+ logError(tag, error) {
36
+ this._onError(tag, error);
37
+ }
38
+ _onError(tag, error, emitter) {
75
39
  try {
76
- Log_1.Log.warn("Caught error in ".concat(tag), { error: error });
77
- var impl = function () { return __awaiter(_this, void 0, void 0, function () {
78
- var unwrapped, isError, name, statsigMetadata, info, body;
79
- return __generator(this, function (_a) {
80
- switch (_a.label) {
81
- case 0:
82
- unwrapped = (error !== null && error !== void 0 ? error : Error('[Statsig] Error was empty'));
83
- isError = unwrapped instanceof Error;
84
- name = isError ? unwrapped.name : 'No Name';
85
- if (this._seen.has(name)) {
86
- return [2 /*return*/];
87
- }
88
- this._seen.add(name);
89
- statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
90
- info = isError ? unwrapped.stack : _getDescription(unwrapped);
91
- body = JSON.stringify(__assign({ tag: tag, exception: name, info: info }, statsigMetadata));
92
- return [4 /*yield*/, fetch(exports.EXCEPTION_ENDPOINT, {
93
- method: 'POST',
94
- headers: {
95
- 'STATSIG-API-KEY': this._sdkKey,
96
- 'STATSIG-SDK-TYPE': String(statsigMetadata.sdkType),
97
- 'STATSIG-SDK-VERSION': String(statsigMetadata.sdkVersion),
98
- 'Content-Type': 'application/json',
99
- },
100
- body: body,
101
- })];
102
- case 1:
103
- _a.sent();
104
- emitter === null || emitter === void 0 ? void 0 : emitter({ event: 'error', error: error });
105
- return [2 /*return*/];
106
- }
40
+ Log_1.Log.warn(`Caught error in ${tag}`, { error });
41
+ const impl = () => __awaiter(this, void 0, void 0, function* () {
42
+ const unwrapped = (error !== null && error !== void 0 ? error : Error('[Statsig] Error was empty'));
43
+ const isError = unwrapped instanceof Error;
44
+ const name = isError ? unwrapped.name : 'No Name';
45
+ if (this._seen.has(name)) {
46
+ return;
47
+ }
48
+ this._seen.add(name);
49
+ const sdkType = SDKType_1.SDKType._get(this._sdkKey);
50
+ const statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
51
+ const info = isError ? unwrapped.stack : _getDescription(unwrapped);
52
+ const body = JSON.stringify(Object.assign({ tag, exception: name, info }, Object.assign(Object.assign({}, statsigMetadata), { sdkType })));
53
+ yield fetch(exports.EXCEPTION_ENDPOINT, {
54
+ method: 'POST',
55
+ headers: {
56
+ 'STATSIG-API-KEY': this._sdkKey,
57
+ 'STATSIG-SDK-TYPE': String(sdkType),
58
+ 'STATSIG-SDK-VERSION': String(statsigMetadata.sdkVersion),
59
+ 'Content-Type': 'application/json',
60
+ },
61
+ body,
107
62
  });
108
- }); };
63
+ emitter === null || emitter === void 0 ? void 0 : emitter({ name: 'error', error });
64
+ });
109
65
  impl()
110
- .then(function () {
66
+ .then(() => {
111
67
  /* noop */
112
68
  })
113
- .catch(function () {
69
+ .catch(() => {
114
70
  /* noop */
115
71
  });
116
72
  }
117
73
  catch (_error) {
118
74
  /* noop */
119
75
  }
120
- };
121
- return ErrorBoundary;
122
- }());
76
+ }
77
+ }
123
78
  exports.ErrorBoundary = ErrorBoundary;
124
79
  function _getDescription(obj) {
125
80
  try {
@@ -0,0 +1,20 @@
1
+ export type EvaluationOptionsCommon = {
2
+ /**
3
+ * Prevents an exposure log being created for this check.
4
+ *
5
+ * default: `false`
6
+ */
7
+ disableExposureLog?: boolean;
8
+ };
9
+ export type FeatureGateEvaluationOptions = EvaluationOptionsCommon & {};
10
+ export type DynamicConfigEvaluationOptions = EvaluationOptionsCommon & {};
11
+ export type ExperimentEvaluationOptions = EvaluationOptionsCommon & {
12
+ /**
13
+ * Provide a map of values to be used across checks
14
+ *
15
+ * @requires {@link @statsig/js-user-persisted-storage}
16
+ * @see {@link https://docs.statsig.com/client/concepts/persistent_assignment#example-usage}
17
+ */
18
+ userPersistedValues?: unknown;
19
+ };
20
+ export type LayerEvaluationOptions = EvaluationOptionsCommon & {};