@statsig/client-core 0.0.1-beta.9 → 1.0.1

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/package.json +1 -1
  2. package/src/$_StatsigGlobal.d.ts +9 -1
  3. package/src/$_StatsigGlobal.js +29 -12
  4. package/src/CacheKey.d.ts +4 -0
  5. package/src/CacheKey.js +28 -0
  6. package/src/ClientInterfaces.d.ts +46 -12
  7. package/src/DataAdapterCore.d.ts +31 -0
  8. package/src/DataAdapterCore.js +196 -0
  9. package/src/Diagnostics.d.ts +1 -3
  10. package/src/Diagnostics.js +4 -49
  11. package/src/DownloadConfigSpecsResponse.d.ts +41 -0
  12. package/src/DownloadConfigSpecsResponse.js +2 -0
  13. package/src/ErrorBoundary.d.ts +7 -2
  14. package/src/ErrorBoundary.js +81 -88
  15. package/src/EvaluationOptions.d.ts +20 -0
  16. package/src/EvaluationOptions.js +2 -0
  17. package/src/EvaluationTypes.d.ts +39 -0
  18. package/src/EvaluationTypes.js +2 -0
  19. package/src/EventLogger.d.ts +15 -10
  20. package/src/EventLogger.js +216 -256
  21. package/src/Hashing.d.ts +2 -1
  22. package/src/Hashing.js +26 -7
  23. package/src/InitializeResponse.d.ts +20 -0
  24. package/src/InitializeResponse.js +2 -0
  25. package/src/Log.js +15 -34
  26. package/src/NetworkConfig.d.ts +19 -0
  27. package/src/NetworkConfig.js +19 -0
  28. package/src/NetworkCore.d.ts +17 -7
  29. package/src/NetworkCore.js +173 -196
  30. package/src/OverrideAdapter.d.ts +9 -0
  31. package/src/OverrideAdapter.js +2 -0
  32. package/src/SDKType.d.ts +8 -0
  33. package/src/SDKType.js +19 -0
  34. package/src/SafeJs.d.ts +6 -0
  35. package/src/SafeJs.js +41 -0
  36. package/src/SessionID.d.ts +17 -1
  37. package/src/SessionID.js +89 -8
  38. package/src/StableID.js +24 -53
  39. package/src/StatsigClientBase.d.ts +56 -19
  40. package/src/StatsigClientBase.js +126 -48
  41. package/src/StatsigClientEventEmitter.d.ts +54 -33
  42. package/src/StatsigDataAdapter.d.ts +103 -17
  43. package/src/StatsigDataAdapter.js +2 -0
  44. package/src/StatsigEvent.d.ts +10 -18
  45. package/src/StatsigEvent.js +41 -39
  46. package/src/StatsigMetadata.d.ts +1 -1
  47. package/src/StatsigMetadata.js +7 -18
  48. package/src/StatsigOptionsCommon.d.ts +84 -20
  49. package/src/StatsigTypeFactories.d.ts +6 -0
  50. package/src/StatsigTypeFactories.js +50 -0
  51. package/src/StatsigTypes.d.ts +28 -22
  52. package/src/StatsigTypes.js +0 -29
  53. package/src/StatsigUser.d.ts +7 -8
  54. package/src/StatsigUser.js +11 -24
  55. package/src/StorageProvider.d.ts +13 -8
  56. package/src/StorageProvider.js +66 -85
  57. package/src/TypedJsonParse.d.ts +8 -0
  58. package/src/TypedJsonParse.js +27 -0
  59. package/src/UUID.js +9 -5
  60. package/src/UrlOverrides.d.ts +1 -0
  61. package/src/UrlOverrides.js +15 -0
  62. package/src/UtitlityTypes.d.ts +3 -0
  63. package/src/UtitlityTypes.js +2 -0
  64. package/src/VisibilityObserving.d.ts +9 -0
  65. package/src/VisibilityObserving.js +39 -0
  66. package/src/index.d.ts +20 -4
  67. package/src/index.js +26 -18
  68. package/README.md +0 -8
  69. package/src/Monitoring.d.ts +0 -3
  70. package/src/Monitoring.js +0 -33
  71. package/src/VisibilityChangeObserver.d.ts +0 -13
  72. package/src/VisibilityChangeObserver.js +0 -48
  73. package/src/__tests__/MockLocalStorage.d.ts +0 -9
  74. package/src/__tests__/MockLocalStorage.js +0 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statsig/client-core",
