@statsig/client-core 0.0.1-beta.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/package.json +1 -1
- package/src/$_StatsigGlobal.d.ts +9 -1
- package/src/$_StatsigGlobal.js +29 -12
- package/src/CacheKey.d.ts +4 -0
- package/src/CacheKey.js +27 -0
- package/src/ClientInterfaces.d.ts +46 -12
- package/src/DataAdapterCore.d.ts +31 -0
- package/src/DataAdapterCore.js +192 -0
- package/src/Diagnostics.d.ts +1 -3
- package/src/Diagnostics.js +4 -49
- package/src/DownloadConfigSpecsResponse.d.ts +41 -0
- package/src/DownloadConfigSpecsResponse.js +2 -0
- package/src/ErrorBoundary.d.ts +7 -2
- package/src/ErrorBoundary.js +81 -88
- package/src/EvaluationOptions.d.ts +20 -0
- package/src/EvaluationOptions.js +2 -0
- package/src/EvaluationTypes.d.ts +39 -0
- package/src/EvaluationTypes.js +2 -0
- package/src/EventLogger.d.ts +15 -10
- package/src/EventLogger.js +216 -256
- package/src/Hashing.d.ts +2 -1
- package/src/Hashing.js +26 -7
- package/src/InitializeResponse.d.ts +20 -0
- package/src/InitializeResponse.js +2 -0
- package/src/Log.js +15 -34
- package/src/NetworkConfig.d.ts +19 -0
- package/src/NetworkConfig.js +19 -0
- package/src/NetworkCore.d.ts +17 -7
- package/src/NetworkCore.js +173 -196
- package/src/OverrideAdapter.d.ts +9 -0
- package/src/OverrideAdapter.js +2 -0
- package/src/SDKType.d.ts +8 -0
- package/src/SDKType.js +19 -0
- package/src/SafeJs.d.ts +6 -0
- package/src/SafeJs.js +41 -0
- package/src/SessionID.d.ts +17 -1
- package/src/SessionID.js +89 -8
- package/src/StableID.js +24 -53
- package/src/StatsigClientBase.d.ts +56 -19
- package/src/StatsigClientBase.js +126 -48
- package/src/StatsigClientEventEmitter.d.ts +54 -33
- package/src/StatsigDataAdapter.d.ts +103 -17
- package/src/StatsigDataAdapter.js +2 -0
- package/src/StatsigEvent.d.ts +10 -18
- package/src/StatsigEvent.js +41 -39
- package/src/StatsigMetadata.d.ts +1 -1
- package/src/StatsigMetadata.js +7 -18
- package/src/StatsigOptionsCommon.d.ts +84 -20
- package/src/StatsigTypeFactories.d.ts +6 -0
- package/src/StatsigTypeFactories.js +50 -0
- package/src/StatsigTypes.d.ts +28 -22
- package/src/StatsigTypes.js +0 -29
- package/src/StatsigUser.d.ts +7 -8
- package/src/StatsigUser.js +11 -24
- package/src/StorageProvider.d.ts +13 -8
- package/src/StorageProvider.js +66 -85
- package/src/TypedJsonParse.d.ts +8 -0
- package/src/TypedJsonParse.js +27 -0
- package/src/UUID.js +9 -5
- package/src/UrlOverrides.d.ts +1 -0
- package/src/UrlOverrides.js +15 -0
- package/src/UtitlityTypes.d.ts +3 -0
- package/src/UtitlityTypes.js +2 -0
- package/src/VisibilityObserving.d.ts +9 -0
- package/src/VisibilityObserving.js +39 -0
- package/src/index.d.ts +20 -4
- package/src/index.js +26 -18
- package/src/Monitoring.d.ts +0 -3
- package/src/Monitoring.js +0 -33
- package/src/VisibilityChangeObserver.d.ts +0 -13
- package/src/VisibilityChangeObserver.js +0 -48
- package/src/__tests__/MockLocalStorage.d.ts +0 -9
- package/src/__tests__/MockLocalStorage.js +0 -37
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const NetworkDefault: {
|
|
2
|
+
eventsApi: "https://prodregistryv2.org/v1";
|
|
3
|
+
initializeApi: "https://featureassets.org/v1";
|
|
4
|
+
specsApi: "https://assetsconfigcdn.org/v1";
|
|
5
|
+
};
|
|
6
|
+
export type NetworkPriority = 'high' | 'low' | 'auto';
|
|
7
|
+
export type NetworkArgs = RequestInit & {
|
|
8
|
+
priority?: NetworkPriority;
|
|
9
|
+
};
|
|
10
|
+
export declare enum NetworkParam {
|
|
11
|
+
EventCount = "ec",
|
|
12
|
+
SdkKey = "k",
|
|
13
|
+
SdkType = "st",
|
|
14
|
+
SdkVersion = "sv",
|
|
15
|
+
Time = "t",
|
|
16
|
+
SessionID = "sid",
|
|
17
|
+
StatsigEncoded = "se",
|
|
18
|
+
IsGzipped = "gz"
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NetworkParam = exports.NetworkDefault = void 0;
|
|
4
|
+
exports.NetworkDefault = {
|
|
5
|
+
eventsApi: 'https://prodregistryv2.org/v1',
|
|
6
|
+
initializeApi: 'https://featureassets.org/v1',
|
|
7
|
+
specsApi: 'https://assetsconfigcdn.org/v1',
|
|
8
|
+
};
|
|
9
|
+
var NetworkParam;
|
|
10
|
+
(function (NetworkParam) {
|
|
11
|
+
NetworkParam["EventCount"] = "ec";
|
|
12
|
+
NetworkParam["SdkKey"] = "k";
|
|
13
|
+
NetworkParam["SdkType"] = "st";
|
|
14
|
+
NetworkParam["SdkVersion"] = "sv";
|
|
15
|
+
NetworkParam["Time"] = "t";
|
|
16
|
+
NetworkParam["SessionID"] = "sid";
|
|
17
|
+
NetworkParam["StatsigEncoded"] = "se";
|
|
18
|
+
NetworkParam["IsGzipped"] = "gz";
|
|
19
|
+
})(NetworkParam || (exports.NetworkParam = NetworkParam = {}));
|
package/src/NetworkCore.d.ts
CHANGED
|
@@ -1,30 +1,40 @@
|
|
|
1
|
+
import './$_StatsigGlobal';
|
|
2
|
+
import { NetworkPriority } from './NetworkConfig';
|
|
1
3
|
import { StatsigClientEmitEventFunc } from './StatsigClientBase';
|
|
2
|
-
import {
|
|
4
|
+
import { AnyStatsigOptions } from './StatsigOptionsCommon';
|
|
5
|
+
import { Flatten } from './UtitlityTypes';
|
|
3
6
|
type RequestArgs = {
|
|
4
7
|
sdkKey: string;
|
|
5
8
|
url: string;
|
|
6
|
-
|
|
9
|
+
priority?: NetworkPriority;
|
|
7
10
|
retries?: number;
|
|
8
11
|
params?: Record<string, string>;
|
|
9
12
|
headers?: Record<string, string>;
|
|
10
13
|
};
|
|
11
|
-
type RequestArgsWithData = RequestArgs & {
|
|
14
|
+
export type RequestArgsWithData = Flatten<RequestArgs & {
|
|
12
15
|
data: Record<string, unknown>;
|
|
13
|
-
|
|
16
|
+
isStatsigEncodable?: boolean;
|
|
17
|
+
isCompressable?: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
type BeaconRequestArgs = Pick<RequestArgsWithData, 'data' | 'sdkKey' | 'url' | 'params' | 'isCompressable'>;
|
|
14
20
|
type NetworkResponse = {
|
|
15
21
|
body: string | null;
|
|
16
22
|
code: number;
|
|
17
23
|
};
|
|
18
24
|
export declare class NetworkCore {
|
|
19
|
-
private _options;
|
|
20
25
|
private _emitter?;
|
|
21
26
|
private readonly _timeout;
|
|
22
|
-
|
|
27
|
+
private readonly _netConfig;
|
|
28
|
+
private readonly _options;
|
|
29
|
+
constructor(options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
|
|
23
30
|
post(args: RequestArgsWithData): Promise<NetworkResponse | null>;
|
|
24
31
|
get(args: RequestArgs): Promise<NetworkResponse | null>;
|
|
25
|
-
|
|
32
|
+
isBeaconSupported(): boolean;
|
|
33
|
+
beacon(args: BeaconRequestArgs): Promise<boolean>;
|
|
26
34
|
private _sendRequest;
|
|
27
35
|
private _getPopulatedURL;
|
|
28
36
|
private _getPopulatedBody;
|
|
37
|
+
private _attemptToEncodeString;
|
|
38
|
+
private _attemptToCompressBody;
|
|
29
39
|
}
|
|
30
40
|
export {};
|
package/src/NetworkCore.js
CHANGED
|
@@ -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,187 +8,190 @@ 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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}(Error));
|
|
81
|
-
var NetworkCore = /** @class */ (function () {
|
|
82
|
-
function NetworkCore(_options, _emitter) {
|
|
83
|
-
var _a;
|
|
84
|
-
this._options = _options;
|
|
13
|
+
require("./$_StatsigGlobal");
|
|
14
|
+
const __StatsigGlobal_1 = require("./$_StatsigGlobal");
|
|
15
|
+
const Diagnostics_1 = require("./Diagnostics");
|
|
16
|
+
const Log_1 = require("./Log");
|
|
17
|
+
const NetworkConfig_1 = require("./NetworkConfig");
|
|
18
|
+
const SDKType_1 = require("./SDKType");
|
|
19
|
+
const SafeJs_1 = require("./SafeJs");
|
|
20
|
+
const SessionID_1 = require("./SessionID");
|
|
21
|
+
const StableID_1 = require("./StableID");
|
|
22
|
+
const StatsigMetadata_1 = require("./StatsigMetadata");
|
|
23
|
+
const VisibilityObserving_1 = require("./VisibilityObserving");
|
|
24
|
+
const DEFAULT_TIMEOUT_MS = 10000;
|
|
25
|
+
class NetworkCore {
|
|
26
|
+
constructor(options, _emitter) {
|
|
85
27
|
this._emitter = _emitter;
|
|
86
|
-
this._timeout =
|
|
28
|
+
this._timeout = DEFAULT_TIMEOUT_MS;
|
|
29
|
+
this._netConfig = {};
|
|
30
|
+
this._options = {};
|
|
31
|
+
if (options) {
|
|
32
|
+
this._options = options;
|
|
33
|
+
}
|
|
34
|
+
if (this._options.networkConfig) {
|
|
35
|
+
this._netConfig = this._options.networkConfig;
|
|
36
|
+
}
|
|
37
|
+
if (this._netConfig.networkTimeoutMs) {
|
|
38
|
+
this._timeout = this._netConfig.networkTimeoutMs;
|
|
39
|
+
}
|
|
87
40
|
}
|
|
88
|
-
|
|
89
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
});
|
|
41
|
+
post(args) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
let body = yield this._getPopulatedBody(args);
|
|
44
|
+
if (args.isStatsigEncodable) {
|
|
45
|
+
body = this._attemptToEncodeString(args, body);
|
|
46
|
+
}
|
|
47
|
+
else if (args.isCompressable) {
|
|
48
|
+
body = yield this._attemptToCompressBody(args, body);
|
|
49
|
+
}
|
|
50
|
+
return this._sendRequest(Object.assign({ method: 'POST', body }, args));
|
|
99
51
|
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
52
|
+
}
|
|
53
|
+
get(args) {
|
|
54
|
+
return this._sendRequest(Object.assign({ method: 'GET' }, args));
|
|
55
|
+
}
|
|
56
|
+
isBeaconSupported() {
|
|
57
|
+
return (typeof navigator !== 'undefined' &&
|
|
58
|
+
typeof navigator.sendBeacon === 'function');
|
|
59
|
+
}
|
|
60
|
+
beacon(args) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (!_ensureValidSdkKey(args)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
let body = yield this._getPopulatedBody(args);
|
|
66
|
+
body = yield this._attemptToCompressBody(args, body);
|
|
67
|
+
const url = yield this._getPopulatedURL(args);
|
|
68
|
+
const nav = navigator;
|
|
69
|
+
return nav.sendBeacon.bind(nav)(url, body);
|
|
106
70
|
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
71
|
+
}
|
|
72
|
+
_sendRequest(args) {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
if (!_ensureValidSdkKey(args)) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if (this._netConfig.preventAllNetworkTraffic) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const { method, body, retries } = args;
|
|
82
|
+
const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
83
|
+
const handle = setTimeout(() => controller === null || controller === void 0 ? void 0 : controller.abort(`Timeout of ${this._timeout}ms expired.`), this._timeout);
|
|
84
|
+
const url = yield this._getPopulatedURL(args);
|
|
85
|
+
let response = null;
|
|
86
|
+
const keepalive = (0, VisibilityObserving_1._isUnloading)();
|
|
87
|
+
try {
|
|
88
|
+
const config = {
|
|
89
|
+
method,
|
|
90
|
+
body,
|
|
91
|
+
headers: Object.assign({}, args.headers),
|
|
92
|
+
signal: controller === null || controller === void 0 ? void 0 : controller.signal,
|
|
93
|
+
priority: args.priority,
|
|
94
|
+
keepalive,
|
|
95
|
+
};
|
|
96
|
+
const func = (_a = this._netConfig.networkOverrideFunc) !== null && _a !== void 0 ? _a : fetch;
|
|
97
|
+
response = yield func(url, config);
|
|
98
|
+
clearTimeout(handle);
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const text = yield response.text().catch(() => 'No Text');
|
|
101
|
+
const err = new Error(`NetworkError: ${url} ${text}`);
|
|
102
|
+
err.name = 'NetworkError';
|
|
103
|
+
throw err;
|
|
119
104
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
response = null;
|
|
135
|
-
_b.label = 1;
|
|
136
|
-
case 1:
|
|
137
|
-
_b.trys.push([1, 4, , 5]);
|
|
138
|
-
url = this._getPopulatedURL(args);
|
|
139
|
-
return [4 /*yield*/, fetch(url, {
|
|
140
|
-
method: method,
|
|
141
|
-
body: body,
|
|
142
|
-
headers: __assign({}, args.headers),
|
|
143
|
-
signal: controller.signal,
|
|
144
|
-
})];
|
|
145
|
-
case 2:
|
|
146
|
-
response = _b.sent();
|
|
147
|
-
clearTimeout(handle);
|
|
148
|
-
return [4 /*yield*/, response.text()];
|
|
149
|
-
case 3:
|
|
150
|
-
text = _b.sent();
|
|
151
|
-
if (!response.ok) {
|
|
152
|
-
throw new NetworkError('Fetch Failure', text);
|
|
153
|
-
}
|
|
154
|
-
Diagnostics_1.Diagnostics.mark('_sendRequest:response-received', {
|
|
155
|
-
status: response.status,
|
|
156
|
-
contentLength: response.headers.get('content-length'),
|
|
157
|
-
});
|
|
158
|
-
return [2 /*return*/, {
|
|
159
|
-
body: text,
|
|
160
|
-
code: response.status,
|
|
161
|
-
}];
|
|
162
|
-
case 4:
|
|
163
|
-
error_1 = _b.sent();
|
|
164
|
-
errorMessage = _getErrorMessage(controller, error_1);
|
|
165
|
-
Diagnostics_1.Diagnostics.mark('_sendRequest:error', {
|
|
166
|
-
error: errorMessage,
|
|
167
|
-
status: response === null || response === void 0 ? void 0 : response.status,
|
|
168
|
-
contentLength: response === null || response === void 0 ? void 0 : response.headers.get('content-length'),
|
|
169
|
-
});
|
|
170
|
-
if (!retries || retries <= 0) {
|
|
171
|
-
(_a = this._emitter) === null || _a === void 0 ? void 0 : _a.call(this, { event: 'error', error: error_1 });
|
|
172
|
-
Log_1.Log.error('A networking error occured.', errorMessage);
|
|
173
|
-
return [2 /*return*/, null];
|
|
174
|
-
}
|
|
175
|
-
return [2 /*return*/, this._sendRequest(__assign(__assign({}, args), { retries: retries - 1 }))];
|
|
176
|
-
case 5: return [2 /*return*/];
|
|
105
|
+
const text = yield response.text();
|
|
106
|
+
Diagnostics_1.Diagnostics.mark();
|
|
107
|
+
return {
|
|
108
|
+
body: text,
|
|
109
|
+
code: response.status,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const errorMessage = _getErrorMessage(controller, error);
|
|
114
|
+
Diagnostics_1.Diagnostics.mark();
|
|
115
|
+
if (!retries || retries <= 0) {
|
|
116
|
+
(_b = this._emitter) === null || _b === void 0 ? void 0 : _b.call(this, { name: 'error', error });
|
|
117
|
+
Log_1.Log.error(`A networking error occured during ${method} request to ${url}.`, errorMessage, error);
|
|
118
|
+
return null;
|
|
177
119
|
}
|
|
178
|
-
|
|
120
|
+
return this._sendRequest(Object.assign(Object.assign({}, args), { retries: retries - 1 }));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
_getPopulatedURL(args) {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
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]: yield SessionID_1.SessionID.get(args.sdkKey) }, args.params);
|
|
127
|
+
const query = Object.entries(params)
|
|
128
|
+
.map(([key, value]) => {
|
|
129
|
+
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
130
|
+
})
|
|
131
|
+
.join('&');
|
|
132
|
+
return `${args.url}${query ? `?${query}` : ''}`;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
_getPopulatedBody(args) {
|
|
136
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
const { data, sdkKey } = args;
|
|
138
|
+
const stableID = yield StableID_1.StableID.get(sdkKey);
|
|
139
|
+
const sessionID = yield SessionID_1.SessionID.get(sdkKey);
|
|
140
|
+
const sdkType = SDKType_1.SDKType._get(sdkKey);
|
|
141
|
+
return JSON.stringify(Object.assign(Object.assign({}, data), { statsigMetadata: Object.assign(Object.assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID,
|
|
142
|
+
sessionID,
|
|
143
|
+
sdkType }) }));
|
|
179
144
|
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
var
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (args.params) {
|
|
190
|
-
Object.entries(args.params).forEach(function (_a) {
|
|
191
|
-
var k = _a[0], v = _a[1];
|
|
192
|
-
url.searchParams.append(k, v);
|
|
193
|
-
});
|
|
145
|
+
}
|
|
146
|
+
_attemptToEncodeString(args, input) {
|
|
147
|
+
var _a, _b;
|
|
148
|
+
const win = (0, SafeJs_1._getWindowSafe)();
|
|
149
|
+
if (!args.isStatsigEncodable ||
|
|
150
|
+
this._options.disableStatsigEncoding ||
|
|
151
|
+
(0, __StatsigGlobal_1._getStatsigGlobalFlag)('no-encode') != null ||
|
|
152
|
+
!(win === null || win === void 0 ? void 0 : win.btoa)) {
|
|
153
|
+
return input;
|
|
194
154
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
155
|
+
try {
|
|
156
|
+
const result = (_a = win.btoa(input).split('').reverse().join('')) !== null && _a !== void 0 ? _a : input;
|
|
157
|
+
args.params = Object.assign(Object.assign({}, ((_b = args.params) !== null && _b !== void 0 ? _b : {})), { [NetworkConfig_1.NetworkParam.StatsigEncoded]: '1' });
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
catch (_c) {
|
|
161
|
+
Log_1.Log.warn('/initialize request encoding failed');
|
|
162
|
+
return input;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
_attemptToCompressBody(args, body) {
|
|
166
|
+
var _a;
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
if (!args.isCompressable ||
|
|
169
|
+
this._options.disableCompression ||
|
|
170
|
+
(0, __StatsigGlobal_1._getStatsigGlobalFlag)('no-compress') != null ||
|
|
171
|
+
typeof CompressionStream === 'undefined' ||
|
|
172
|
+
typeof TextEncoder === 'undefined') {
|
|
173
|
+
return body;
|
|
174
|
+
}
|
|
175
|
+
const bytes = new TextEncoder().encode(body);
|
|
176
|
+
const stream = new CompressionStream('gzip');
|
|
177
|
+
const writer = stream.writable.getWriter();
|
|
178
|
+
writer.write(bytes).catch(Log_1.Log.error);
|
|
179
|
+
writer.close().catch(Log_1.Log.error);
|
|
180
|
+
args.params = Object.assign(Object.assign({}, ((_a = args.params) !== null && _a !== void 0 ? _a : {})), { [NetworkConfig_1.NetworkParam.IsGzipped]: '1' });
|
|
181
|
+
return yield new Response(stream.readable).arrayBuffer();
|
|
211
182
|
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
}());
|
|
183
|
+
}
|
|
184
|
+
}
|
|
215
185
|
exports.NetworkCore = NetworkCore;
|
|
186
|
+
const _ensureValidSdkKey = (args) => {
|
|
187
|
+
if (!args.sdkKey) {
|
|
188
|
+
Log_1.Log.warn('Unable to make request without an SDK key');
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
};
|
|
216
193
|
function _getErrorMessage(controller, error) {
|
|
217
|
-
if (controller.signal.aborted &&
|
|
194
|
+
if ((controller === null || controller === void 0 ? void 0 : controller.signal.aborted) &&
|
|
218
195
|
typeof controller.signal.reason === 'string') {
|
|
219
196
|
return controller.signal.reason;
|
|
220
197
|
}
|
|
@@ -222,7 +199,7 @@ function _getErrorMessage(controller, error) {
|
|
|
222
199
|
return error;
|
|
223
200
|
}
|
|
224
201
|
if (error instanceof Error) {
|
|
225
|
-
return
|
|
202
|
+
return `${error.name}: ${error.message}`;
|
|
226
203
|
}
|
|
227
|
-
return
|
|
204
|
+
return 'Unknown Error';
|
|
228
205
|
}
|
|
@@ -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
|
+
};
|
package/src/SDKType.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type ClientType = 'javascript-client' | 'js-on-device-eval-client';
|
|
2
|
+
type BindingType = 'expo' | 'rn' | 'react' | 'angular';
|
|
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
|
+
};
|
package/src/SafeJs.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const _getWindowSafe: () => Window | null;
|
|
2
|
+
export declare const _getDocumentSafe: () => Document | null;
|
|
3
|
+
export declare const _isBrowserEnv: () => boolean;
|
|
4
|
+
export declare const _addWindowEventListenerSafe: (key: string, listener: () => void) => void;
|
|
5
|
+
export declare const _addDocumentEventListenerSafe: (key: string, listener: () => void) => void;
|
|
6
|
+
export declare const _getCurrentPageUrlSafe: () => string | undefined;
|
package/src/SafeJs.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._getCurrentPageUrlSafe = exports._addDocumentEventListenerSafe = exports._addWindowEventListenerSafe = exports._isBrowserEnv = exports._getDocumentSafe = exports._getWindowSafe = void 0;
|
|
4
|
+
const _getWindowSafe = () => {
|
|
5
|
+
return typeof window !== 'undefined' ? window : null;
|
|
6
|
+
};
|
|
7
|
+
exports._getWindowSafe = _getWindowSafe;
|
|
8
|
+
const _getDocumentSafe = () => {
|
|
9
|
+
var _a;
|
|
10
|
+
const win = (0, exports._getWindowSafe)();
|
|
11
|
+
return (_a = win === null || win === void 0 ? void 0 : win.document) !== null && _a !== void 0 ? _a : null;
|
|
12
|
+
};
|
|
13
|
+
exports._getDocumentSafe = _getDocumentSafe;
|
|
14
|
+
const _isBrowserEnv = () => {
|
|
15
|
+
return (0, exports._getDocumentSafe)() != null;
|
|
16
|
+
};
|
|
17
|
+
exports._isBrowserEnv = _isBrowserEnv;
|
|
18
|
+
const _addWindowEventListenerSafe = (key, listener) => {
|
|
19
|
+
const win = (0, exports._getWindowSafe)();
|
|
20
|
+
if (typeof (win === null || win === void 0 ? void 0 : win.addEventListener) === 'function') {
|
|
21
|
+
win.addEventListener(key, listener);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports._addWindowEventListenerSafe = _addWindowEventListenerSafe;
|
|
25
|
+
const _addDocumentEventListenerSafe = (key, listener) => {
|
|
26
|
+
const doc = (0, exports._getDocumentSafe)();
|
|
27
|
+
if (typeof (doc === null || doc === void 0 ? void 0 : doc.addEventListener) === 'function') {
|
|
28
|
+
doc.addEventListener(key, listener);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
exports._addDocumentEventListenerSafe = _addDocumentEventListenerSafe;
|
|
32
|
+
const _getCurrentPageUrlSafe = () => {
|
|
33
|
+
var _a;
|
|
34
|
+
try {
|
|
35
|
+
return (_a = (0, exports._getWindowSafe)()) === null || _a === void 0 ? void 0 : _a.location.href.split(/[?#]/)[0];
|
|
36
|
+
}
|
|
37
|
+
catch (_b) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
exports._getCurrentPageUrlSafe = _getCurrentPageUrlSafe;
|
package/src/SessionID.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
type SessionTimeoutID = ReturnType<typeof setTimeout>;
|
|
2
|
+
type SessionData = {
|
|
3
|
+
sessionID: string;
|
|
4
|
+
startTime: number;
|
|
5
|
+
lastUpdate: number;
|
|
6
|
+
};
|
|
7
|
+
export type StatsigSession = {
|
|
8
|
+
data: SessionData;
|
|
9
|
+
sdkKey: string;
|
|
10
|
+
ageTimeoutID?: SessionTimeoutID;
|
|
11
|
+
idleTimeoutID?: SessionTimeoutID;
|
|
12
|
+
};
|
|
1
13
|
export declare const SessionID: {
|
|
2
|
-
get: (sdkKey: string) => string
|
|
14
|
+
get: (sdkKey: string) => Promise<string>;
|
|
15
|
+
};
|
|
16
|
+
export declare const StatsigSession: {
|
|
17
|
+
get: (sdkKey: string) => Promise<StatsigSession>;
|
|
3
18
|
};
|
|
19
|
+
export {};
|