@statsig/client-core 3.3.0-beta.3 → 3.3.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": "3.3.0-beta.3",
3
+ "version": "3.3.0",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -2,7 +2,7 @@ import { StatsigClientInterface } from './ClientInterfaces';
2
2
  export type StatsigGlobal = {
3
3
  [key: string]: unknown;
4
4
  instances?: Record<string, StatsigClientInterface>;
5
- lastInstance?: StatsigClientInterface;
5
+ firstInstance?: StatsigClientInterface;
6
6
  acInstances?: Record<string, unknown>;
7
7
  srInstances?: Record<string, unknown>;
8
8
  instance: (sdkKey?: string) => StatsigClientInterface | undefined;
@@ -3,6 +3,7 @@
3
3
  var _a, _b, _c;
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports._getInstance = exports._getStatsigGlobalFlag = exports._getStatsigGlobal = void 0;
6
+ const Log_1 = require("./Log");
6
7
  const _getStatsigGlobal = () => {
7
8
  return __STATSIG__ ? __STATSIG__ : statsigGlobal;
8
9
  };
@@ -14,7 +15,10 @@ exports._getStatsigGlobalFlag = _getStatsigGlobalFlag;
14
15
  const _getInstance = (sdkKey) => {
15
16
  const gbl = (0, exports._getStatsigGlobal)();
16
17
  if (!sdkKey) {
17
- return gbl.lastInstance;
18
+ if (gbl.instances && Object.keys(gbl.instances).length > 1) {
19
+ Log_1.Log.warn('Call made to Statsig global instance without an SDK key but there is more than one client instance. If you are using mulitple clients, please specify the SDK key.');
20
+ }
21
+ return gbl.firstInstance;
18
22
  }
19
23
  return gbl.instances && gbl.instances[sdkKey];
20
24
  };
@@ -1,5 +1,4 @@
1
1
  import './$_StatsigGlobal';
2
- import { ErrorBoundary } from './ErrorBoundary';
3
2
  import { NetworkPriority } from './NetworkConfig';
4
3
  import { StatsigClientEmitEventFunc } from './StatsigClientBase';
5
4
  import { AnyStatsigOptions } from './StatsigOptionsCommon';
@@ -29,18 +28,14 @@ export declare class NetworkCore {
29
28
  private readonly _timeout;
30
29
  private readonly _netConfig;
31
30
  private readonly _options;
32
- private readonly _fallbackResolver;
33
- private _errorBoundary;
34
31
  constructor(options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
35
- setErrorBoundary(errorBoundary: ErrorBoundary): void;
36
- isBeaconSupported(): boolean;
37
- beacon(args: BeaconRequestArgs): Promise<boolean>;
38
32
  post(args: RequestArgsWithData): Promise<NetworkResponse | null>;
39
33
  get(args: RequestArgs): Promise<NetworkResponse | null>;
34
+ isBeaconSupported(): boolean;
35
+ beacon(args: BeaconRequestArgs): Promise<boolean>;
40
36
  private _sendRequest;
41
37
  private _getPopulatedURL;
42
38
  private _getPopulatedBody;
43
39
  private _attemptToEncodeString;
44
- private _getInternalRequestArgs;
45
40
  }
46
41
  export {};
@@ -15,7 +15,6 @@ const __StatsigGlobal_1 = require("./$_StatsigGlobal");
15
15
  const Diagnostics_1 = require("./Diagnostics");
16
16
  const Log_1 = require("./Log");
17
17
  const NetworkConfig_1 = require("./NetworkConfig");
18
- const NetworkFallbackResolver_1 = require("./NetworkFallbackResolver");
19
18
  const SDKType_1 = require("./SDKType");
20
19
  const SafeJs_1 = require("./SafeJs");
21
20
  const SessionID_1 = require("./SessionID");
@@ -31,7 +30,6 @@ class NetworkCore {
31
30
  this._timeout = DEFAULT_TIMEOUT_MS;
32
31
  this._netConfig = {};
33
32
  this._options = {};
34
- this._errorBoundary = null;
35
33
  if (options) {
36
34
  this._options = options;
37
35
  }
@@ -41,13 +39,18 @@ class NetworkCore {
41
39
  if (this._netConfig.networkTimeoutMs) {
42
40
  this._timeout = this._netConfig.networkTimeoutMs;
43
41
  }
44
- this._fallbackResolver = new NetworkFallbackResolver_1.NetworkFallbackResolver(this._options);
45
42
  }
46
- setErrorBoundary(errorBoundary) {
47
- this._errorBoundary = errorBoundary;
48
- this._errorBoundary.wrap(this);
49
- this._errorBoundary.wrap(this._fallbackResolver);
50
- this._fallbackResolver.setErrorBoundary(errorBoundary);
43
+ post(args) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ let body = yield this._getPopulatedBody(args);
46
+ if (args.isStatsigEncodable) {
47
+ body = this._attemptToEncodeString(args, body);
48
+ }
49
+ return this._sendRequest(Object.assign({ method: 'POST', body }, args));
50
+ });
51
+ }
52
+ get(args) {
53
+ return this._sendRequest(Object.assign({ method: 'GET' }, args));
51
54
  }
52
55
  isBeaconSupported() {
53
56
  return (typeof navigator !== 'undefined' &&
@@ -58,27 +61,12 @@ class NetworkCore {
58
61
  if (!_ensureValidSdkKey(args)) {
59
62
  return false;
60
63
  }
61
- const argsInternal = this._getInternalRequestArgs('POST', args);
62
- const body = yield this._getPopulatedBody(argsInternal, args.data);
63
- const url = yield this._getPopulatedURL(argsInternal);
64
+ const body = yield this._getPopulatedBody(args);
65
+ const url = yield this._getPopulatedURL(args);
64
66
  const nav = navigator;
65
67
  return nav.sendBeacon.bind(nav)(url, body);
66
68
  });
67
69
  }
68
- post(args) {
69
- return __awaiter(this, void 0, void 0, function* () {
70
- const argsInternal = this._getInternalRequestArgs('POST', args);
71
- argsInternal.body = yield this._getPopulatedBody(argsInternal, args.data);
72
- if (args.isStatsigEncodable) {
73
- argsInternal.body = this._attemptToEncodeString(argsInternal, argsInternal.body);
74
- }
75
- return this._sendRequest(argsInternal);
76
- });
77
- }
78
- get(args) {
79
- const argsInternal = this._getInternalRequestArgs('GET', args);
80
- return this._sendRequest(argsInternal);
81
- }
82
70
  _sendRequest(args) {
83
71
  var _a, _b, _c;
84
72
  return __awaiter(this, void 0, void 0, function* () {
@@ -90,11 +78,9 @@ class NetworkCore {
90
78
  }
91
79
  const { method, body, retries, attempt } = args;
92
80
  const currentAttempt = attempt !== null && attempt !== void 0 ? attempt : 1;
93
- const abortController = typeof AbortController !== 'undefined' ? new AbortController() : null;
94
- const timeoutHandle = setTimeout(() => {
95
- abortController === null || abortController === void 0 ? void 0 : abortController.abort(`Timeout of ${this._timeout}ms expired.`);
96
- }, this._timeout);
97
- const populatedUrl = yield this._getPopulatedURL(args);
81
+ const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
82
+ const handle = setTimeout(() => controller === null || controller === void 0 ? void 0 : controller.abort(`Timeout of ${this._timeout}ms expired.`), this._timeout);
83
+ const url = yield this._getPopulatedURL(args);
98
84
  let response = null;
99
85
  const keepalive = (0, VisibilityObserving_1._isUnloading)();
100
86
  try {
@@ -102,35 +88,37 @@ class NetworkCore {
102
88
  method,
103
89
  body,
104
90
  headers: Object.assign({}, args.headers),
105
- signal: abortController === null || abortController === void 0 ? void 0 : abortController.signal,
91
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
106
92
  priority: args.priority,
107
93
  keepalive,
108
94
  };
109
- _tryMarkInitStart(args, currentAttempt);
95
+ if (args.isInitialize) {
96
+ Diagnostics_1.Diagnostics._markInitNetworkReqStart(args.sdkKey, {
97
+ attempt: currentAttempt,
98
+ });
99
+ }
110
100
  const func = (_a = this._netConfig.networkOverrideFunc) !== null && _a !== void 0 ? _a : fetch;
111
- response = yield func(populatedUrl, config);
112
- clearTimeout(timeoutHandle);
101
+ response = yield func(url, config);
102
+ clearTimeout(handle);
113
103
  if (!response.ok) {
114
104
  const text = yield response.text().catch(() => 'No Text');
115
- const err = new Error(`NetworkError: ${populatedUrl} ${text}`);
105
+ const err = new Error(`NetworkError: ${url} ${text}`);
116
106
  err.name = 'NetworkError';
117
107
  throw err;
118
108
  }
119
109
  const text = yield response.text();
120
- _tryMarkInitEnd(args, response, currentAttempt, text);
121
- this._fallbackResolver.tryBumpExpiryTime(args.sdkKey, populatedUrl);
110
+ if (args.isInitialize) {
111
+ Diagnostics_1.Diagnostics._markInitNetworkReqEnd(args.sdkKey, Diagnostics_1.Diagnostics._getDiagnosticsData(response, currentAttempt, text));
112
+ }
122
113
  return {
123
114
  body: text,
124
115
  code: response.status,
125
116
  };
126
117
  }
127
118
  catch (error) {
128
- const errorMessage = _getErrorMessage(abortController, error);
129
- const timedOut = _didTimeout(abortController);
130
- _tryMarkInitEnd(args, response, currentAttempt, '', error);
131
- const fallbackUpdated = yield this._fallbackResolver.tryFetchUpdatedFallbackInfo(args.sdkKey, populatedUrl, errorMessage, timedOut);
132
- if (fallbackUpdated) {
133
- args.fallbackUrl = this._fallbackResolver.getFallbackUrl(args.sdkKey, args.url);
119
+ const errorMessage = _getErrorMessage(controller, error);
120
+ if (args.isInitialize) {
121
+ Diagnostics_1.Diagnostics._markInitNetworkReqEnd(args.sdkKey, Diagnostics_1.Diagnostics._getDiagnosticsData(response, currentAttempt, '', error));
134
122
  }
135
123
  if (!retries ||
136
124
  currentAttempt > retries ||
@@ -141,42 +129,40 @@ class NetworkCore {
141
129
  tag: StatsigClientEventEmitter_1.ErrorTag.NetworkError,
142
130
  requestArgs: args,
143
131
  });
144
- Log_1.Log.error(`A networking error occured during ${method} request to ${populatedUrl}.`, errorMessage, error);
132
+ Log_1.Log.error(`A networking error occured during ${method} request to ${url}.`, errorMessage, error);
145
133
  return null;
146
134
  }
147
- return this._sendRequest(Object.assign(Object.assign({}, args), { retries, attempt: currentAttempt + 1 }));
135
+ return this._sendRequest(Object.assign(Object.assign({}, args), { retries: retries, attempt: currentAttempt + 1 }));
148
136
  }
149
137
  });
150
138
  }
151
139
  _getPopulatedURL(args) {
152
- var _a;
153
140
  return __awaiter(this, void 0, void 0, function* () {
154
- const url = (_a = args.fallbackUrl) !== null && _a !== void 0 ? _a : args.url;
155
141
  const params = Object.assign({ [NetworkConfig_1.NetworkParam.SdkKey]: args.sdkKey, [NetworkConfig_1.NetworkParam.SdkType]: SDKType_1.SDKType._get(args.sdkKey), [NetworkConfig_1.NetworkParam.SdkVersion]: StatsigMetadata_1.SDK_VERSION, [NetworkConfig_1.NetworkParam.Time]: String(Date.now()), [NetworkConfig_1.NetworkParam.SessionID]: SessionID_1.SessionID.get(args.sdkKey) }, args.params);
156
142
  const query = Object.keys(params)
157
143
  .map((key) => {
158
144
  return `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`;
159
145
  })
160
146
  .join('&');
161
- return `${url}${query ? `?${query}` : ''}`;
147
+ return `${args.url}${query ? `?${query}` : ''}`;
162
148
  });
163
149
  }
164
- _getPopulatedBody(args, data) {
150
+ _getPopulatedBody(args) {
165
151
  return __awaiter(this, void 0, void 0, function* () {
166
- const { sdkKey, fallbackUrl } = args;
152
+ const { data, sdkKey } = args;
167
153
  const stableID = StableID_1.StableID.get(sdkKey);
168
154
  const sessionID = SessionID_1.SessionID.get(sdkKey);
169
155
  const sdkType = SDKType_1.SDKType._get(sdkKey);
170
156
  return JSON.stringify(Object.assign(Object.assign({}, data), { statsigMetadata: Object.assign(Object.assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID,
171
157
  sessionID,
172
- sdkType,
173
- fallbackUrl }) }));
158
+ sdkType }) }));
174
159
  });
