@statsig/client-core 0.0.1-beta.3 → 0.0.1-beta.31

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 +8 -1
  4. package/src/$_StatsigGlobal.js +22 -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 +128 -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 +114 -238
  42. package/src/StatsigClientEventEmitter.d.ts +65 -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
@@ -0,0 +1,18 @@
1
+ import { DynamicConfigEvaluation, GateEvaluation, LayerEvaluation } from './EvaluationTypes';
2
+ type SessionReplayFields = {
3
+ can_record_session?: boolean;
4
+ session_recording_rate?: number;
5
+ };
6
+ export type InitializeResponseWithUpdates = SessionReplayFields & {
7
+ feature_gates: Record<string, GateEvaluation>;
8
+ dynamic_configs: Record<string, DynamicConfigEvaluation>;
9
+ layer_configs: Record<string, LayerEvaluation>;
10
+ time: number;
11
+ has_updates: true;
12
+ hash_used: 'none' | 'sha256' | 'djb2';
13
+ derived_fields?: Record<string, unknown>;
14
+ };
15
+ export type InitializeResponse = InitializeResponseWithUpdates | {
16
+ has_updates: false;
17
+ };
18
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/src/Log.js CHANGED
@@ -14,46 +14,27 @@ var LogLevel;
14
14
  LogLevel[LogLevel["Info"] = 3] = "Info";
15
15
  LogLevel[LogLevel["Debug"] = 4] = "Debug";
16
16
  })(LogLevel || (exports.LogLevel = LogLevel = {}));
17
- var Log = /** @class */ (function () {
18
- function Log() {
19
- }
20
- Log.info = function () {
21
- var args = [];
22
- for (var _i = 0; _i < arguments.length; _i++) {
23
- args[_i] = arguments[_i];
24
- }
17
+ class Log {
18
+ static info(...args) {
25
19
  if (this.level >= LogLevel.Info) {
26
- console.info.apply(console, addTag(args));
27
- }
28
- };
29
- Log.debug = function () {
30
- var args = [];
31
- for (var _i = 0; _i < arguments.length; _i++) {
32
- args[_i] = arguments[_i];
20
+ console.info(...addTag(args));
33
21
  }
22
+ }
23
+ static debug(...args) {
34
24
  if (this.level >= LogLevel.Debug) {
35
- console.debug.apply(console, addTag(args));
36
- }
37
- };
38
- Log.warn = function () {
39
- var args = [];
40
- for (var _i = 0; _i < arguments.length; _i++) {
41
- args[_i] = arguments[_i];
25
+ console.debug(...addTag(args));
42
26
  }
27
+ }
28
+ static warn(...args) {
43
29
  if (this.level >= LogLevel.Warn) {
44
- console.warn.apply(console, addTag(args));
45
- }
46
- };
47
- Log.error = function () {
48
- var args = [];
49
- for (var _i = 0; _i < arguments.length; _i++) {
50
- args[_i] = arguments[_i];
30
+ console.warn(...addTag(args));
51
31
  }
32
+ }
33
+ static error(...args) {
52
34
  if (this.level >= LogLevel.Error) {
53
- console.error.apply(console, addTag(args));
35
+ console.error(...addTag(args));
54
36
  }
55
- };
56
- Log.level = LogLevel.Error;
57
- return Log;
58
- }());
37
+ }
38
+ }
59
39
  exports.Log = Log;
40
+ Log.level = LogLevel.Error;
@@ -1,3 +1,2 @@
1
1
  import { ErrorBoundary } from './ErrorBoundary';
