@statsig/js-client 0.0.1-beta.24 → 0.0.1-beta.26
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/build/statsig-js-client+session-replay+web-analytics.min.js +1 -0
- package/build/statsig-js-client+web-analytics.min.js +1 -0
- package/build/statsig-js-client.min.js +1 -1
- package/package.json +2 -2
- package/src/StatsigClient.d.ts +105 -2
- package/src/StatsigClient.js +123 -19
- package/src/__tests__/MockLocalStorage.d.ts +0 -9
- package/src/__tests__/MockLocalStorage.js +0 -36
package/src/StatsigClient.js
CHANGED
|
@@ -15,6 +15,13 @@ const Network_1 = require("./Network");
|
|
|
15
15
|
const StatsigEvaluationsDataAdapter_1 = require("./StatsigEvaluationsDataAdapter");
|
|
16
16
|
require("./StatsigMetadataAdditions");
|
|
17
17
|
class StatsigClient extends client_core_1.StatsigClientBase {
|
|
18
|
+
/**
|
|
19
|
+
* StatsigClient constuctor
|
|
20
|
+
*
|
|
21
|
+
* @param {string} sdkKey A Statsig client SDK key. eg "client-xyz123..."
|
|
22
|
+
* @param {StatsigUser} user StatsigUser object containing various attributes related to a user.
|
|
23
|
+
* @param {StatsigOptions | null} options StatsigOptions, used to customize the behavior of the SDK.
|
|
24
|
+
*/
|
|
18
25
|
constructor(sdkKey, user, options = null) {
|
|
19
26
|
var _a;
|
|
20
27
|
const network = new Network_1.default(options, (e) => {
|
|
@@ -26,6 +33,14 @@ class StatsigClient extends client_core_1.StatsigClientBase {
|
|
|
26
33
|
this._store = new EvaluationStore_1.default();
|
|
27
34
|
this._user = user;
|
|
28
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Retrieves an instance of the StatsigClient based on the provided SDK key.
|
|
38
|
+
* If no SDK key is provided, the method returns the most recently created instance of the StatsigClient.
|
|
39
|
+
* The method ensures that each unique SDK key corresponds to a single instance of StatsigClient, effectively implementing a singleton pattern for each key.
|
|
40
|
+
*
|
|
41
|
+
* @param {string} [sdkKey] - Optional. The SDK key used to identify a specific instance of the StatsigClient. If omitted, the method returns the last created instance.
|
|
42
|
+
* @returns {StatsigClient|undefined} Returns the StatsigClient instance associated with the given SDK key, or undefined if no instance is associated with the key or if no key is provided and no instances exist.
|
|
43
|
+
*/
|
|
29
44
|
static instance(sdkKey) {
|
|
30
45
|
var _a;
|
|
31
46
|
__STATSIG__ = __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {};
|
|
@@ -34,12 +49,36 @@ class StatsigClient extends client_core_1.StatsigClientBase {
|
|
|
34
49
|
}
|
|
35
50
|
return (_a = __STATSIG__.instances) === null || _a === void 0 ? void 0 : _a[sdkKey];
|
|
36
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Initializes the StatsigClient using cached values. This method sets up the client synchronously by utilizing previously cached values.
|
|
54
|
+
* After initialization, cache values are updated in the background for future use, either in subsequent sessions or when `updateUser` is called.
|
|
55
|
+
* This is useful for quickly starting with the last-known-good configurations while refreshing data to keep settings up-to-date.
|
|
56
|
+
*
|
|
57
|
+
* @see {@link initializeAsync} for the asynchronous version of this method.
|
|
58
|
+
*/
|
|
37
59
|
initializeSync() {
|
|
38
60
|
this.updateUserSync(this._user);
|
|
39
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Initializes the StatsigClient asynchronously by first using cached values and then updating to the latest values from the network.
|
|
64
|
+
* Once the network values are fetched, they replace the existing cached values. If this method's promise is not awaited,
|
|
65
|
+
* there might be a transition from cached to network values during the session, which can affect consistency.
|
|
66
|
+
* This method is useful when it's acceptable to begin with potentially stale data and switch to the latest configuration as it becomes available.
|
|
67
|
+
*
|
|
68
|
+
* @returns {Promise<void>} A promise that resolves once the client is fully initialized with the latest values from the network.
|
|
69
|
+
* @see {@link initializeSync} for the synchronous version of this method.
|
|
70
|
+
*/
|
|
40
71
|
initializeAsync() {
|
|
41
72
|
return this.updateUserAsync(this._user);
|
|
42
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Synchronously updates the user in the Statsig client and switches the internal state to use cached values for the newly specified user.
|
|
76
|
+
* After the initial switch to cached values, this method updates these values in the background, preparing them for future sessions or subsequent calls to updateUser.
|
|
77
|
+
* This method ensures the client is quickly ready with available data.
|
|
78
|
+
*
|
|
79
|
+
* @param {StatsigUser} user - The new StatsigUser for which the client should update its internal state.
|
|
80
|
+
* @see {@link updateUserAsync} for the asynchronous version of this method.
|
|
81
|
+
*/
|
|
43
82
|
updateUserSync(user) {
|
|
44
83
|
this._resetForUser(user);
|
|
45
84
|
const result = this.dataAdapter.getDataSync(this._user);
|
|
@@ -48,6 +87,16 @@ class StatsigClient extends client_core_1.StatsigClientBase {
|
|
|
48
87
|
this._setStatus('Ready', result);
|
|
49
88
|
this._runPostUpdate(result !== null && result !== void 0 ? result : null, this._user);
|
|
50
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Asynchronously updates the user in the Statsig client by initially using cached values and then fetching the latest values from the network.
|
|
92
|
+
* When the latest values are fetched, they replace the cached values. If the promise returned by this method is not awaited,
|
|
93
|
+
* the client's state may shift from cached to updated network values during the session, potentially affecting consistency.
|
|
94
|
+
* This method is best used in scenarios where up-to-date configuration is critical and initial delays are acceptable.
|
|
95
|
+
*
|
|
96
|
+
* @param {StatsigUser} user - The new StatsigUser for which the client should update its internal state.
|
|
97
|
+
* @returns {Promise<void>} A promise that resolves once the client is fully updated with the latest network values.
|
|
98
|
+
* @see {@link updateUserSync} for the synchronous version of this method.
|
|
99
|
+
*/
|
|
51
100
|
updateUserAsync(user) {
|
|
52
101
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
102
|
this._resetForUser(user);
|
|
@@ -64,9 +113,12 @@ class StatsigClient extends client_core_1.StatsigClientBase {
|
|
|
64
113
|
this._setStatus('Ready', result);
|
|
65
114
|
});
|
|
66
115
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Retrieves a synchronous context containing data currently being used by the SDK. Represented as a {@link PrecomputedEvaluationsContext} object.
|
|
118
|
+
*
|
|
119
|
+
* @returns {PrecomputedEvaluationsContext} The current synchronous context for the this StatsigClient instance.
|
|
120
|
+
* @see {@link getAsyncContext} for the asynchronous version of the context that includes more information.
|
|
121
|
+
*/
|
|
70
122
|
getContext() {
|
|
71
123
|
return {
|
|
72
124
|
sdkKey: this._sdkKey,
|
|
@@ -75,51 +127,103 @@ class StatsigClient extends client_core_1.StatsigClientBase {
|
|
|
75
127
|
user: JSON.parse(JSON.stringify(this._user)),
|
|
76
128
|
};
|
|
77
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Asynchronously retrieves a context similar to that provided by {@link getContext}, but with additional properties fetched asynchronously, such as session and stable IDs. This is useful for situations where these IDs are required and are not immediately available.
|
|
132
|
+
*
|
|
133
|
+
* @returns {PrecomputedEvaluationsAsyncContext} An object containing the current values.
|
|
134
|
+
* @see {@link getContext} for the synchronous version of the context that this function extends.
|
|
135
|
+
*/
|
|
78
136
|
getAsyncContext() {
|
|
79
137
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
138
|
return Object.assign(Object.assign({}, this.getContext()), { sessionID: yield client_core_1.SessionID.get(this._sdkKey), stableID: yield client_core_1.StableID.get(this._sdkKey) });
|
|
81
139
|
});
|
|
82
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Retrieves the value of a feature gate for the current user, represented as a simple boolean.
|
|
143
|
+
*
|
|
144
|
+
* @param {string} name - The name of the feature gate to retrieve.
|
|
145
|
+
* @param {FeatureGateEvaluationOptions} [options] - Optional. Additional options to customize the method call.
|
|
146
|
+
* @returns {boolean} - The boolean value representing the gate's current evaluation results for the user.
|
|
147
|
+
*/
|
|
148
|
+
checkGate(name, options) {
|
|
149
|
+
return this.getFeatureGate(name, options).value;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Retrieves the value of a feature gate for the current user, represented as a {@link FeatureGate} object.
|
|
153
|
+
*
|
|
154
|
+
* @param {string} name - The name of the feature gate to retrieve.
|
|
155
|
+
* @param {FeatureGateEvaluationOptions} [options] - Optional. Additional options to customize the method call.
|
|
156
|
+
* @returns {FeatureGate} - The {@link FeatureGate} object representing the gate's current evaluation results for the user.
|
|
157
|
+
*/
|
|
83
158
|
getFeatureGate(name, options) {
|
|
84
159
|
var _a, _b;
|
|
85
160
|
const hash = (0, client_core_1.DJB2)(name);
|
|
86
161
|
const { evaluation, details } = this._store.getGate(hash);
|
|
87
|
-
const gate = (0, client_core_1.
|
|
162
|
+
const gate = (0, client_core_1._makeFeatureGate)(name, details, evaluation);
|
|
88
163
|
const overridden = (_b = (_a = this._overrideAdapter) === null || _a === void 0 ? void 0 : _a.getGateOverride) === null || _b === void 0 ? void 0 : _b.call(_a, gate, this._user, options);
|
|
89
164
|
const result = overridden !== null && overridden !== void 0 ? overridden : gate;
|
|
90
165
|
this._enqueueExposure(name, (0, client_core_1.createGateExposure)(this._user, result), options);
|
|
91
166
|
this._emit({ name: 'gate_evaluation', gate: result });
|
|
92
167
|
return result;
|
|
93
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Retrieves the value of a dynamic config for the current user.
|
|
171
|
+
*
|
|
172
|
+
* @param {string} name The name of the dynamic config to get.
|
|
173
|
+
* @param {DynamicConfigEvaluationOptions} [options] - Optional. Additional options to customize the method call.
|
|
174
|
+
* @returns {DynamicConfig} - The {@link DynamicConfig} object representing the dynamic configs's current evaluation results for the user.
|
|
175
|
+
*/
|
|
94
176
|
getDynamicConfig(name, options) {
|
|
95
177
|
const dynamicConfig = this._getConfigImpl('dynamic_config', name, options);
|
|
96
178
|
this._emit({ name: 'dynamic_config_evaluation', dynamicConfig });
|
|
97
179
|
return dynamicConfig;
|
|
98
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Retrieves the value of a experiment for the current user.
|
|
183
|
+
*
|
|
184
|
+
* @param {string} name The name of the experiment to get.
|
|
185
|
+
* @param {ExperimentEvaluationOptions} [options] - Optional. Additional options to customize the method call.
|
|
186
|
+
* @returns {Experiment} - The {@link Experiment} object representing the experiments's current evaluation results for the user.
|
|
187
|
+
*/
|
|
99
188
|
getExperiment(name, options) {
|
|
100
189
|
const experiment = this._getConfigImpl('experiment', name, options);
|
|
101
190
|
this._emit({ name: 'experiment_evaluation', experiment });
|
|
102
191
|
return experiment;
|
|
103
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Retrieves the value of a layer for the current user.
|
|
195
|
+
*
|
|
196
|
+
* @param {string} name The name of the layer to get.
|
|
197
|
+
* @param {LayerEvaluationOptions} [options] - Optional. Additional options to customize the method call.
|
|
198
|
+
* @returns {Layer} - The {@link Layer} object representing the layers's current evaluation results for the user.
|
|
199
|
+
*/
|
|
104
200
|
getLayer(name, options) {
|
|
105
|
-
var _a, _b;
|
|
201
|
+
var _a, _b, _c;
|
|
106
202
|
const hash = (0, client_core_1.DJB2)(name);
|
|
107
203
|
const { evaluation, details } = this._store.getLayer(hash);
|
|
108
|
-
const layer = (0, client_core_1.
|
|
204
|
+
const layer = (0, client_core_1._makeLayer)(name, details, evaluation);
|
|
109
205
|
const overridden = (_b = (_a = this._overrideAdapter) === null || _a === void 0 ? void 0 : _a.getLayerOverride) === null || _b === void 0 ? void 0 : _b.call(_a, layer, this._user, options);
|
|
110
|
-
const result = overridden !== null &&
|
|
206
|
+
const result = (0, client_core_1._mergeOverride)(layer, overridden, (_c = overridden === null || overridden === void 0 ? void 0 : overridden.__value) !== null && _c !== void 0 ? _c : layer.__value, (param) => {
|
|
207
|
+
this._enqueueExposure(name, (0, client_core_1.createLayerParameterExposure)(this._user, result, param), options);
|
|
208
|
+
});
|
|
111
209
|
this._emit({ name: 'layer_evaluation', layer: result });
|
|
112
|
-
return
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Logs an event to the internal logging system. This function allows logging by either passing a fully formed event object or by specifying the event name with optional value and metadata.
|
|
214
|
+
*
|
|
215
|
+
* @param {StatsigEvent|string} eventOrName - The event object conforming to the StatsigEvent interface, or the name of the event as a string.
|
|
216
|
+
* @param {string|number} value - Optional. The value associated with the event, which can be a string or a number. This parameter is ignored if the first parameter is a StatsigEvent object.
|
|
217
|
+
* @param {Record<string, string>} metadata - Optional. A key-value record containing metadata about the event. This is also ignored if the first parameter is an event object.
|
|
218
|
+
*/
|
|
219
|
+
logEvent(eventOrName, value, metadata) {
|
|
220
|
+
const event = typeof eventOrName === 'string'
|
|
221
|
+
? {
|
|
222
|
+
eventName: eventOrName,
|
|
223
|
+
value,
|
|
224
|
+
metadata,
|
|
225
|
+
}
|
|
226
|
+
: eventOrName;
|
|
123
227
|
this._logger.enqueue(Object.assign(Object.assign({}, event), { user: this._user, time: Date.now() }));
|
|
124
228
|
}
|
|
125
229
|
_runPostUpdate(current, user) {
|
|
@@ -136,7 +240,7 @@ class StatsigClient extends client_core_1.StatsigClientBase {
|
|
|
136
240
|
var _a, _b, _c, _d;
|
|
137
241
|
const hash = (0, client_core_1.DJB2)(name);
|
|
138
242
|
const { evaluation, details } = this._store.getConfig(hash);
|
|
139
|
-
const config = (0, client_core_1.
|
|
243
|
+
const config = (0, client_core_1._makeDynamicConfig)(name, details, evaluation);
|
|
140
244
|
const overridden = kind === 'experiment'
|
|
141
245
|
? (_b = (_a = this._overrideAdapter) === null || _a === void 0 ? void 0 : _a.getExperimentOverride) === null || _b === void 0 ? void 0 : _b.call(_a, config, this._user, options)
|
|
142
246
|
: (_d = (_c = this._overrideAdapter) === null || _c === void 0 ? void 0 : _c.getDynamicConfigOverride) === null || _d === void 0 ? void 0 : _d.call(_c, config, this._user, options);
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare class MockLocalStorage {
|
|
2
|
-
data: Record<string, string>;
|
|
3
|
-
static enabledMockStorage(): MockLocalStorage;
|
|
4
|
-
static disableMockStorage(): void;
|
|
5
|
-
clear(): void;
|
|
6
|
-
getItem(key: string): string | null;
|
|
7
|
-
setItem(key: string, value: string): void;
|
|
8
|
-
removeItem(key: string): void;
|
|
9
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MockLocalStorage = void 0;
|
|
4
|
-
const actualLocalStorage = window.localStorage;
|
|
5
|
-
// todo: move to test-helpers (break circular dep)
|
|
6
|
-
class MockLocalStorage {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.data = {};
|
|
9
|
-
}
|
|
10
|
-
static enabledMockStorage() {
|
|
11
|
-
const value = new MockLocalStorage();
|
|
12
|
-
Object.defineProperty(window, 'localStorage', {
|
|
13
|
-
value,
|
|
14
|
-
});
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
static disableMockStorage() {
|
|
18
|
-
Object.defineProperty(window, 'localStorage', {
|
|
19
|
-
value: actualLocalStorage,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
// LocalStorage Functions
|
|
23
|
-
clear() {
|
|
24
|
-
this.data = {};
|
|
25
|
-
}
|
|
26
|
-
getItem(key) {
|
|
27
|
-
return this.data[key] ? this.data[key] : null;
|
|
28
|
-
}
|
|
29
|
-
setItem(key, value) {
|
|
30
|
-
this.data[key] = String(value);
|
|
31
|
-
}
|
|
32
|
-
removeItem(key) {
|
|
33
|
-
delete this.data[key];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
exports.MockLocalStorage = MockLocalStorage;
|