@statsig/client-core 3.9.1 → 3.10.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 +1 -1
- package/src/ClientInterfaces.d.ts +5 -4
- package/src/Diagnostics.d.ts +1 -1
- package/src/Diagnostics.js +3 -1
- package/src/ErrorBoundary.d.ts +4 -1
- package/src/ErrorBoundary.js +26 -1
- package/src/EvaluationTypes.d.ts +2 -2
- package/src/NetworkCore.d.ts +3 -1
- package/src/NetworkCore.js +15 -3
- package/src/StatsigClientBase.d.ts +2 -1
- package/src/StatsigMetadata.d.ts +1 -1
- package/src/StatsigMetadata.js +1 -1
- package/src/StatsigUpdateDetails.d.ts +14 -0
- package/src/StatsigUpdateDetails.js +17 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
package/package.json
CHANGED
|
@@ -8,11 +8,12 @@ import { EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
|
|
|
8
8
|
import { StatsigEvent } from './StatsigEvent';
|
|
9
9
|
import { AnyStatsigOptions, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
|
|
10
10
|
import { DynamicConfig, Experiment, FeatureGate, Layer, ParameterStore } from './StatsigTypes';
|
|
11
|
+
import { StatsigUpdateDetails } from './StatsigUpdateDetails';
|
|
11
12
|
import { StatsigUser } from './StatsigUser';
|
|
12
13
|
import { Flatten } from './TypingUtils';
|
|
13
14
|
export interface StatsigClientCommonInterface extends StatsigClientEventEmitterInterface {
|
|
14
|
-
initializeSync():
|
|
15
|
-
initializeAsync(): Promise<
|
|
15
|
+
initializeSync(): StatsigUpdateDetails;
|
|
16
|
+
initializeAsync(): Promise<StatsigUpdateDetails>;
|
|
16
17
|
shutdown(): Promise<void>;
|
|
17
18
|
flush(): Promise<void>;
|
|
18
19
|
updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
|
|
@@ -45,8 +46,8 @@ export type PrecomputedEvaluationsContext = Flatten<CommonContext & {
|
|
|
45
46
|
export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
|
|
46
47
|
readonly dataAdapter: EvaluationsDataAdapter;
|
|
47
48
|
getContext(): PrecomputedEvaluationsContext;
|
|
48
|
-
updateUserSync(user: StatsigUser):
|
|
49
|
-
updateUserAsync(user: StatsigUser): Promise<
|
|
49
|
+
updateUserSync(user: StatsigUser): StatsigUpdateDetails;
|
|
50
|
+
updateUserAsync(user: StatsigUser): Promise<StatsigUpdateDetails>;
|
|
50
51
|
checkGate(name: string, options?: FeatureGateEvaluationOptions): boolean;
|
|
51
52
|
getFeatureGate(name: string, options?: FeatureGateEvaluationOptions): FeatureGate;
|
|
52
53
|
getDynamicConfig(name: string, options?: DynamicConfigEvaluationOptions): DynamicConfig;
|
package/src/Diagnostics.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export declare const Diagnostics: {
|
|
|
42
42
|
attempt: number;
|
|
43
43
|
error?: Record<string, unknown> | undefined;
|
|
44
44
|
};
|
|
45
|
-
_enqueueDiagnosticsEvent(user: StatsigUserInternal | null, logger: EventLogger, sdk: string, options: StatsigOptionsCommon<NetworkConfigCommon> | null):
|
|
45
|
+
_enqueueDiagnosticsEvent(user: StatsigUserInternal | null, logger: EventLogger, sdk: string, options: StatsigOptionsCommon<NetworkConfigCommon> | null): number;
|
|
46
46
|
};
|
|
47
47
|
interface InitializeDataType {
|
|
48
48
|
process: {
|
package/src/Diagnostics.js
CHANGED
|
@@ -60,8 +60,9 @@ exports.Diagnostics = {
|
|
|
60
60
|
_enqueueDiagnosticsEvent(user, logger, sdk, options) {
|
|
61
61
|
const markers = exports.Diagnostics._getMarkers(sdk);
|
|
62
62
|
if (markers == null || markers.length <= 0) {
|
|
63
|
-
return;
|
|
63
|
+
return -1;
|
|
64
64
|
}
|
|
65
|
+
const overallInitDuration = markers[markers.length - 1].timestamp - markers[0].timestamp;
|
|
65
66
|
exports.Diagnostics._clearMarkers(sdk);
|
|
66
67
|
const event = _makeDiagnosticsEvent(user, {
|
|
67
68
|
context: 'initialize',
|
|
@@ -69,6 +70,7 @@ exports.Diagnostics = {
|
|
|
69
70
|
statsigOptions: options,
|
|
70
71
|
});
|
|
71
72
|
logger.enqueue(event);
|
|
73
|
+
return overallInitDuration;
|
|
72
74
|
},
|
|
73
75
|
};
|
|
74
76
|
function _createMarker(data, action, key, step) {
|
package/src/ErrorBoundary.d.ts
CHANGED
|
@@ -5,10 +5,13 @@ export declare class ErrorBoundary {
|
|
|
5
5
|
private _sdkKey;
|
|
6
6
|
private _options;
|
|
7
7
|
private _emitter?;
|
|
8
|
+
private _lastSeenError?;
|
|
8
9
|
private _seen;
|
|
9
|
-
constructor(_sdkKey: string, _options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
|
|
10
|
+
constructor(_sdkKey: string, _options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined, _lastSeenError?: Error | undefined);
|
|
10
11
|
wrap(instance: unknown): void;
|
|
11
12
|
logError(tag: string, error: unknown): void;
|
|
13
|
+
getLastSeenErrorAndReset(): Error | null;
|
|
14
|
+
attachErrorIfNoneExists(error: unknown): void;
|
|
12
15
|
private _capture;
|
|
13
16
|
private _onError;
|
|
14
17
|
}
|
package/src/ErrorBoundary.js
CHANGED
|
@@ -16,10 +16,11 @@ const StatsigMetadata_1 = require("./StatsigMetadata");
|
|
|
16
16
|
exports.EXCEPTION_ENDPOINT = 'https://statsigapi.net/v1/sdk_exception';
|
|
17
17
|
const UNKNOWN_ERROR = '[Statsig] UnknownError';
|
|
18
18
|
class ErrorBoundary {
|
|
19
|
-
constructor(_sdkKey, _options, _emitter) {
|
|
19
|
+
constructor(_sdkKey, _options, _emitter, _lastSeenError) {
|
|
20
20
|
this._sdkKey = _sdkKey;
|
|
21
21
|
this._options = _options;
|
|
22
22
|
this._emitter = _emitter;
|
|
23
|
+
this._lastSeenError = _lastSeenError;
|
|
23
24
|
this._seen = new Set();
|
|
24
25
|
}
|
|
25
26
|
wrap(instance) {
|
|
@@ -43,6 +44,17 @@ class ErrorBoundary {
|
|
|
43
44
|
logError(tag, error) {
|
|
44
45
|
this._onError(tag, error);
|
|
45
46
|
}
|
|
47
|
+
getLastSeenErrorAndReset() {
|
|
48
|
+
const tempError = this._lastSeenError;
|
|
49
|
+
this._lastSeenError = undefined;
|
|
50
|
+
return tempError !== null && tempError !== void 0 ? tempError : null;
|
|
51
|
+
}
|
|
52
|
+
attachErrorIfNoneExists(error) {
|
|
53
|
+
if (this._lastSeenError) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this._lastSeenError = _resolveError(error);
|
|
57
|
+
}
|
|
46
58
|
_capture(tag, task) {
|
|
47
59
|
try {
|
|
48
60
|
const res = task();
|
|
@@ -64,6 +76,8 @@ class ErrorBoundary {
|
|
|
64
76
|
const unwrapped = (error ? error : Error(UNKNOWN_ERROR));
|
|
65
77
|
const isError = unwrapped instanceof Error;
|
|
66
78
|
const name = isError ? unwrapped.name : 'No Name';
|
|
79
|
+
const resolvedError = _resolveError(unwrapped);
|
|
80
|
+
this._lastSeenError = resolvedError;
|
|
67
81
|
if (this._seen.has(name)) {
|
|
68
82
|
return;
|
|
69
83
|
}
|
|
@@ -111,6 +125,17 @@ class ErrorBoundary {
|
|
|
111
125
|
}
|
|
112
126
|
}
|
|
113
127
|
exports.ErrorBoundary = ErrorBoundary;
|
|
128
|
+
function _resolveError(error) {
|
|
129
|
+
if (error instanceof Error) {
|
|
130
|
+
return error;
|
|
131
|
+
}
|
|
132
|
+
else if (typeof error === 'string') {
|
|
133
|
+
return new Error(error);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
return new Error('An unknown error occurred.');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
114
139
|
function _getDescription(obj) {
|
|
115
140
|
try {
|
|
116
141
|
return JSON.stringify(obj);
|
package/src/EvaluationTypes.d.ts
CHANGED
|
@@ -35,12 +35,12 @@ export type EvaluationDetails = {
|
|
|
35
35
|
reason: string;
|
|
36
36
|
lcut?: number;
|
|
37
37
|
receivedAt?: number;
|
|
38
|
-
warnings?:
|
|
38
|
+
warnings?: StatsigWarnings[];
|
|
39
39
|
bootstrapMetadata?: BootstrapMetadata;
|
|
40
40
|
};
|
|
41
41
|
export type DetailedStoreResult<T extends AnyEvaluation | ParamStoreConfig> = {
|
|
42
42
|
result: T | null;
|
|
43
43
|
details: EvaluationDetails;
|
|
44
44
|
};
|
|
45
|
-
export type
|
|
45
|
+
export type StatsigWarnings = 'PartialUserMatch' | 'StableIDMismatch' | 'MultipleInitializations' | 'NoCachedValues';
|
|
46
46
|
export {};
|
package/src/NetworkCore.d.ts
CHANGED
|
@@ -26,15 +26,17 @@ type NetworkResponse = {
|
|
|
26
26
|
};
|
|
27
27
|
export declare class NetworkCore {
|
|
28
28
|
private _emitter?;
|
|
29
|
+
protected _errorBoundary: ErrorBoundary | null;
|
|
29
30
|
private readonly _timeout;
|
|
30
31
|
private readonly _netConfig;
|
|
31
32
|
private readonly _options;
|
|
32
33
|
private readonly _fallbackResolver;
|
|
33
34
|
private _leakyBucket;
|
|
34
|
-
private
|
|
35
|
+
private _lastUsedInitUrl;
|
|
35
36
|
constructor(options: AnyStatsigOptions | null, _emitter?: StatsigClientEmitEventFunc | undefined);
|
|
36
37
|
setErrorBoundary(errorBoundary: ErrorBoundary): void;
|
|
37
38
|
isBeaconSupported(): boolean;
|
|
39
|
+
getLastUsedInitUrlAndReset(): string | null;
|
|
38
40
|
beacon(args: BeaconRequestArgs): Promise<boolean>;
|
|
39
41
|
post(args: RequestArgsWithData): Promise<NetworkResponse | null>;
|
|
40
42
|
get(args: RequestArgs): Promise<NetworkResponse | null>;
|
package/src/NetworkCore.js
CHANGED
|
@@ -33,11 +33,12 @@ const RETRYABLE_CODES = new Set([408, 500, 502, 503, 504, 522, 524, 599]);
|
|
|
33
33
|
class NetworkCore {
|
|
34
34
|
constructor(options, _emitter) {
|
|
35
35
|
this._emitter = _emitter;
|
|
36
|
+
this._errorBoundary = null;
|
|
36
37
|
this._timeout = DEFAULT_TIMEOUT_MS;
|
|
37
38
|
this._netConfig = {};
|
|
38
39
|
this._options = {};
|
|
39
40
|
this._leakyBucket = {};
|
|
40
|
-
this.
|
|
41
|
+
this._lastUsedInitUrl = null;
|
|
41
42
|
if (options) {
|
|
42
43
|
this._options = options;
|
|
43
44
|
}
|
|
@@ -59,6 +60,11 @@ class NetworkCore {
|
|
|
59
60
|
return (typeof navigator !== 'undefined' &&
|
|
60
61
|
typeof navigator.sendBeacon === 'function');
|
|
61
62
|
}
|
|
63
|
+
getLastUsedInitUrlAndReset() {
|
|
64
|
+
const tempUrl = this._lastUsedInitUrl;
|
|
65
|
+
this._lastUsedInitUrl = null;
|
|
66
|
+
return tempUrl;
|
|
67
|
+
}
|
|
62
68
|
beacon(args) {
|
|
63
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
70
|
if (!_ensureValidSdkKey(args)) {
|
|
@@ -86,7 +92,7 @@ class NetworkCore {
|
|
|
86
92
|
return this._sendRequest(argsInternal);
|
|
87
93
|
}
|
|
88
94
|
_sendRequest(args) {
|
|
89
|
-
var _a, _b, _c;
|
|
95
|
+
var _a, _b, _c, _d;
|
|
90
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
97
|
if (!_ensureValidSdkKey(args)) {
|
|
92
98
|
return null;
|
|
@@ -157,7 +163,9 @@ class NetworkCore {
|
|
|
157
163
|
tag: StatsigClientEventEmitter_1.ErrorTag.NetworkError,
|
|
158
164
|
requestArgs: args,
|
|
159
165
|
});
|
|
160
|
-
|
|
166
|
+
const formattedErrorMsg = `A networking error occurred during ${method} request to ${populatedUrl}.`;
|
|
167
|
+
Log_1.Log.error(formattedErrorMsg, errorMessage, error);
|
|
168
|
+
(_d = this._errorBoundary) === null || _d === void 0 ? void 0 : _d.attachErrorIfNoneExists(formattedErrorMsg);
|
|
161
169
|
return null;
|
|
162
170
|
}
|
|
163
171
|
yield _exponentialBackoff(currentAttempt);
|
|
@@ -187,6 +195,10 @@ class NetworkCore {
|
|
|
187
195
|
var _a;
|
|
188
196
|
return __awaiter(this, void 0, void 0, function* () {
|
|
189
197
|
const url = (_a = args.fallbackUrl) !== null && _a !== void 0 ? _a : args.urlConfig.getUrl();
|
|
198
|
+
if (args.urlConfig.endpoint === NetworkConfig_1.Endpoint._initialize ||
|
|
199
|
+
args.urlConfig.endpoint === NetworkConfig_1.Endpoint._download_config_specs) {
|
|
200
|
+
this._lastUsedInitUrl = url;
|
|
201
|
+
}
|
|
190
202
|
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);
|
|
191
203
|
const query = Object.keys(params)
|
|
192
204
|
.map((key) => {
|
|
@@ -8,6 +8,7 @@ import { AnyStatsigClientEvent, StatsigClientEventCallback, StatsigClientEventEm
|
|
|
8
8
|
import { DataAdapterResult, EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
|
|
9
9
|
import { StatsigEventInternal } from './StatsigEvent';
|
|
10
10
|
import { AnyStatsigOptions, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
|
|
11
|
+
import { StatsigUpdateDetails } from './StatsigUpdateDetails';
|
|
11
12
|
import { StorageProvider } from './StorageProvider';
|
|
12
13
|
export type StatsigClientEmitEventFunc = (event: AnyStatsigClientEvent) => void;
|
|
13
14
|
export type StatsigContext = {
|
|
@@ -25,7 +26,7 @@ export declare abstract class StatsigClientBase<TAdapter extends EvaluationsData
|
|
|
25
26
|
protected readonly _options: AnyStatsigOptions;
|
|
26
27
|
protected readonly _errorBoundary: ErrorBoundary;
|
|
27
28
|
protected readonly _logger: EventLogger;
|
|
28
|
-
protected _initializePromise: Promise<
|
|
29
|
+
protected _initializePromise: Promise<StatsigUpdateDetails> | null;
|
|
29
30
|
protected _memoCache: Record<string, unknown>;
|
|
30
31
|
private _listeners;
|
|
31
32
|
constructor(sdkKey: string, adapter: TAdapter, network: NetworkCore, options: AnyStatsigOptions | null);
|
package/src/StatsigMetadata.d.ts
CHANGED
package/src/StatsigMetadata.js
CHANGED
|
@@ -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.
|
|
4
|
+
exports.SDK_VERSION = '3.10.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
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StatsigWarnings } from './EvaluationTypes';
|
|
2
|
+
import { DataSource } from './StatsigDataAdapter';
|
|
3
|
+
export type StatsigUpdateDetails = {
|
|
4
|
+
duration: number;
|
|
5
|
+
source: DataSource;
|
|
6
|
+
success: boolean;
|
|
7
|
+
error: Error | null;
|
|
8
|
+
sourceUrl: string | null;
|
|
9
|
+
warnings?: StatsigWarnings[];
|
|
10
|
+
};
|
|
11
|
+
export declare const createUpdateDetails: (success: boolean, source: DataSource, initDuration: number, error: Error | null, sourceUrl: string | null, warnings?: StatsigWarnings[]) => StatsigUpdateDetails;
|
|
12
|
+
export declare const UPDATE_DETAIL_ERROR_MESSAGES: {
|
|
13
|
+
NO_NETWORK_DATA: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UPDATE_DETAIL_ERROR_MESSAGES = exports.createUpdateDetails = void 0;
|
|
4
|
+
const createUpdateDetails = (success, source, initDuration, error, sourceUrl, warnings) => {
|
|
5
|
+
return {
|
|
6
|
+
duration: initDuration,
|
|
7
|
+
source,
|
|
8
|
+
success,
|
|
9
|
+
error,
|
|
10
|
+
sourceUrl,
|
|
11
|
+
warnings,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
exports.createUpdateDetails = createUpdateDetails;
|
|
15
|
+
exports.UPDATE_DETAIL_ERROR_MESSAGES = {
|
|
16
|
+
NO_NETWORK_DATA: 'No data was returned from the network. This may be due to a network timeout if a timeout value was specified in the options or ad blocker error.',
|
|
17
|
+
};
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -62,5 +62,6 @@ __exportStar(require("./TypingUtils"), exports);
|
|
|
62
62
|
__exportStar(require("./UrlConfiguration"), exports);
|
|
63
63
|
__exportStar(require("./UUID"), exports);
|
|
64
64
|
__exportStar(require("./VisibilityObserving"), exports);
|
|
65
|
+
__exportStar(require("./StatsigUpdateDetails"), exports);
|
|
65
66
|
__STATSIG__ = Object.assign(Object.assign({}, (__STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {})), { Log: Log_1.Log,
|
|
66
67
|
SDK_VERSION: StatsigMetadata_1.SDK_VERSION });
|