2
- export declare function monitorClass<T extends new (...args: any[]) => any>(errorBoundary: ErrorBoundary, target: T, instance: unknown): void;
3
- export declare function monitorFunction<T>(errorBoundary: ErrorBoundary, tag: string, func: () => T, instance: unknown): T;
2
+ export declare function monitorClass(errorBoundary: ErrorBoundary, instance: object): void;
package/src/Monitoring.js CHANGED
@@ -1,33 +1,74 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.monitorFunction = exports.monitorClass = void 0;
4
- var Diagnostics_1 = require("./Diagnostics");
5
- var StatsigClientBase_1 = require("./StatsigClientBase");
6
- function monitorClass(errorBoundary, target, instance) {
7
- var methods = Object.getOwnPropertyNames(target.prototype);
8
- var obj = instance;
9
- var _loop_1 = function (method) {
10
- if (method === 'constructor' || typeof obj[method] !== 'function') {
11
- return "continue";
12
- }
13
- var original = obj[method];
14
- obj[method] = function () {
15
- var _this = this;
16
- var args = [];
17
- for (var _i = 0; _i < arguments.length; _i++) {
18
- args[_i] = arguments[_i];
19
- }
20
- return monitorFunction(errorBoundary, method, function () { return original.apply(_this, args); }, instance);
21
- };
22
- };
23
- for (var _i = 0, methods_1 = methods; _i < methods_1.length; _i++) {
24
- var method = methods_1[_i];
25
- _loop_1(method);
3
+ exports.monitorClass = void 0;
4
+ const Diagnostics_1 = require("./Diagnostics");
5
+ const StatsigClientBase_1 = require("./StatsigClientBase");
6
+ function monitorClass(errorBoundary, instance) {
7
+ try {
8
+ _monitorClassImpl(errorBoundary, instance);
9
+ }
10
+ catch (error) {
11
+ errorBoundary.logError('monitorClass', error);
26
12
  }
27
13
  }
28
14
  exports.monitorClass = monitorClass;
29
- function monitorFunction(errorBoundary, tag, func, instance) {
30
- var client = instance instanceof StatsigClientBase_1.StatsigClientBase ? instance['emit'] : undefined;
31
- return errorBoundary.capture(tag, function () { return (0, Diagnostics_1.captureDiagnostics)(tag, function () { return func.apply(instance); }); }, client);
15
+ function _monitorFunction(errorBoundary, tag, func, instance) {
16
+ const emitFunc = instance instanceof StatsigClientBase_1.StatsigClientBase
17
+ ? instance['_emit'].bind(instance)
18
+ : undefined;
19
+ return errorBoundary.capture(tag, () => (0, Diagnostics_1.captureDiagnostics)(tag, () => func.apply(instance)), emitFunc);
20
+ }
21
+ function _getProtoSafe(instance) {
22
+ if (typeof instance === 'object') {
23
+ const proto = Object.getPrototypeOf(instance);
24
+ return proto && typeof proto === 'object'
25
+ ? proto
26
+ : null;
27
+ }
28
+ return null;
29
+ }
30
+ function _getAllInstanceMethodNames(instance) {
31
+ const names = new Set();
32
+ let proto = _getProtoSafe(instance);
33
+ while (proto && proto !== Object.prototype) {
34
+ Object.getOwnPropertyNames(proto)
35
+ .filter((prop) => typeof (proto === null || proto === void 0 ? void 0 : proto[prop]) === 'function')
36
+ .forEach((name) => names.add(name));
37
+ proto = Object.getPrototypeOf(proto);
38
+ }
39
+ return Array.from(names);
40
+ }
41
+ function _getAllStaticMethodNames(instance) {
42
+ const names = new Set();
43
+ const proto = _getProtoSafe(instance);
44
+ Object.getOwnPropertyNames((proto === null || proto === void 0 ? void 0 : proto.constructor) || {})
45
+ .filter((prop) => {
46
+ var _a;
47
+ if (prop === 'caller' || prop === 'arguments' || prop === 'callee') {
48
+ return false;
49
+ }
50
+ return (typeof ((_a = proto === null || proto === void 0 ? void 0 : proto.constructor) === null || _a === void 0 ? void 0 : _a[prop]) === 'function');
51
+ })
52
+ .forEach((name) => names.add(name));
53
+ return Array.from(names);
54
+ }
55
+ function _monitorClassImpl(errorBoundary, instance) {
56
+ var _a;
57
+ const obj = instance;
58
+ for (const method of _getAllInstanceMethodNames(obj)) {
59
+ if (method === 'constructor') {
60
+ continue;
61
+ }
62
+ const original = obj[method];
63
+ obj[method] = function (...args) {
64
+ return _monitorFunction(errorBoundary, method, () => original.apply(this, args), instance);
65
+ };
66
+ }
67
+ for (const method of _getAllStaticMethodNames(obj)) {
68
+ const original = (_a = obj === null || obj === void 0 ? void 0 : obj.constructor) === null || _a === void 0 ? void 0 : _a[method];
69
+ (obj === null || obj === void 0 ? void 0 : obj.constructor)[method] =
70
+ function (...args) {
71
+ return _monitorFunction(errorBoundary, `${obj.constructor.name}.${method}`, () => original.apply(obj.constructor, args), instance);
72
+ };
73
+ }
32
74
  }
33
- exports.monitorFunction = monitorFunction;
@@ -1,22 +1,33 @@
1
- import { StatsigOptionsCommon } from './StatsigOptionsCommon';
1
+ import './$_StatsigGlobal';
2
+ import { StatsigClientEmitEventFunc } from './StatsigClientBase';
3
+ import { AnyStatsigOptions } from './StatsigOptionsCommon';
2
4
  type RequestArgs = {
3
5
  sdkKey: string;
4
6
  url: string;
5
- timeoutMs?: number;
6
7
  retries?: number;
8
+ params?: Record<string, string>;
7
9
  headers?: Record<string, string>;
8
10
  };
9
11
  type RequestArgsWithData = RequestArgs & {
10
12
  data: Record<string, unknown>;
13
+ isStatsigEncodable?: boolean;
14
+ };
15
+ type NetworkResponse = {
16
+ body: string | null;
17
+ code: number;
11
18
  };
12
19
  export declare class NetworkCore {
13
20
  private _options;
21
+ private _emitter?;
14
22
  private readonly _timeout;
15
- constructor(_options: StatsigOptionsCommon | null);
16
- post(args: RequestArgsWithData): Promise<string | null>;
17
- get(args: RequestArgs): Promise<string | null>;
18
- beacon(args: RequestArgsWithData): boolean;
23
+ constructor(_options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
24
+ post(args: RequestArgsWithData): Promise<NetworkResponse | null>;
25
+ get(args: RequestArgs): Promise<NetworkResponse | null>;
26
+ isBeaconSupported(): boolean;
27
+ beacon(args: RequestArgsWithData): Promise<boolean>;
19
28
  private _sendRequest;
20
29
  private _getPopulatedURL;
30
+ private _getPopulatedBody;
31
+ private _attemptToEncodeString;
21
32
  }
22
33
  export {};
@@ -1,30 +1,4 @@
1
1
  "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = function (d, b) {
4
- extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
- return extendStatics(d, b);
8
- };
9
- return function (d, b) {
10
- if (typeof b !== "function" && b !== null)
11
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
- extendStatics(d, b);
13
- function __() { this.constructor = d; }
14
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
- };
16
- })();
17
- var __assign = (this && this.__assign) || function () {
18
- __assign = Object.assign || function(t) {
19
- for (var s, i = 1, n = arguments.length; i < n; i++) {
20
- s = arguments[i];
21
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
22
- t[p] = s[p];
23
- }
24
- return t;
25
- };
26
- return __assign.apply(this, arguments);
27
- };
28
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
3
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
4
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -34,154 +8,142 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
34
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
35
9
  });