175
160
  }
176
161
  _attemptToEncodeString(args, input) {
177
162
  var _a, _b;
178
163
  const win = (0, SafeJs_1._getWindowSafe)();
179
- if (this._options.disableStatsigEncoding ||
164
+ if (!args.isStatsigEncodable ||
165
+ this._options.disableStatsigEncoding ||
180
166
  (0, __StatsigGlobal_1._getStatsigGlobalFlag)('no-encode') != null ||
181
167
  !(win === null || win === void 0 ? void 0 : win.btoa)) {
182
168
  return input;
@@ -191,11 +177,6 @@ class NetworkCore {
191
177
  return input;
192
178
  }
193
179
  }
194
- _getInternalRequestArgs(method, args) {
195
- const fallbackUrl = this._fallbackResolver.getFallbackUrl(args.sdkKey, args.url);
196
- return Object.assign(Object.assign({}, args), { method,
197
- fallbackUrl });
198
- }
199
180
  }
200
181
  exports.NetworkCore = NetworkCore;
201
182
  const _ensureValidSdkKey = (args) => {
@@ -218,23 +199,3 @@ function _getErrorMessage(controller, error) {
218
199
  }
219
200
  return 'Unknown Error';
220
201
  }
221
- function _didTimeout(controller) {
222
- const timeout = (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) &&
223
- typeof controller.signal.reason === 'string' &&
224
- controller.signal.reason.includes('Timeout');
225
- return timeout || false;
226
- }
227
- function _tryMarkInitStart(args, attempt) {
228
- if (!args.isInitialize) {
229
- return;
230
- }
231
- Diagnostics_1.Diagnostics._markInitNetworkReqStart(args.sdkKey, {
232
- attempt,
233
- });
234
- }
235
- function _tryMarkInitEnd(args, response, attempt, body, err) {
236
- if (!args.isInitialize) {
237
- return;
238
- }
239
- Diagnostics_1.Diagnostics._markInitNetworkReqEnd(args.sdkKey, Diagnostics_1.Diagnostics._getDiagnosticsData(response, attempt, body, err));
240
- }
@@ -36,9 +36,9 @@ class StatsigClientBase {
36
36
  this._logger = new EventLogger_1.EventLogger(sdkKey, emitter, network, options);
37
37
  this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(sdkKey, options, emitter);
38
38
  this._errorBoundary.wrap(this);
39
+ this._errorBoundary.wrap(network);
39
40
  this._errorBoundary.wrap(adapter);
40
41
  this._errorBoundary.wrap(this._logger);
41
- network.setErrorBoundary(this._errorBoundary);
42
42
  this.dataAdapter = adapter;
43
43
  this.dataAdapter.attach(sdkKey, options);
44
44
  this.storageProvider = StorageProvider_1.Storage;
@@ -157,7 +157,9 @@ function _assignGlobalInstance(sdkKey, client) {
157
157
  Log_1.Log.warn('Creating multiple Statsig clients with the same SDK key can lead to unexpected behavior. Multi-instance support requires different SDK keys.');
158
158
  }
159
159
  instances[sdkKey] = inst;
160
- statsigGlobal.lastInstance = inst;
160
+ if (!statsigGlobal.firstInstance) {
161
+ statsigGlobal.firstInstance = inst;
162
+ }
161
163
  statsigGlobal.instances = instances;
162
164
  __STATSIG__ = statsigGlobal;
163
165
  }
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "3.3.0-beta.3";
1
+ export declare const SDK_VERSION = "3.3.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 = '3.3.0-beta.3';
4
+ exports.SDK_VERSION = '3.3.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,20 +0,0 @@
1
- import { ErrorBoundary } from './ErrorBoundary';
2
- import { AnyStatsigOptions } from './StatsigOptionsCommon';
3
- export type FallbackResolverArgs = {
4
- fallbackUrl: string | null;
5
- };
6
- export declare class NetworkFallbackResolver {
7
- private _fallbackInfo;
8
- private _errorBoundary;
9
- private _networkOverrideFunc?;
10
- private _cooldowns;
11
- constructor(options: AnyStatsigOptions);
12
- setErrorBoundary(errorBoundary: ErrorBoundary): void;
13
- tryBumpExpiryTime(sdkKey: string, url: string): void;
14
- getFallbackUrl(sdkKey: string, url: string): string | null;
15
- tryFetchUpdatedFallbackInfo(sdkKey: string, url: string, errorMessage: string | null, timedOut: boolean): Promise<boolean>;
16
- private _updateFallbackInfoWithNewUrl;
17
- private _fetchFallbackUrl;
18
- }
19
- export declare function _isDefaultUrl(url: string): boolean;
20
- export declare function _isDomainFailure(errorMsg: string | null, timedOut: boolean): boolean;
@@ -1,208 +0,0 @@
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._isDomainFailure = exports._isDefaultUrl = exports.NetworkFallbackResolver = void 0;
13
- const DnsTxtQuery_1 = require("./DnsTxtQuery");
14
- const Hashing_1 = require("./Hashing");
15
- const Log_1 = require("./Log");
16
- const NetworkConfig_1 = require("./NetworkConfig");
17
- const StorageProvider_1 = require("./StorageProvider");
18
- const DEFAULT_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
19
- const COOLDOWN_TIME_MS = 4 * 60 * 60 * 1000; // 4 hours
20
- class NetworkFallbackResolver {
21
- constructor(options) {
22
- var _a;
23
- this._fallbackInfo = null;
24
- this._errorBoundary = null;
25
- this._cooldowns = {};
26
- this._networkOverrideFunc = (_a = options.networkConfig) === null || _a === void 0 ? void 0 : _a.networkOverrideFunc;
27
- }
28
- setErrorBoundary(errorBoundary) {
29
- this._errorBoundary = errorBoundary;
30
- }
31
- tryBumpExpiryTime(sdkKey, url) {
32
- var _a;
33
- const domainKey = _getDomainKeyFromEndpoint(url);
34
- if (!domainKey) {
35
- return;
36
- }
37
- const info = (_a = this._fallbackInfo) === null || _a === void 0 ? void 0 : _a[domainKey];
38
- if (!info) {
39
- return;
40
- }
41
- info.expiryTime = Date.now() + DEFAULT_TTL_MS;
42
- _tryWriteFallbackInfoToCache(sdkKey, Object.assign(Object.assign({}, this._fallbackInfo), { [domainKey]: info }));
43
- }
44
- getFallbackUrl(sdkKey, url) {
45
- var _a, _b;
46
- const domainKey = _getDomainKeyFromEndpoint(url);
47
- if (!_isDefaultUrl(url) || !domainKey) {
48
- return null;
49
- }
50
- let info = this._fallbackInfo;
51
- if (info == null) {
52
- info = (_a = _readFallbackInfoFromCache(sdkKey)) !== null && _a !== void 0 ? _a : {};
53
- this._fallbackInfo = info;
54
- }
55
- const entry = info[domainKey];
56
- if (!entry || Date.now() > ((_b = entry.expiryTime) !== null && _b !== void 0 ? _b : 0)) {
57
- delete info[domainKey];
58
- this._fallbackInfo = info;
59
- _tryWriteFallbackInfoToCache(sdkKey, this._fallbackInfo);
60
- return null;
61
- }
62
- const endpoint = _extractEndpointForUrl(url);
63
- if (entry.url) {
64
- return `https://${entry.url}/${endpoint}`;
65
- }
66
- return null;
67
- }
68
- tryFetchUpdatedFallbackInfo(sdkKey, url, errorMessage, timedOut) {
69
- var _a;
70
- return __awaiter(this, void 0, void 0, function* () {
71
- try {
72
- const domainKey = _getDomainKeyFromEndpoint(url);
73
- if (!_isDomainFailure(errorMessage, timedOut) || !domainKey) {
74
- return false;
75
- }
76
- if (this._cooldowns[domainKey] &&
77
- Date.now() < this._cooldowns[domainKey]) {
78
- return false;
79
- }
80
- this._cooldowns[domainKey] = Date.now() + COOLDOWN_TIME_MS;
81
- const newUrl = yield this._fetchFallbackUrl(domainKey);
82
- if (!newUrl) {
83
- return false;
84
- }
85
- this._updateFallbackInfoWithNewUrl(sdkKey, domainKey, newUrl);
86
- return true;
87
- }
88
- catch (error) {
89
- (_a = this._errorBoundary) === null || _a === void 0 ? void 0 : _a.logError('tryFetchUpdatedFallbackInfo', error);
90
- return false;
91
- }
92
- });
93
- }
94
- _updateFallbackInfoWithNewUrl(sdkKey, domainKey, newUrl) {
95
- var _a, _b, _c;
96
- const newFallbackInfo = {
97
- url: newUrl,
98
- expiryTime: Date.now() + DEFAULT_TTL_MS,
99
- previous: [],
100
- };
101
- const previousInfo = (_a = this._fallbackInfo) === null || _a === void 0 ? void 0 : _a[domainKey];
102
- if (previousInfo) {
103
- newFallbackInfo.previous.push(...previousInfo.previous);
104
- }
105
- if (newFallbackInfo.previous.length > 10) {
106
- newFallbackInfo.previous = [];
107
- }
108
- const previousUrl = (_c = (_b = this._fallbackInfo) === null || _b === void 0 ? void 0 : _b[domainKey]) === null || _c === void 0 ? void 0 : _c.url;
109
- if (previousUrl != null) {
110
- newFallbackInfo.previous.push(previousUrl);
111
- }
112
- this._fallbackInfo = Object.assign(Object.assign({}, this._fallbackInfo), { [domainKey]: newFallbackInfo });
113
- _tryWriteFallbackInfoToCache(sdkKey, this._fallbackInfo);
114
- }
115
- _fetchFallbackUrl(domainKey) {
116
- var _a, _b, _c, _d, _e, _f;
117
- return __awaiter(this, void 0, void 0, function* () {
118
- const records = yield (0, DnsTxtQuery_1._fetchTxtRecords)((_a = this._networkOverrideFunc) !== null && _a !== void 0 ? _a : fetch);
119
- if (records.length === 0) {
120
- return null;
121
- }
122
- const seen = new Set((_d = (_c = (_b = this._fallbackInfo) === null || _b === void 0 ? void 0 : _b[domainKey]) === null || _c === void 0 ? void 0 : _c.previous) !== null && _d !== void 0 ? _d : []);
123
- const currentUrl = (_f = (_e = this._fallbackInfo) === null || _e === void 0 ? void 0 : _e[domainKey]) === null || _f === void 0 ? void 0 : _f.url;
124
- let found = null;
125
- for (const record of records) {
126
- const [recordKey, recordUrl] = record.split('=');
127
- if (!recordUrl || recordKey !== domainKey) {
128
- continue;
129
- }
130
- let url = recordUrl;
131
- if (recordUrl.endsWith('/')) {
132
- url = recordUrl.slice(0, -1);
133
- }
134
- if (!seen.has(recordUrl) && url !== currentUrl) {
135
- found = url;
136
- break;
137
- }
138
- }
139
- return found;
140
- });
141
- }
142
- }
143
- exports.NetworkFallbackResolver = NetworkFallbackResolver;
144
- function _isDefaultUrl(url) {
145
- for (const key in NetworkConfig_1.NetworkDefault) {
146
- if (url.startsWith(NetworkConfig_1.NetworkDefault[key])) {
147
- return true;
148
- }
149
- }
150
- return false;
151
- }
152
- exports._isDefaultUrl = _isDefaultUrl;
153
- function _isDomainFailure(errorMsg, timedOut) {
154
- var _a;
155
- const lowerErrorMsg = (_a = errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.toLowerCase()) !== null && _a !== void 0 ? _a : '';
156
- return (timedOut ||
157
- lowerErrorMsg.includes('uncaught exception') ||
158
- lowerErrorMsg.includes('failed to fetch') ||
159
- lowerErrorMsg.includes('networkerror when attempting to fetch resource'));
160
- }
161
- exports._isDomainFailure = _isDomainFailure;
162
- function _getFallbackInfoStorageKey(sdkKey) {
163
- return `statsig.network_fallback.${(0, Hashing_1._DJB2)(sdkKey)}`;
164
- }
165
- function _tryWriteFallbackInfoToCache(sdkKey, info) {
166
- const hashKey = _getFallbackInfoStorageKey(sdkKey);
167
- if (!info || Object.keys(info).length === 0) {
168
- StorageProvider_1.Storage.removeItem(hashKey);
169
- return;
170
- }
171
- StorageProvider_1.Storage.setItem(hashKey, JSON.stringify(info));
172
- }
173
- function _readFallbackInfoFromCache(sdkKey) {
174
- const hashKey = _getFallbackInfoStorageKey(sdkKey);
175
- const data = StorageProvider_1.Storage.getItem(hashKey);
176
- if (!data) {
177
- return null;
178
- }
179
- try {
180
- return JSON.parse(data);
181
- }
182
- catch (_a) {
183
- Log_1.Log.error('Failed to parse FallbackInfo');
184
- return null;
185
- }
186
- }
187
- function _extractEndpointForUrl(urlString) {
188
- try {
189
- const url = new URL(urlString);
190
- const endpoint = url.pathname.substring(1);
191
- return endpoint;
192
- }
193
- catch (error) {
194
- return '';
195
- }
196
- }
197
- function _getDomainKeyFromEndpoint(endpoint) {
198
- if (endpoint.includes('initialize')) {
199
- return 'i';
200
- }
201
- if (endpoint.includes('rgstr')) {
202
- return 'e';
203
- }
204
- if (endpoint.includes('download_config_specs')) {
205
- return 'd';
206
- }
207
- return null;
208
- }