3
- "version": "0.0.1-beta.9",
3
+ "version": "1.0.1",
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,6 @@ declare global {
8
13
  __STATSIG__: StatsigGlobal | undefined;
9
14
  }
10
15
  }
16
+ export declare const _getStatsigGlobal: () => StatsigGlobal;
17
+ export declare const _getStatsigGlobalFlag: (flag: string) => unknown;
18
+ export declare const _getInstance: (sdkKey: string) => StatsigClientInterface | undefined;
@@ -1,14 +1,31 @@
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._getInstance = exports._getStatsigGlobalFlag = exports._getStatsigGlobal = void 0;
6
+ const _getStatsigGlobal = () => {
7
+ return __STATSIG__ ? __STATSIG__ : statsigGlobal;
8
+ };
9
+ exports._getStatsigGlobal = _getStatsigGlobal;
10
+ const _getStatsigGlobalFlag = (flag) => {
11
+ return (0, exports._getStatsigGlobal)()[flag];
12
+ };
13
+ exports._getStatsigGlobalFlag = _getStatsigGlobalFlag;
14
+ const _getInstance = (sdkKey) => {
15
+ const gbl = (0, exports._getStatsigGlobal)();
16
+ if (!sdkKey) {
17
+ return gbl.lastInstance;
18
+ }
19
+ return gbl.instances && gbl.instances[sdkKey];
20
+ };
21
+ exports._getInstance = _getInstance;
22
+ const GLOBAL_KEY = '__STATSIG__';
23
+ const _window = typeof window !== 'undefined' ? window : {};
24
+ const _global = typeof global !== 'undefined' ? global : {};
25
+ const _globalThis = typeof globalThis !== 'undefined' ? globalThis : {};
26
+ 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 : {
27
+ instance: exports._getInstance,
28
+ };
29
+ _window[GLOBAL_KEY] = statsigGlobal;
30
+ _global[GLOBAL_KEY] = statsigGlobal;
31
+ _globalThis[GLOBAL_KEY] = statsigGlobal;
@@ -0,0 +1,4 @@
1
+ import { StatsigUser } from './StatsigUser';
2
+ export type CustomCacheKeyGenerator = (sdkKey: string, user: StatsigUser) => string;
3
+ export declare function _getUserStorageKey(sdkKey: string, user: StatsigUser, customKeyGenerator?: CustomCacheKeyGenerator): string;
4
+ export declare function _getStorageKey(sdkKey: string, user?: StatsigUser, customKeyGenerator?: CustomCacheKeyGenerator): string;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._getStorageKey = exports._getUserStorageKey = void 0;
4
+ const Hashing_1 = require("./Hashing");
5
+ function _getUserStorageKey(sdkKey, user, customKeyGenerator) {
6
+ var _a;
7
+ if (customKeyGenerator) {
8
+ return customKeyGenerator(sdkKey, user);
9
+ }
10
+ const cids = user && user.customIDs ? user.customIDs : {};
11
+ const parts = [
12
+ `uid:${(_a = user === null || user === void 0 ? void 0 : user.userID) !== null && _a !== void 0 ? _a : ''}`,
13
+ `cids:${Object.keys(cids)
14
+ .sort((leftKey, rightKey) => leftKey.localeCompare(rightKey))
15
+ .map((key) => `${key}-${cids[key]}`)
16
+ .join(',')}`,
17
+ `k:${sdkKey}`,
18
+ ];
19
+ return (0, Hashing_1._DJB2)(parts.join('|'));
20
+ }
21
+ exports._getUserStorageKey = _getUserStorageKey;
22
+ function _getStorageKey(sdkKey, user, customKeyGenerator) {
23
+ if (user) {
24
+ return _getUserStorageKey(sdkKey, user, customKeyGenerator);
25
+ }
26
+ return (0, Hashing_1._DJB2)(`k:${sdkKey}`);
27
+ }
28
+ exports._getStorageKey = _getStorageKey;
@@ -1,30 +1,64 @@
1
- import { EvaluationOptions } from './StatsigClientBase';
1
+ import { DownloadConfigSpecsResponse } from './DownloadConfigSpecsResponse';
2
+ import { ErrorBoundary } from './ErrorBoundary';
3
+ import { DynamicConfigEvaluationOptions, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, LayerEvaluationOptions } from './EvaluationOptions';
4
+ import { InitializeResponseWithUpdates } from './InitializeResponse';
5
+ import { StatsigSession } from './SessionID';
2
6
  import { StatsigClientEventEmitterInterface } from './StatsigClientEventEmitter';