36
10
  };
37
- var __generator = (this && this.__generator) || function (thisArg, body) {
38
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
39
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
- function verb(n) { return function (v) { return step([n, v]); }; }
41
- function step(op) {
42
- if (f) throw new TypeError("Generator is already executing.");
43
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
44
- 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;
45
- if (y = 0, t) op = [op[0] & 2, t.value];
46
- switch (op[0]) {
47
- case 0: case 1: t = op; break;
48
- case 4: _.label++; return { value: op[1], done: false };
49
- case 5: _.label++; y = op[1]; op = [0]; continue;
50
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
51
- default:
52
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
53
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
54
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
55
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
56
- if (t[2]) _.ops.pop();
57
- _.trys.pop(); continue;
58
- }
59
- op = body.call(thisArg, _);
60
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
61
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
- }
63
- };
64
11
  Object.defineProperty(exports, "__esModule", { value: true });
65
12
  exports.NetworkCore = void 0;
66
- var Diagnostics_1 = require("./Diagnostics");
67
- var Log_1 = require("./Log");
68
- var SessionID_1 = require("./SessionID");
69
- var StableID_1 = require("./StableID");
70
- var StatsigMetadata_1 = require("./StatsigMetadata");
71
- var DEFAULT_TIMEOUT_MS = 10000;
72
- var NetworkError = /** @class */ (function (_super) {
73
- __extends(NetworkError, _super);
74
- function NetworkError(message, errorDescription) {
75
- var _this = _super.call(this, message) || this;
76
- _this.errorDescription = errorDescription;
77
- return _this;
78
- }
79
- return NetworkError;
80
- }(Error));
81
- var NetworkCore = /** @class */ (function () {
82
- function NetworkCore(_options) {
83
- var _a;
13
+ require("./$_StatsigGlobal");
14
+ const Diagnostics_1 = require("./Diagnostics");
15
+ const Log_1 = require("./Log");
16
+ const NetworkParams_1 = require("./NetworkParams");
17
+ const SDKType_1 = require("./SDKType");
18
+ const SessionID_1 = require("./SessionID");
19
+ const StableID_1 = require("./StableID");
20
+ const StatsigMetadata_1 = require("./StatsigMetadata");
21
+ const DEFAULT_TIMEOUT_MS = 10000;
22
+ class NetworkCore {
23
+ constructor(_options, _emitter) {
24
+ var _a, _b;
84
25
  this._options = _options;
85
- this._timeout = (_a = _options === null || _options === void 0 ? void 0 : _options.networkTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
26
+ this._emitter = _emitter;
27
+ this._timeout =
28
+ (_b = (_a = _options === null || _options === void 0 ? void 0 : _options.networkConfig) === null || _a === void 0 ? void 0 : _a.networkTimeoutMs) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT_MS;
86
29
  }
87
- NetworkCore.prototype.post = function (args) {
88
- return __awaiter(this, void 0, void 0, function () {
89
- var data, stableID, sessionID, body;
90
- return __generator(this, function (_a) {
91
- switch (_a.label) {
92
- case 0:
93
- data = args.data;
94
- return [4 /*yield*/, StableID_1.StableID.get(args.sdkKey)];
95
- case 1:
96
- stableID = _a.sent();
97
- sessionID = SessionID_1.SessionID.get(args.sdkKey);
98
- body = JSON.stringify(__assign(__assign({}, data), { statsigMetadata: __assign(__assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID: stableID, sessionID: sessionID }) }));
99
- return [2 /*return*/, this._sendRequest(__assign({ method: 'POST', body: body }, args))];
100
- }
101
- });
30
+ post(args) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const body = yield this._getPopulatedBody(args);
33
+ return this._sendRequest(Object.assign({ method: 'POST', body: this._attemptToEncodeString(args, body) }, args));
102
34
  });
103
- };
104
- NetworkCore.prototype.get = function (args) {
105
- return __awaiter(this, void 0, void 0, function () {
106
- return __generator(this, function (_a) {
107
- return [2 /*return*/, this._sendRequest(__assign({ method: 'GET' }, args))];
108
- });
35
+ }
36
+ get(args) {
37
+ return this._sendRequest(Object.assign({ method: 'GET' }, args));
38
+ }
39
+ isBeaconSupported() {
40
+ return (typeof navigator !== 'undefined' &&
41
+ typeof (navigator === null || navigator === void 0 ? void 0 : navigator.sendBeacon) === 'function');
42
+ }
43
+ beacon(args) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ if (!_ensureValidSdkKey(args)) {
46
+ return false;
47
+ }
48
+ const url = yield this._getPopulatedURL(args);
49
+ const body = yield this._getPopulatedBody(args);
50
+ return navigator.sendBeacon(url, body);
109
51
  });
110
- };
111
- NetworkCore.prototype.beacon = function (args) {
112
- var url = new URL(args.url);
113
- url.searchParams.append('k', args.sdkKey);
114
- return navigator.sendBeacon(url, JSON.stringify(args.data));
115
- };
116
- NetworkCore.prototype._sendRequest = function (args) {
117
- return __awaiter(this, void 0, void 0, function () {
118
- var method, body, retries, controller, handle, response, fullUrl, text, error_1, errorMessage;
119
- var _this = this;
120
- return __generator(this, function (_a) {
121
- switch (_a.label) {
122
- case 0:
123
- method = args.method, body = args.body, retries = args.retries;
124
- controller = new AbortController();
125
- handle = setTimeout(function () { return controller.abort("Timeout of ".concat(_this._timeout, "ms expired.")); }, this._timeout);
126
- response = null;
127
- _a.label = 1;
128
- case 1:
129
- _a.trys.push([1, 4, , 5]);
130
- fullUrl = this._getPopulatedURL(args);
131
- return [4 /*yield*/, fetch(fullUrl, {
132
- method: method,
133
- body: body,
134
- headers: __assign({
135
- // Must set this content type to bypass cors
136
- // can override via headers if necessary (recommended for logevent)
137
- 'Content-Type': 'text/plain' }, args.headers),
138
- signal: controller.signal,
139
- })];
140
- case 2:
141
- response = _a.sent();
142
- clearTimeout(handle);
143
- return [4 /*yield*/, response.text()];
144
- case 3:
145
- text = _a.sent();
146
- if (!response.ok) {
147
- throw new NetworkError('Fetch Failure', text);
148
- }
149
- Diagnostics_1.Diagnostics.mark('_sendRequest:response-received', {
150
- status: response.status,
151
- contentLength: response.headers.get('content-length'),
152
- });
153
- return [2 /*return*/, text];
154
- case 4:
155
- error_1 = _a.sent();
156
- errorMessage = _getErrorMessage(controller, error_1);
157
- Diagnostics_1.Diagnostics.mark('_sendRequest:error', {
158
- error: errorMessage,
159
- status: response === null || response === void 0 ? void 0 : response.status,
160
- contentLength: response === null || response === void 0 ? void 0 : response.headers.get('content-length'),
161
- });
162
- if (!retries || retries <= 0) {
163
- Log_1.Log.error('A networking error occured.', errorMessage);
164
- return [2 /*return*/, null];
165
- }
166
- return [2 /*return*/, this._sendRequest(__assign(__assign({}, args), { retries: retries - 1 }))];
167
- case 5: return [2 /*return*/];
52
+ }
53
+ _sendRequest(args) {
54
+ var _a;
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ if (!_ensureValidSdkKey(args)) {
57
+ return null;
58
+ }
59
+ const { method, body, retries } = args;
60
+ const controller = new AbortController();
61
+ const handle = setTimeout(() => controller.abort(`Timeout of ${this._timeout}ms expired.`), this._timeout);
62
+ const url = yield this._getPopulatedURL(args);
63
+ let response = null;
64
+ try {
65
+ response = yield fetch(url, {
66
+ method,
67
+ body,
68
+ headers: Object.assign({}, args.headers),
69
+ signal: controller.signal,
70
+ });
71
+ clearTimeout(handle);
72
+ if (!response.ok) {
73
+ const text = yield response.text().catch(() => 'No Text');
74
+ const err = new Error(`Failed to fetch: ${url} ${text}`);
75
+ err.name = 'NetworkError';
76
+ throw err;
77
+ }
78
+ const text = yield response.text();
79
+ Diagnostics_1.Diagnostics.mark('_sendRequest:response-received', {
80
+ status: response.status,
81
+ contentLength: response.headers.get('content-length'),
82
+ });
83
+ return {
84
+ body: text,
85
+ code: response.status,
86
+ };
87
+ }
88
+ catch (error) {
89
+ const errorMessage = _getErrorMessage(controller, error);
90
+ Diagnostics_1.Diagnostics.mark('_sendRequest:error', {
91
+ error: errorMessage,
92
+ status: response === null || response === void 0 ? void 0 : response.status,
93
+ contentLength: response === null || response === void 0 ? void 0 : response.headers.get('content-length'),
94
+ });
95
+ if (!retries || retries <= 0) {
96
+ (_a = this._emitter) === null || _a === void 0 ? void 0 : _a.call(this, { name: 'error', error });
97
+ Log_1.Log.error(`A networking error occured during ${method} request to ${url}.`, errorMessage, error);
98
+ return null;
168
99
  }
169
- });
100
+ return this._sendRequest(Object.assign(Object.assign({}, args), { retries: retries - 1 }));
101
+ }
102
+ });
103
+ }
104
+ _getPopulatedURL(args) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ const params = Object.assign({ [NetworkParams_1.NetworkParam.SdkKey]: args.sdkKey, [NetworkParams_1.NetworkParam.SdkType]: SDKType_1.SDKType._get(args.sdkKey), [NetworkParams_1.NetworkParam.SdkVersion]: StatsigMetadata_1.SDK_VERSION, [NetworkParams_1.NetworkParam.Time]: String(Date.now()), [NetworkParams_1.NetworkParam.SessionID]: yield SessionID_1.SessionID.get(args.sdkKey) }, args.params);
107
+ const query = Object.entries(params)
108
+ .map(([key, value]) => {
109
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
110
+ })
111
+ .join('&');
112
+ return `${args.url}${query ? `?${query}` : ''}`;
113
+ });
114
+ }
115
+ _getPopulatedBody(args) {
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ const { data, sdkKey } = args;
118
+ const stableID = yield StableID_1.StableID.get(sdkKey);
119
+ const sessionID = yield SessionID_1.SessionID.get(sdkKey);
120
+ const sdkType = SDKType_1.SDKType._get(sdkKey);
121
+ return JSON.stringify(Object.assign(Object.assign({}, data), { statsigMetadata: Object.assign(Object.assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID,
122
+ sessionID,
123
+ sdkType }) }));
170
124
  });
