@statsig/js-client 3.9.1 → 3.11.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.
@@ -1,10 +1,11 @@
1
- import { DataAdapterAsyncOptions, DataAdapterSyncOptions, EvaluationsDataAdapter, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, PrecomputedEvaluationsContext, PrecomputedEvaluationsInterface, StatsigClientBase, StatsigEvent, StatsigUser } from '@statsig/client-core';
1
+ import { DataAdapterAsyncOptions, DataAdapterSyncOptions, EvaluationsDataAdapter, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, PrecomputedEvaluationsContext, PrecomputedEvaluationsInterface, StatsigClientBase, StatsigEvent, StatsigUpdateDetails, StatsigUser } from '@statsig/client-core';
2
2
  import type { StatsigOptions } from './StatsigOptions';
3
3
  type AsyncUpdateOptions = DataAdapterAsyncOptions;
4
4
  type SyncUpdateOptions = DataAdapterSyncOptions;
5
5
  export default class StatsigClient extends StatsigClientBase<EvaluationsDataAdapter> implements PrecomputedEvaluationsInterface {
6
6
  private _store;
7
7
  private _user;
8
+ private _network;
8
9
  /**
9
10
  * Retrieves an instance of the StatsigClient based on the provided SDK key.
10
11
  * If no SDK key is provided, the method returns the most recently created instance of the StatsigClient.
@@ -29,7 +30,7 @@ export default class StatsigClient extends StatsigClientBase<EvaluationsDataAdap
29
30
  *
30
31
  * @see {@link initializeAsync} for the asynchronous version of this method.
31
32
  */
32
- initializeSync(options?: SyncUpdateOptions): void;
33
+ initializeSync(options?: SyncUpdateOptions): StatsigUpdateDetails;
33
34
  /**
34
35
  * Initializes the StatsigClient asynchronously by first using cached values and then updating to the latest values from the network.
35
36
  * Once the network values are fetched, they replace the existing cached values. If this method's promise is not awaited,
@@ -40,7 +41,7 @@ export default class StatsigClient extends StatsigClientBase<EvaluationsDataAdap
40
41
  * @returns {Promise<void>} A promise that resolves once the client is fully initialized with the latest values from the network or a timeout (if set) is hit.
41
42
  * @see {@link initializeSync} for the synchronous version of this method.
42
43
  */
43
- initializeAsync(options?: AsyncUpdateOptions): Promise<void>;
44
+ initializeAsync(options?: AsyncUpdateOptions): Promise<StatsigUpdateDetails>;
44
45
  /**
45
46
  * Synchronously updates the user in the Statsig client and switches the internal state to use cached values for the newly specified user.
46
47
  * 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.
@@ -49,7 +50,7 @@ export default class StatsigClient extends StatsigClientBase<EvaluationsDataAdap
49
50
  * @param {StatsigUser} user - The new StatsigUser for which the client should update its internal state.
50
51
  * @see {@link updateUserAsync} for the asynchronous version of this method.
51
52
  */
52
- updateUserSync(user: StatsigUser, options?: SyncUpdateOptions): void;
53
+ updateUserSync(user: StatsigUser, options?: SyncUpdateOptions): StatsigUpdateDetails;
53
54
  /**
54
55
  * Asynchronously updates the user in the Statsig client by initially using cached values and then fetching the latest values from the network.
55
56
  * When the latest values are fetched, they replace the cached values. If the promise returned by this method is not awaited,
@@ -61,7 +62,7 @@ export default class StatsigClient extends StatsigClientBase<EvaluationsDataAdap
61
62
  * @returns {Promise<void>} A promise that resolves once the client is fully updated with the latest values from the network or a timeout (if set) is hit.
62
63
  * @see {@link updateUserSync} for the synchronous version of this method.
63
64
  */
64
- updateUserAsync(user: StatsigUser, options?: AsyncUpdateOptions): Promise<void>;
65
+ updateUserAsync(user: StatsigUser, options?: AsyncUpdateOptions): Promise<StatsigUpdateDetails>;
65
66
  /**
66
67
  * Retrieves a synchronous context containing data currently being used by the SDK. Represented as a {@link PrecomputedEvaluationsContext} object.
67
68
  *
@@ -54,7 +54,7 @@ class StatsigClient extends client_core_1.StatsigClientBase {
54
54
  * @param {FeatureGateEvaluationOptions} [options] - Optional. Additional options to customize the method call.
55
55
  * @returns {FeatureGate} - The {@link FeatureGate} object representing the gate's current evaluation results for the user.
56
56
  */
57
- this.getFeatureGate = this._memoize(this._getFeatureGateImpl.bind(this));
57
+ this.getFeatureGate = this._memoize(client_core_1.MemoPrefix._gate, this._getFeatureGateImpl.bind(this));
58
58
  /**
59
59
  * Retrieves the value of a dynamic config for the current user.
60
60
  *
@@ -62,7 +62,7 @@ class StatsigClient extends client_core_1.StatsigClientBase {
62
62
  * @param {DynamicConfigEvaluationOptions} [options] - Optional. Additional options to customize the method call.
63
63
  * @returns {DynamicConfig} - The {@link DynamicConfig} object representing the dynamic configs's current evaluation results for the user.
64
64
  */
65
- this.getDynamicConfig = this._memoize(this._getDynamicConfigImpl.bind(this));
65
+ this.getDynamicConfig = this._memoize(client_core_1.MemoPrefix._dynamicConfig, this._getDynamicConfigImpl.bind(this));
66
66
  /**
67
67
  * Retrieves the value of a experiment for the current user.
68
68
  *
@@ -70,7 +70,7 @@ class StatsigClient extends client_core_1.StatsigClientBase {
70
70
  * @param {ExperimentEvaluationOptions} [options] - Optional. Additional options to customize the method call.
71
71
  * @returns {Experiment} - The {@link Experiment} object representing the experiments's current evaluation results for the user.
72
72
  */
73
- this.getExperiment = this._memoize(this._getExperimentImpl.bind(this));
73
+ this.getExperiment = this._memoize(client_core_1.MemoPrefix._experiment, this._getExperimentImpl.bind(this));
74
74
  /**
75
75
  * Retrieves the value of a layer for the current user.
76
76
  *
@@ -78,7 +78,7 @@ class StatsigClient extends client_core_1.StatsigClientBase {
78
78
  * @param {LayerEvaluationOptions} [options] - Optional. Additional options to customize the method call.
79
79
  * @returns {Layer} - The {@link Layer} object representing the layers's current evaluation results for the user.
80
80
  */
81
- this.getLayer = this._memoize(this._getLayerImpl.bind(this));
81
+ this.getLayer = this._memoize(client_core_1.MemoPrefix._layer, this._getLayerImpl.bind(this));
82
82
  /**
83
83
  * Retrieves the value of a parameter store for the current user.
84
84
  *
@@ -86,8 +86,9 @@ class StatsigClient extends client_core_1.StatsigClientBase {
86
86
  * @param {ParameterStoreEvaluationOptions} [options] - Optional. Additional options to customize the method call.
87
87
  * @returns {ParameterStore} - The {@link ParameterStore} object representing the parameter store's current mappings for the user.
88
88
  */
89
- this.getParameterStore = this._memoize(this._getParameterStoreImpl.bind(this));
89
+ this.getParameterStore = this._memoize(client_core_1.MemoPrefix._paramStore, this._getParameterStoreImpl.bind(this));
90
90
  this._store = new EvaluationStore_1.default(sdkKey);
91
+ this._network = network;
91
92
  this._user = this._configureUser(user, options);
92
93
  const plugins = (_b = options === null || options === void 0 ? void 0 : options.plugins) !== null && _b !== void 0 ? _b : [];
93
94
  for (const plugin of plugins) {
@@ -102,11 +103,12 @@ class StatsigClient extends client_core_1.StatsigClientBase {
102
103
  * @see {@link initializeAsync} for the asynchronous version of this method.
103
104
  */
104
105
  initializeSync(options) {
106
+ var _a;
105
107
  if (this.loadingStatus !== 'Uninitialized') {
106
- return;
108
+ return (0, client_core_1.createUpdateDetails)(true, this._store.getSource(), -1, null, null, ['MultipleInitializations', ...((_a = this._store.getWarnings()) !== null && _a !== void 0 ? _a : [])]);
107
109
  }
108
110
  this._logger.start();
109
- this.updateUserSync(this._user, options);
111
+ return this.updateUserSync(this._user, options);
110
112
  }
111
113
  /**
112
114
  * Initializes the StatsigClient asynchronously by first using cached values and then updating to the latest values from the network.
@@ -136,16 +138,23 @@ class StatsigClient extends client_core_1.StatsigClientBase {
136
138
  * @see {@link updateUserAsync} for the asynchronous version of this method.
137
139
  */
138
140
  updateUserSync(user, options) {
141
+ var _a;
142
+ const startTime = performance.now();
143
+ const warnings = [...((_a = this._store.getWarnings()) !== null && _a !== void 0 ? _a : [])];
139
144
  this._resetForUser(user);
140
145
  const result = this.dataAdapter.getDataSync(this._user);
146
+ if (result == null) {
147
+ warnings.push('NoCachedValues');
148
+ }
141
149
  this._store.setValues(result, this._user);
142
150
  this._finalizeUpdate(result);
143
151
  const disable = options === null || options === void 0 ? void 0 : options.disableBackgroundCacheRefresh;
144
152
  if (disable === true ||
145
153
  (disable == null && (result === null || result === void 0 ? void 0 : result.source) === 'Bootstrap')) {
146
- return;
154
+ return (0, client_core_1.createUpdateDetails)(true, this._store.getSource(), performance.now() - startTime, this._errorBoundary.getLastSeenErrorAndReset(), this._network.getLastUsedInitUrlAndReset(), warnings);
147
155
  }
148
156
  this._runPostUpdate(result !== null && result !== void 0 ? result : null, this._user);
157
+ return (0, client_core_1.createUpdateDetails)(true, this._store.getSource(), performance.now() - startTime, this._errorBoundary.getLastSeenErrorAndReset(), this._network.getLastUsedInitUrlAndReset(), warnings);
149
158
  }
150
159
  /**
151
160
  * Asynchronously updates the user in the Statsig client by initially using cached values and then fetching the latest values from the network.
@@ -169,7 +178,7 @@ class StatsigClient extends client_core_1.StatsigClientBase {
169
178
  result = yield this.dataAdapter.getDataAsync(result, initiator, options);
170
179
  // ensure the user hasn't changed while we were waiting
171
180
  if (initiator !== this._user) {
172
- return;
181
+ return (0, client_core_1.createUpdateDetails)(false, this._store.getSource(), -1, new Error('User changed during update'), this._network.getLastUsedInitUrlAndReset());
173
182
  }
174
183
  let isUsingNetworkValues = false;
175
184
  if (result != null) {
@@ -181,10 +190,12 @@ class StatsigClient extends client_core_1.StatsigClientBase {
181
190
  }
182
191
  this._finalizeUpdate(result);
183
192
  if (!isUsingNetworkValues) {
193
+ this._errorBoundary.attachErrorIfNoneExists(client_core_1.UPDATE_DETAIL_ERROR_MESSAGES.NO_NETWORK_DATA);
184
194
  this.$emt({ name: 'initialization_failure' });
185
195
  }
186
196
  client_core_1.Diagnostics._markInitOverallEnd(this._sdkKey, isUsingNetworkValues, this._store.getCurrentSourceDetails());
187
- client_core_1.Diagnostics._enqueueDiagnosticsEvent(this._user, this._logger, this._sdkKey, this._options);
197
+ const initDuration = client_core_1.Diagnostics._enqueueDiagnosticsEvent(this._user, this._logger, this._sdkKey, this._options);
198
+ return (0, client_core_1.createUpdateDetails)(isUsingNetworkValues, this._store.getSource(), initDuration, this._errorBoundary.getLastSeenErrorAndReset(), this._network.getLastUsedInitUrlAndReset(), this._store.getWarnings());
188
199
  });
189
200
  }
190
201
  /**