7
+ import { EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
3
8
  import { StatsigEvent } from './StatsigEvent';
9
+ import { AnyStatsigOptions, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
4
10
  import { DynamicConfig, Experiment, FeatureGate, Layer } from './StatsigTypes';
5
11
  import { StatsigUser } from './StatsigUser';
12
+ import { Flatten } from './UtitlityTypes';
6
13
  export interface StatsigClientCommonInterface extends StatsigClientEventEmitterInterface {
7
14
  initializeSync(): void;
8
15
  initializeAsync(): Promise<void>;
9
16
  shutdown(): Promise<void>;
17
+ flush(): Promise<void>;
18
+ updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
10
19
  }
20
+ export type CommonContext = {
21
+ sdkKey: string;
22
+ options: AnyStatsigOptions;
23
+ errorBoundary: ErrorBoundary;
24
+ };
25
+ export type AsyncCommonContext = {
26
+ session: StatsigSession;
27
+ stableID: string;
28
+ };
29
+ export type OnDeviceEvaluationsContext = CommonContext & {
30
+ values: DownloadConfigSpecsResponse | null;
31
+ };
32
+ export type OnDeviceEvaluationsAsyncContext = OnDeviceEvaluationsContext & AsyncCommonContext;
11
33
  export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterface {
12
- checkGate(name: string, user: StatsigUser, options: EvaluationOptions): boolean;
13
- getFeatureGate(name: string, user: StatsigUser, options: EvaluationOptions): FeatureGate;
14
- getDynamicConfig(name: string, user: StatsigUser, options: EvaluationOptions): DynamicConfig;
15
- getExperiment(name: string, user: StatsigUser, options: EvaluationOptions): Experiment;
16
- getLayer(name: string, user: StatsigUser, options: EvaluationOptions): Layer;
34
+ readonly dataAdapter: SpecsDataAdapter;
35
+ getAsyncContext(): Promise<OnDeviceEvaluationsAsyncContext>;
36
+ getContext(): OnDeviceEvaluationsContext;
37
+ checkGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): boolean;
38
+ getFeatureGate(name: string, user: StatsigUser, options?: FeatureGateEvaluationOptions): FeatureGate;
39
+ getDynamicConfig(name: string, user: StatsigUser, options?: DynamicConfigEvaluationOptions): DynamicConfig;
40
+ getExperiment(name: string, user: StatsigUser, options?: ExperimentEvaluationOptions): Experiment;
41
+ getLayer(name: string, user: StatsigUser, options?: LayerEvaluationOptions): Layer;
17
42
  logEvent(event: StatsigEvent, user: StatsigUser): void;
43
+ logEvent(eventName: string, user: StatsigUser, value?: string | number, metadata?: Record<string, string>): void;
18
44
  }
45
+ export type PrecomputedEvaluationsContext = Flatten<CommonContext & {
46
+ values: InitializeResponseWithUpdates | null;
47
+ user: StatsigUser;
48
+ }>;
49
+ export type PrecomputedEvaluationsAsyncContext = Flatten<AsyncCommonContext & PrecomputedEvaluationsContext>;
19
50
  export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
20
- getCurrentUser(): StatsigUser;
51
+ readonly dataAdapter: EvaluationsDataAdapter;
52
+ getAsyncContext(): Promise<PrecomputedEvaluationsAsyncContext>;
53
+ getContext(): PrecomputedEvaluationsContext;
21
54
  updateUserSync(user: StatsigUser): void;
22
55
  updateUserAsync(user: StatsigUser): Promise<void>;
23
- checkGate(name: string, options: EvaluationOptions): boolean;
24
- getFeatureGate(name: string, options: EvaluationOptions): FeatureGate;
25
- getDynamicConfig(name: string, options: EvaluationOptions): DynamicConfig;
26
- getExperiment(name: string, options: EvaluationOptions): Experiment;
27
- getLayer(name: string, options: EvaluationOptions): Layer;
56
+ checkGate(name: string, options?: FeatureGateEvaluationOptions): boolean;
57
+ getFeatureGate(name: string, options?: FeatureGateEvaluationOptions): FeatureGate;
58
+ getDynamicConfig(name: string, options?: DynamicConfigEvaluationOptions): DynamicConfig;
59
+ getExperiment(name: string, options?: ExperimentEvaluationOptions): Experiment;
60
+ getLayer(name: string, options?: LayerEvaluationOptions): Layer;
28
61
  logEvent(event: StatsigEvent): void;
62
+ logEvent(eventName: string, value?: string | number, metadata?: Record<string, string>): void;
29
63
  }