171
- };
172
- NetworkCore.prototype._getPopulatedURL = function (args) {
173
- var statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
174
- var fullUrl = new URL(args.url);
175
- fullUrl.searchParams.append('k', args.sdkKey);
176
- fullUrl.searchParams.append('st', statsigMetadata.sdkType);
177
- fullUrl.searchParams.append('sv', statsigMetadata.sdkVersion);
178
- fullUrl.searchParams.append('t', String(Date.now()));
179
- fullUrl.searchParams.append('sid', SessionID_1.SessionID.get(args.sdkKey));
180
- return fullUrl.toString();
181
- };
182
- return NetworkCore;
183
- }());
125
+ }
126
+ _attemptToEncodeString(args, input) {
127
+ var _a, _b, _c;
128
+ if ((__STATSIG__ === null || __STATSIG__ === void 0 ? void 0 : __STATSIG__['no-encode']) != null ||
129
+ ((_a = this._options) === null || _a === void 0 ? void 0 : _a.disableStatsigEncoding) ||
130
+ !args.isStatsigEncodable ||
131
+ typeof window === 'undefined' ||
132
+ !window.btoa) {
133
+ return input;
134
+ }
135
+ args.params = Object.assign(Object.assign({}, ((_b = args.params) !== null && _b !== void 0 ? _b : {})), { [NetworkParams_1.NetworkParam.StatsigEncoded]: '1' });
136
+ return (_c = window.btoa(input).split('').reverse().join('')) !== null && _c !== void 0 ? _c : input;
137
+ }
138
+ }
184
139
  exports.NetworkCore = NetworkCore;