30
64
  export type StatsigClientInterface = OnDeviceEvaluationsInterface | PrecomputedEvaluationsInterface;
@@ -0,0 +1,31 @@
1
+ import { DataAdapterAsyncOptions, DataAdapterResult } from './StatsigDataAdapter';
2
+ import { AnyStatsigOptions } from './StatsigOptionsCommon';
3
+ import { StatsigUser } from './StatsigUser';
4
+ export declare abstract class DataAdapterCore {
5
+ private _adapterName;
6
+ protected _cacheSuffix: string;
7
+ protected _options: AnyStatsigOptions | null;
8
+ private _sdkKey;
9
+ private _inMemoryCache;
10
+ private _lastModifiedStoreKey;
11
+ protected constructor(_adapterName: string, _cacheSuffix: string);
12
+ attach(sdkKey: string, options: AnyStatsigOptions | null): void;
13
+ getDataSync(user?: StatsigUser | undefined): DataAdapterResult | null;
14
+ setData(data: string, user?: StatsigUser): void;
15
+ /**
16
+ * (Internal Use Only) - Used by \@statsig/react-native-bindings to prime the cache from AsyncStorage
17
+ *
18
+ * @param {Record<string, DataAdapterResult>} cache The values to merge into _inMemoryCache
19
+ */
20
+ __primeInMemoryCache(cache: Record<string, DataAdapterResult>): void;
21
+ protected _getDataAsyncImpl(current: DataAdapterResult | null, user?: StatsigUser, options?: DataAdapterAsyncOptions): Promise<DataAdapterResult | null>;
22
+ protected _prefetchDataImpl(user?: StatsigUser, options?: DataAdapterAsyncOptions): Promise<void>;
23
+ protected abstract _fetchFromNetwork(current: string | null, user?: StatsigUser, options?: DataAdapterAsyncOptions): Promise<string | null>;
24
+ protected abstract _getCacheKey(user?: StatsigUser): string;
25
+ protected abstract _isCachedResultValidFor204(result: DataAdapterResult, user: StatsigUser | undefined): boolean;
26
+ private _fetchAndPrepFromNetwork;
27
+ protected _getSdkKey(): string;
28
+ private _loadFromCache;
29
+ private _writeToCache;
30
+ private _runLocalStorageCacheEviction;
31
+ }
@@ -0,0 +1,196 @@
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 Log_1 = require("./Log");
14
+ const StableID_1 = require("./StableID");
15
+ const StatsigUser_1 = require("./StatsigUser");
16
+ const StorageProvider_1 = require("./StorageProvider");
17
+ const TypedJsonParse_1 = require("./TypedJsonParse");
18
+ const CACHE_LIMIT = 10;
19
+ class DataAdapterCore {
20
+ constructor(_adapterName, _cacheSuffix) {
21
+ this._adapterName = _adapterName;
22
+ this._cacheSuffix = _cacheSuffix;
23
+ this._options = null;
24
+ this._sdkKey = null;
25
+ this._lastModifiedStoreKey = `statsig.last_modified_time.${_cacheSuffix}`;
26
+ this._inMemoryCache = new InMemoryCache();
27
+ }
28
+ attach(sdkKey, options) {
29
+ this._sdkKey = sdkKey;
30
+ this._options = options;
31
+ }
32
+ getDataSync(user) {
33
+ const cacheKey = this._getCacheKey(user);
34
+ const inMem = this._inMemoryCache.get(cacheKey, user);
35
+ if (inMem) {
36
+ return inMem;
37
+ }
38
+ const cache = this._loadFromCache(cacheKey);
39
+ if (cache) {
40
+ this._inMemoryCache.add(cacheKey, cache);
41
+ return this._inMemoryCache.get(cacheKey, user);
42
+ }
43
+ return null;
44
+ }
45
+ setData(data, user) {
46
+ var _a;
47
+ const normalized = user && (0, StatsigUser_1._normalizeUser)(user, (_a = this._options) === null || _a === void 0 ? void 0 : _a.environment);
48
+ const cacheKey = this._getCacheKey(normalized);
49
+ this._inMemoryCache.add(cacheKey, _makeDataAdapterResult('Bootstrap', data, null, normalized));
50
+ }
51
+ /**
52
+ * (Internal Use Only) - Used by \@statsig/react-native-bindings to prime the cache from AsyncStorage
53
+ *
54
+ * @param {Record<string, DataAdapterResult>} cache The values to merge into _inMemoryCache
55
+ */
56
+ __primeInMemoryCache(cache) {
57
+ this._inMemoryCache.merge(cache);
58
+ }
59
+ _getDataAsyncImpl(current, user, options) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ const cache = current !== null && current !== void 0 ? current : this.getDataSync(user);
62
+ const ops = [this._fetchAndPrepFromNetwork(cache, user, options)];
63
+ if (options === null || options === void 0 ? void 0 : options.timeoutMs) {
64
+ ops.push(new Promise((r) => setTimeout(r, options.timeoutMs)).then(() => {
65
+ Log_1.Log.debug('Fetching latest value timed out');
66
+ return null;
67
+ }));
68
+ }
69
+ return yield Promise.race(ops);
70
+ });
71
+ }
72
+ _prefetchDataImpl(user, options) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const cacheKey = this._getCacheKey(user);
75
+ const result = yield this._getDataAsyncImpl(null, user, options);
76
+ if (result) {
77
+ this._inMemoryCache.add(cacheKey, Object.assign(Object.assign({}, result), { source: 'Prefetch' }));
78
+ }
79
+ });
80
+ }
81
+ _fetchAndPrepFromNetwork(cachedResult, user, options) {
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ let cachedData = null;
84
+ if (cachedResult && this._isCachedResultValidFor204(cachedResult, user)) {
85
+ cachedData = cachedResult.data;
86
+ }
87
+ const latest = yield this._fetchFromNetwork(cachedData, user, options);
88
+ if (!latest) {
89
+ Log_1.Log.debug('No response returned for latest value');
90
+ return null;
91
+ }
92
+ const response = (0, TypedJsonParse_1._typedJsonParse)(latest, 'has_updates', 'Response');
93
+ const sdkKey = this._getSdkKey();
94
+ const stableID = yield StableID_1.StableID.get(sdkKey);
95
+ let result = null;
96
+ if ((response === null || response === void 0 ? void 0 : response.has_updates) === true) {
97
+ result = _makeDataAdapterResult('Network', latest, stableID, user);
98
+ }
99
+ else if (cachedData && (response === null || response === void 0 ? void 0 : response.has_updates) === false) {
100
+ result = _makeDataAdapterResult('NetworkNotModified', cachedData, stableID, user);
101
+ }
102
+ else {
103
+ return null;
104
+ }
105
+ const cacheKey = this._getCacheKey(user);
106
+ this._inMemoryCache.add(cacheKey, result);
107
+ yield this._writeToCache(cacheKey, result);
108
+ return result;
109
+ });
110
+ }
111
+ _getSdkKey() {
112
+ if (this._sdkKey != null) {
113
+ return this._sdkKey;
114
+ }
115
+ Log_1.Log.error(`${this._adapterName} is not attached to a Client`);
116
+ return '';
117
+ }
118
+ _loadFromCache(cacheKey) {
119
+ var _a;
120
+ const cache = (_a = StorageProvider_1.Storage._getItemSync) === null || _a === void 0 ? void 0 : _a.call(StorageProvider_1.Storage, cacheKey);
121
+ if (cache == null) {
122
+ return null;
123
+ }
124
+ const result = (0, TypedJsonParse_1._typedJsonParse)(cache, 'source', 'Cached Result');
125
+ return result ? Object.assign(Object.assign({}, result), { source: 'Cache' }) : null;
126
+ }
127
+ _writeToCache(cacheKey, result) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ yield StorageProvider_1.Storage._setItem(cacheKey, JSON.stringify(result));
130
+ yield this._runLocalStorageCacheEviction(cacheKey);
131
+ });
132
+ }
133
+ _runLocalStorageCacheEviction(cacheKey) {
134
+ var _a;
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ const lastModifiedTimeMap = (_a = (yield (0, StorageProvider_1._getObjectFromStorage)(this._lastModifiedStoreKey))) !== null && _a !== void 0 ? _a : {};
137
+ lastModifiedTimeMap[cacheKey] = Date.now();
138
+ const evictable = _getEvictableKey(lastModifiedTimeMap, CACHE_LIMIT);
139
+ if (evictable) {
140
+ delete lastModifiedTimeMap[evictable];
141
+ yield StorageProvider_1.Storage._removeItem(evictable);
142
+ }
143
+ yield (0, StorageProvider_1._setObjectInStorage)(this._lastModifiedStoreKey, lastModifiedTimeMap);
144
+ });
145
+ }
146
+ }
147
+ exports.DataAdapterCore = DataAdapterCore;
148
+ function _makeDataAdapterResult(source, data, stableID, user) {
149
+ return {
150
+ source,
151
+ data,
152
+ receivedAt: Date.now(),
153
+ stableID,
154
+ fullUserHash: (0, StatsigUser_1._getFullUserHash)(user),
155
+ };
156
+ }
157
+ class InMemoryCache {
158
+ constructor() {
159
+ this._data = {};
160
+ }
161
+ get(cacheKey, user) {
162
+ var _a;
163
+ const result = this._data[cacheKey];
164
+ const cached = result === null || result === void 0 ? void 0 : result.stableID;
165
+ const provided = (_a = user === null || user === void 0 ? void 0 : user.customIDs) === null || _a === void 0 ? void 0 : _a.stableID;
166
+ if (provided && cached && provided !== cached) {
167
+ Log_1.Log.warn("'StatsigUser.customIDs.stableID' mismatch");
168
+ return null;
169
+ }
170
+ return result;
171
+ }
172
+ add(cacheKey, value) {
173
+ const oldest = _getEvictableKey(this._data, CACHE_LIMIT - 1);
174
+ if (oldest) {
175
+ delete this._data[oldest];
176
+ }
177
+ this._data[cacheKey] = value;
178
+ }
179
+ merge(values) {
180
+ this._data = Object.assign(Object.assign({}, this._data), values);
181
+ }
182
+ }
183
+ function _getEvictableKey(data, limit) {
184
+ const keys = Object.keys(data);
185
+ if (keys.length <= limit) {
186
+ return null;
187
+ }
188
+ return keys.reduce((prevKey, currKey) => {
189
+ const prev = data[prevKey];
190
+ const current = data[currKey];
191
+ if (typeof prev === 'object' && typeof current === 'object') {
192
+ return current.receivedAt < prev.receivedAt ? currKey : prevKey;
193
+ }
194
+ return current < prev ? currKey : prevKey;
195
+ });
196
+ }
@@ -1,5 +1,3 @@
1
- export declare function captureDiagnostics(func: string, task: () => unknown): unknown;
2
1
  export declare abstract class Diagnostics {
3
- static mark(tag: string, metadata?: Record<string, unknown>): void;
4
- static flush(): void;
2
+ static mark(): void;
5
3
  }