140
+ const _ensureValidSdkKey = (args) => {
141
+ if (!args.sdkKey) {
142
+ Log_1.Log.warn('Unable to make request without an SDK key');
143
+ return false;
144
+ }
145
+ return true;
146
+ };
185
147
  function _getErrorMessage(controller, error) {
186
148
  if (controller.signal.aborted &&
187
149
  typeof controller.signal.reason === 'string') {
@@ -191,7 +153,7 @@ function _getErrorMessage(controller, error) {
191
153
  return error;
192
154
  }
193
155
  if (error instanceof Error) {
194
- return "".concat(error.name, ": ").concat(error.message);
156
+ return `${error.name}: ${error.message}`;
195
157
  }
196
158
  return null;
197
159
  }
@@ -0,0 +1,5 @@
1
+ export declare const NetworkDefault: {
2
+ eventsApi: "https://events.statsigapi.net/v1";
3
+ initializeApi: "https://featuregates.org/v1";
4
+ specsApi: "https://api.statsigcdn.com/v1";
5
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkDefault = void 0;
4
+ exports.NetworkDefault = {
5
+ eventsApi: 'https://events.statsigapi.net/v1',
6
+ initializeApi: 'https://featuregates.org/v1',
7
+ specsApi: 'https://api.statsigcdn.com/v1',
8
+ };
@@ -0,0 +1,9 @@
1
+ export declare enum NetworkParam {
2
+ EventCount = "ec",
3
+ SdkKey = "k",
4
+ SdkType = "st",
5
+ SdkVersion = "sv",
6
+ Time = "t",
7
+ SessionID = "sid",
8
+ StatsigEncoded = "se"
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkParam = void 0;
4
+ var NetworkParam;
5
+ (function (NetworkParam) {
6
+ NetworkParam["EventCount"] = "ec";
7
+ NetworkParam["SdkKey"] = "k";
8
+ NetworkParam["SdkType"] = "st";
9
+ NetworkParam["SdkVersion"] = "sv";
10
+ NetworkParam["Time"] = "t";
11
+ NetworkParam["SessionID"] = "sid";
12
+ NetworkParam["StatsigEncoded"] = "se";
13
+ })(NetworkParam || (exports.NetworkParam = NetworkParam = {}));
@@ -0,0 +1,9 @@
1
+ import { DynamicConfigEvaluationOptions, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, LayerEvaluationOptions } from './EvaluationOptions';
2
+ import { DynamicConfig, Experiment, FeatureGate, Layer } from './StatsigTypes';
3
+ import { StatsigUser } from './StatsigUser';
4
+ export type OverrideAdapter = {
5
+ getGateOverride?(current: FeatureGate, user: StatsigUser, options?: FeatureGateEvaluationOptions): FeatureGate | null;
6
+ getDynamicConfigOverride?(current: DynamicConfig, user: StatsigUser, options?: DynamicConfigEvaluationOptions): DynamicConfig | null;
7
+ getExperimentOverride?(current: Experiment, user: StatsigUser, options?: ExperimentEvaluationOptions): Experiment | null;
8
+ getLayerOverride?(current: Layer, user: StatsigUser, options?: LayerEvaluationOptions): Layer | null;
9
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ type ClientType = 'javascript-client' | 'js-on-device-eval-client';
2
+ type BindingType = 'expo' | 'rn' | 'react';
3
+ export declare const SDKType: {
4
+ _get: (sdkKey: string) => string;
5
+ _setClientType(sdkKey: string, client: ClientType): void;
6
+ _setBindingType(binding: BindingType): void;
7
+ };
8
+ export {};
package/src/SDKType.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SDKType = void 0;
4
+ const SDK_CLIENT = {};
5
+ let suffix;
6
+ exports.SDKType = {
7
+ _get: (sdkKey) => {
8
+ var _a;
9
+ return ((_a = SDK_CLIENT[sdkKey]) !== null && _a !== void 0 ? _a : 'js-mono') + (suffix !== null && suffix !== void 0 ? suffix : '');
10
+ },
11
+ _setClientType(sdkKey, client) {
12
+ SDK_CLIENT[sdkKey] = client;
13
+ },
14
+ _setBindingType(binding) {
15
+ if (!suffix || suffix === '-react') {
16
+ suffix = '-' + binding;
17
+ }
18
+ },
19
+ };