@@ -1,54 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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 = [];
7
- 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"));
13
- };
14
- if (result && result instanceof Promise) {
15
- return result.finally(function () { return markEnd(); });
3
+ exports.Diagnostics = void 0;
4
+ class Diagnostics {
5
+ static mark() {
6
+ //
16
7
  }
17
- else {
18
- markEnd();
19
- }
20
- return result;
21
8
  }
22
- exports.captureDiagnostics = captureDiagnostics;
23
- var Diagnostics = /** @class */ (function () {
24
- function Diagnostics() {
25
- }
26
- Diagnostics.mark = function (tag, metadata) {
27
- if (!SUPPORTS_PERFORMANCE_API) {
28
- return;
29
- }
30
- var marker = performance.mark(tag, { detail: metadata });
31
- markers.push(marker);
32
- };
33
- Diagnostics.flush = function () {
34
- var resources = performance
35
- .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,
42
- };
43
- // TODO: Send as log to Statsig
44
- Log_1.Log.debug('Diagnostics', payload, JSON.stringify(payload));
45
- markers = [];
46
- };
47
- return Diagnostics;
48
- }());
49
9
  exports.Diagnostics = Diagnostics;
50
- function maybeFlush(tag) {
51
- if (tag.startsWith('initialize:')) {
52
- Diagnostics.flush();
53
- }
54
- }
@@ -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 });
@@ -1,9 +1,14 @@
1
1
  import { StatsigClientEmitEventFunc } from './StatsigClientBase';
2
+ import { AnyStatsigOptions } from './StatsigOptionsCommon';
2
3
  export declare const EXCEPTION_ENDPOINT = "https://statsigapi.net/v1/sdk_exception";
3
4
  export declare class ErrorBoundary {
4
5
  private _sdkKey;
6
+ private _options;
7
+ private _emitter?;
5
8
  private _seen;
6
- constructor(_sdkKey: string);
7
- capture(tag: string, task: () => unknown, emitter?: StatsigClientEmitEventFunc): unknown;
9
+ constructor(_sdkKey: string, _options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
10
+ wrap(instance: unknown): void;
11
+ logError(tag: string, error: unknown): void;
12
+ private _capture;
8
13
  private _onError;
9
14
  }