@statsig/client-core 0.0.1-beta.4 → 0.0.1-beta.40

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 (73) hide show
  1. package/README.md +1 -4
  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 +50 -14
  6. package/src/DataAdapterCore.d.ts +30 -0
  7. package/src/DataAdapterCore.js +169 -0
  8. package/src/Diagnostics.d.ts +1 -3
  9. package/src/Diagnostics.js +4 -49
  10. package/src/DownloadConfigSpecsResponse.d.ts +41 -0
  11. package/src/ErrorBoundary.d.ts +7 -2
  12. package/src/ErrorBoundary.js +79 -87
  13. package/src/EvaluationOptions.d.ts +20 -0
  14. package/src/EvaluationOptions.js +2 -0
  15. package/src/EvaluationTypes.d.ts +39 -0
  16. package/src/EvaluationTypes.js +2 -0
  17. package/src/EventLogger.d.ts +20 -9
  18. package/src/EventLogger.js +216 -232
  19. package/src/Hashing.d.ts +2 -1
  20. package/src/Hashing.js +25 -6
  21. package/src/InitializeResponse.d.ts +18 -0
  22. package/src/InitializeResponse.js +2 -0
  23. package/src/Log.js +15 -34
  24. package/src/NetworkConfig.d.ts +18 -0
  25. package/src/NetworkConfig.js +18 -0
  26. package/src/NetworkCore.d.ts +19 -6
  27. package/src/NetworkCore.js +137 -167
  28. package/src/OverrideAdapter.d.ts +9 -0
  29. package/src/OverrideAdapter.js +2 -0
  30. package/src/SDKType.d.ts +8 -0
  31. package/src/SDKType.js +19 -0
  32. package/src/SafeJs.d.ts +6 -0
  33. package/src/SafeJs.js +41 -0
  34. package/src/SessionID.d.ts +17 -1
  35. package/src/SessionID.js +89 -8
  36. package/src/StableID.js +24 -53
  37. package/src/StatsigClientBase.d.ts +57 -28
  38. package/src/StatsigClientBase.js +115 -238
  39. package/src/StatsigClientEventEmitter.d.ts +69 -28
  40. package/src/StatsigDataAdapter.d.ts +107 -0
  41. package/src/StatsigDataAdapter.js +4 -0
  42. package/src/StatsigEvent.d.ts +10 -19
  43. package/src/StatsigEvent.js +50 -41
  44. package/src/StatsigMetadata.d.ts +1 -1
  45. package/src/StatsigMetadata.js +7 -18
  46. package/src/StatsigOptionsCommon.d.ts +85 -17
  47. package/src/StatsigTypeFactories.d.ts +6 -0
  48. package/src/StatsigTypeFactories.js +50 -0
  49. package/src/StatsigTypes.d.ts +29 -18
  50. package/src/StatsigTypes.js +0 -29
  51. package/src/StatsigUser.d.ts +2 -5
  52. package/src/StatsigUser.js +10 -18
  53. package/src/StorageProvider.d.ts +13 -8
  54. package/src/StorageProvider.js +77 -73
  55. package/src/TypedJsonParse.d.ts +8 -0
  56. package/src/TypedJsonParse.js +27 -0
  57. package/src/UUID.js +9 -5
  58. package/src/UrlOverrides.d.ts +1 -0
  59. package/src/UrlOverrides.js +15 -0
  60. package/src/UtitlityTypes.d.ts +3 -0
  61. package/src/UtitlityTypes.js +2 -0
  62. package/src/VisibilityObserving.d.ts +8 -0
  63. package/src/VisibilityObserving.js +30 -0
  64. package/src/index.d.ts +20 -5
  65. package/src/index.js +30 -18
  66. package/src/Monitoring.d.ts +0 -3
  67. package/src/Monitoring.js +0 -33
  68. package/src/StatsigDataProvider.d.ts +0 -9
  69. package/src/VisibilityChangeObserver.d.ts +0 -13
  70. package/src/VisibilityChangeObserver.js +0 -48
  71. package/src/__tests__/MockLocalStorage.d.ts +0 -9
  72. package/src/__tests__/MockLocalStorage.js +0 -37
  73. /package/src/{StatsigDataProvider.js → DownloadConfigSpecsResponse.js} +0 -0
package/src/StableID.js CHANGED
@@ -8,71 +8,42 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- 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;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
11
  Object.defineProperty(exports, "__esModule", { value: true });
39
12
  exports.StableID = void 0;
40
- var Hashing_1 = require("./Hashing");
41
- var Log_1 = require("./Log");
42
- var StorageProvider_1 = require("./StorageProvider");
43
- var UUID_1 = require("./UUID");
44
- var PROMISE_MAP = {};
13
+ const Hashing_1 = require("./Hashing");
14
+ const Log_1 = require("./Log");
15
+ const StorageProvider_1 = require("./StorageProvider");
16
+ const UUID_1 = require("./UUID");
17
+ const PROMISE_MAP = {};
45
18
  exports.StableID = {
46
- get: function (sdkKey) { return __awaiter(void 0, void 0, void 0, function () {
47
- return __generator(this, function (_a) {
48
- if (PROMISE_MAP[sdkKey] == null) {
49
- PROMISE_MAP[sdkKey] = _loadFromStorage(sdkKey).then(function (stableID) {
50
- if (stableID != null) {
51
- return stableID;
52
- }
53
- var newStableID = (0, UUID_1.getUUID)();
54
- _persistToStorage(newStableID, sdkKey);
55
- return newStableID;
56
- });
57
- }
58
- return [2 /*return*/, PROMISE_MAP[sdkKey]];
59
- });
60
- }); },
61
- setOverride: function (override, sdkKey) {
19
+ get: (sdkKey) => __awaiter(void 0, void 0, void 0, function* () {
20
+ if (PROMISE_MAP[sdkKey] == null) {
21
+ PROMISE_MAP[sdkKey] = _loadFromStorage(sdkKey).then((stableID) => {
22
+ if (stableID != null) {
23
+ return stableID;
24
+ }
25
+ const newStableID = (0, UUID_1.getUUID)();
26
+ _persistToStorage(newStableID, sdkKey);
27
+ return newStableID;
28
+ });
29
+ }
30
+ return PROMISE_MAP[sdkKey];
31
+ }),
32
+ setOverride: (override, sdkKey) => {
62
33
  PROMISE_MAP[sdkKey] = Promise.resolve(override);
63
34
  _persistToStorage(override, sdkKey);
64
35
  },
65
36
  };
66
37
  function _getStableIDStorageKey(sdkKey) {
67
- return "statsig.stable_id:".concat((0, Hashing_1.DJB2)(sdkKey));
38
+ return `statsig.stable_id.${(0, Hashing_1.DJB2)(sdkKey)}`;
68
39
  }
69
40
  function _persistToStorage(stableID, sdkKey) {
70
- var storageKey = _getStableIDStorageKey(sdkKey);
71
- (0, StorageProvider_1.setObjectInStorage)(storageKey, stableID).catch(function () {
41
+ const storageKey = _getStableIDStorageKey(sdkKey);
42
+ (0, StorageProvider_1._setObjectInStorage)(storageKey, stableID).catch(() => {
72
43
  Log_1.Log.warn('Failed to save StableID');
73
44
  });
74
45
  }
75
46
  function _loadFromStorage(sdkKey) {
76
- var storageKey = _getStableIDStorageKey(sdkKey);
77
- return (0, StorageProvider_1.getObjectFromStorage)(storageKey);
47
+ const storageKey = _getStableIDStorageKey(sdkKey);
48
+ return (0, StorageProvider_1._getObjectFromStorage)(storageKey);
78
49
  }
@@ -1,37 +1,66 @@
1
1
  import './$_StatsigGlobal';
2
2
  import { ErrorBoundary } from './ErrorBoundary';
3
+ import { EvaluationOptionsCommon } from './EvaluationOptions';
3
4
  import { EventLogger } from './EventLogger';
4
5
  import { NetworkCore } from './NetworkCore';
5
- import { StatsigClientEvent, StatsigClientEventCallback, StatsigClientEventData, StatsigClientEventEmitterInterface, StatsigLoadingStatus } from './StatsigClientEventEmitter';
6
- import { DataSource, StatsigDataProvider } from './StatsigDataProvider';
6
+ import { OverrideAdapter } from './OverrideAdapter';
7
+ import { AnyStatsigClientEvent, StatsigClientEventCallback, StatsigClientEventEmitterInterface, StatsigClientEventName, StatsigLoadingStatus } from './StatsigClientEventEmitter';
8
+ import { DataAdapterResult, EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
7
9
  import { StatsigEventInternal } from './StatsigEvent';
8
- import { StatsigOptionsCommon } from './StatsigOptionsCommon';
9
- import { StatsigUser } from './StatsigUser';
10
- type DataProviderResult = {
11
- data: string | null;
12
- source: DataSource;
10
+ import { AnyStatsigOptions, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
11
+ export type StatsigClientEmitEventFunc = (event: AnyStatsigClientEvent) => void;
12
+ export type StatsigContext = {
13
+ sdkKey: string;
14
+ options: AnyStatsigOptions;
15
+ sessionID: string;
16
+ values: unknown;
13
17
  };
14
- export type EvaluationOptions = {
15
- disableExposureLog?: boolean;
16
- };
17
- export declare const DEFAULT_EVAL_OPTIONS: EvaluationOptions;
18
- export type StatsigClientEmitEventFunc = (data: StatsigClientEventData) => void;
19
- export declare class StatsigClientBase implements StatsigClientEventEmitterInterface {
18
+ export declare abstract class StatsigClientBase<TAdapter extends EvaluationsDataAdapter | SpecsDataAdapter> implements StatsigClientEventEmitterInterface {
20
19
  loadingStatus: StatsigLoadingStatus;
21
- protected _errorBoundary: ErrorBoundary;
22
- protected _logger: EventLogger;
23
- protected _sdkKey: string;
24
- protected _dataProviders: StatsigDataProvider[];
20
+ readonly dataAdapter: TAdapter;
21
+ protected readonly _sdkKey: string;
22
+ protected readonly _options: AnyStatsigOptions;
23
+ protected readonly _errorBoundary: ErrorBoundary;
24
+ protected readonly _logger: EventLogger;
25
+ protected readonly _overrideAdapter: OverrideAdapter | null;
25
26
  private _listeners;
26
- constructor(sdkKey: string, network: NetworkCore, options: StatsigOptionsCommon | null, dataProviders: StatsigDataProvider[]);
27
- on(event: StatsigClientEvent | '*', listener: StatsigClientEventCallback): void;
28
- off(event: StatsigClientEvent | '*', listener: StatsigClientEventCallback): void;
29
- protected emit(data: StatsigClientEventData): void;
30
- protected _setStatus(newStatus: StatsigLoadingStatus): void;
31
- protected _getDataFromProviders(user?: StatsigUser): DataProviderResult;
32
- protected _getDataFromProvidersAsync(user?: StatsigUser): Promise<DataProviderResult>;
33
- protected _getDataPostInitFromProviders(currentData: string | null, user?: StatsigUser): Promise<DataProviderResult>;
34
- protected _saveToDataProviders(currentData: string | null, user?: StatsigUser): void;
35
- protected _enqueueExposure(options: EvaluationOptions, exposure: StatsigEventInternal): void;
27
+ constructor(sdkKey: string, adapter: TAdapter, network: NetworkCore, options: AnyStatsigOptions | null);
28
+ /**
29
+ * Updates runtime configuration options for the SDK, allowing toggling of certain behaviors such as logging and storage to comply with user preferences or regulations such as GDPR.
30
+ *
31
+ * @param {StatsigRuntimeMutableOptions} options - The configuration options that dictate the runtime behavior of the SDK.
32
+ */
33
+ updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
34
+ /**
35
+ * Flushes any currently queued events.
36
+ */
37
+ flush(): Promise<void>;
38
+ /**
39
+ * Gracefully shuts down the SDK, ensuring that all pending events are send before the SDK stops.
40
+ * This function emits a 'pre_shutdown' event and then waits for the logger to complete its shutdown process.
41
+ *
42
+ * @returns {Promise<void>} A promise that resolves when all shutdown procedures, including logging shutdown, have been completed.
43
+ */
44
+ shutdown(): Promise<void>;
45
+ /**
46
+ * Subscribes a callback function to a specific {@link StatsigClientEvent} or all StatsigClientEvents if the wildcard '*' is used.
47
+ * Once subscribed, the listener callback will be invoked whenever the specified event is emitted.
48
+ *
49
+ * @param {StatsigClientEventName} event - The name of the event to subscribe to, or '*' to subscribe to all events.
50
+ * @param {StatsigClientEventCallback<T>} listener - The callback function to execute when the event occurs. The function receives event-specific data as its parameter.
51
+ * @see {@link off} for unsubscribing from events.
52
+ */
53
+ on<T extends StatsigClientEventName>(event: T, listener: StatsigClientEventCallback<T>): void;
54
+ /**
55
+ * Unsubscribes a previously registered callback function from a specific {@link StatsigClientEvent} or all StatsigClientEvents if the wildcard '*' is used.
56
+ *
57
+ * @param {StatsigClientEventName} event - The name of the event from which to unsubscribe, or '*' to unsubscribe from all events.
58
+ * @param {StatsigClientEventCallback<T>} listener - The callback function to remove from the event's notification list.
59
+ * @see {@link on} for subscribing to events.
60
+ */
61
+ off<T extends StatsigClientEventName>(event: T, listener: StatsigClientEventCallback<T>): void;
62
+ $on<T extends StatsigClientEventName>(event: T, listener: StatsigClientEventCallback<T>): void;
63
+ $emt(event: AnyStatsigClientEvent): void;
64
+ protected _setStatus(newStatus: StatsigLoadingStatus, values: DataAdapterResult | null): void;
65
+ protected _enqueueExposure(name: string, exposure: StatsigEventInternal, options?: EvaluationOptionsCommon): void;
36
66
  }
37
- export {};
@@ -8,265 +8,142 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- 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;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- var __asyncValues = (this && this.__asyncValues) || function (o) {
39
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
40
- var m = o[Symbol.asyncIterator], i;
41
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
42
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
43
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
44
- };
45
11
  Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.StatsigClientBase = exports.DEFAULT_EVAL_OPTIONS = void 0;
12
+ exports.StatsigClientBase = void 0;
47
13
  require("./$_StatsigGlobal");
48
- var ErrorBoundary_1 = require("./ErrorBoundary");
49
- var EventLogger_1 = require("./EventLogger");
50
- var Log_1 = require("./Log");
51
- var StableID_1 = require("./StableID");
52
- exports.DEFAULT_EVAL_OPTIONS = {
53
- disableExposureLog: false,
54
- };
55
- var StatsigClientBase = /** @class */ (function () {
56
- function StatsigClientBase(sdkKey, network, options, dataProviders) {
14
+ const __StatsigGlobal_1 = require("./$_StatsigGlobal");
15
+ const ErrorBoundary_1 = require("./ErrorBoundary");
16
+ const EventLogger_1 = require("./EventLogger");
17
+ const Log_1 = require("./Log");
18
+ const SafeJs_1 = require("./SafeJs");
19
+ const StableID_1 = require("./StableID");
20
+ const StorageProvider_1 = require("./StorageProvider");
21
+ class StatsigClientBase {
22
+ constructor(sdkKey, adapter, network, options) {
57
23
  var _a, _b;
58
24
  this.loadingStatus = 'Uninitialized';
59
25
  this._listeners = {};
60
- this._logger = new EventLogger_1.EventLogger(sdkKey, this.emit.bind(this), network, options);
61
- this._sdkKey = sdkKey;
62
- this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(sdkKey);
63
- if (options === null || options === void 0 ? void 0 : options.overrideStableID) {
26
+ const emitter = this.$emt.bind(this);
27
+ const statsigGlobal = (0, __StatsigGlobal_1._getStatsigGlobal)();
28
+ const instances = (_a = statsigGlobal.instances) !== null && _a !== void 0 ? _a : {};
29
+ const inst = this;
30
+ (options === null || options === void 0 ? void 0 : options.logLevel) && (Log_1.Log.level = options === null || options === void 0 ? void 0 : options.logLevel);
31
+ (options === null || options === void 0 ? void 0 : options.disableStorage) && StorageProvider_1.Storage._setDisabled(true);
32
+ (options === null || options === void 0 ? void 0 : options.overrideStableID) &&
64
33
  StableID_1.StableID.setOverride(options.overrideStableID, sdkKey);
34
+ this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(sdkKey, options, emitter);
35
+ this._errorBoundary.wrap(this);
36
+ this._errorBoundary.wrap(network);
37
+ this._errorBoundary.wrap(adapter);
38
+ this._sdkKey = sdkKey;
39
+ this._options = options !== null && options !== void 0 ? options : {};
40
+ this._overrideAdapter = (_b = options === null || options === void 0 ? void 0 : options.overrideAdapter) !== null && _b !== void 0 ? _b : null;
41
+ this._logger = new EventLogger_1.EventLogger(sdkKey, emitter, network, options);
42
+ if (instances[sdkKey] != null && (0, SafeJs_1._isBrowserEnv)()) {
43
+ Log_1.Log.warn('Creating multiple Statsig clients with the same SDK key can lead to unexpected behavior. Multi-instance support requires different SDK keys.');
44
+ }
45
+ instances[sdkKey] = inst;
46
+ statsigGlobal.lastInstance = inst;
47
+ statsigGlobal.instances = instances;
48
+ __STATSIG__ = statsigGlobal;
49
+ this.dataAdapter = adapter;
50
+ this.dataAdapter.attach(sdkKey, options);
51
+ }
52
+ /**
53
+ * Updates runtime configuration options for the SDK, allowing toggling of certain behaviors such as logging and storage to comply with user preferences or regulations such as GDPR.
54
+ *
55
+ * @param {StatsigRuntimeMutableOptions} options - The configuration options that dictate the runtime behavior of the SDK.
56
+ */
57
+ updateRuntimeOptions(options) {
58
+ if (options.disableLogging != null) {
59
+ this._options.disableLogging = options.disableLogging;
60
+ this._logger.setLoggingDisabled(options.disableLogging);
61
+ }
62
+ if (options.disableStorage != null) {
63
+ this._options.disableStorage = options.disableStorage;
64
+ StorageProvider_1.Storage._setDisabled(options.disableStorage);
65
65
  }
66
- __STATSIG__ = __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {};
67
- var instances = (_a = __STATSIG__.instances) !== null && _a !== void 0 ? _a : new Set();
68
- instances.add(this);
69
- __STATSIG__.instances = instances;
70
- Log_1.Log.level = (_b = options === null || options === void 0 ? void 0 : options.logLevel) !== null && _b !== void 0 ? _b : Log_1.LogLevel.Warn;
71
- this._dataProviders = dataProviders;
72
66
  }
73
- StatsigClientBase.prototype.on = function (event, listener) {
67
+ /**
68
+ * Flushes any currently queued events.
69
+ */
70
+ flush() {
71
+ return this._logger.flush();
72
+ }
73
+ /**
74
+ * Gracefully shuts down the SDK, ensuring that all pending events are send before the SDK stops.
75
+ * This function emits a 'pre_shutdown' event and then waits for the logger to complete its shutdown process.
76
+ *
77
+ * @returns {Promise<void>} A promise that resolves when all shutdown procedures, including logging shutdown, have been completed.
78
+ */
79
+ shutdown() {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ this.$emt({ name: 'pre_shutdown' });
82
+ yield this._logger.shutdown();
83
+ });
84
+ }
85
+ /**
86
+ * Subscribes a callback function to a specific {@link StatsigClientEvent} or all StatsigClientEvents if the wildcard '*' is used.
87
+ * Once subscribed, the listener callback will be invoked whenever the specified event is emitted.
88
+ *
89
+ * @param {StatsigClientEventName} event - The name of the event to subscribe to, or '*' to subscribe to all events.
90
+ * @param {StatsigClientEventCallback<T>} listener - The callback function to execute when the event occurs. The function receives event-specific data as its parameter.
91
+ * @see {@link off} for unsubscribing from events.
92
+ */
93
+ on(event, listener) {
74
94
  if (!this._listeners[event]) {
75
95
  this._listeners[event] = [];
76
96
  }
77
97
  this._listeners[event].push(listener);
78
- };
79
- StatsigClientBase.prototype.off = function (event, listener) {
98
+ }
99
+ /**
100
+ * Unsubscribes a previously registered callback function from a specific {@link StatsigClientEvent} or all StatsigClientEvents if the wildcard '*' is used.
101
+ *
102
+ * @param {StatsigClientEventName} event - The name of the event from which to unsubscribe, or '*' to unsubscribe from all events.
103
+ * @param {StatsigClientEventCallback<T>} listener - The callback function to remove from the event's notification list.
104
+ * @see {@link on} for subscribing to events.
105
+ */
106
+ off(event, listener) {
80
107
  if (this._listeners[event]) {
81
- var index = this._listeners[event].indexOf(listener);
108
+ const index = this._listeners[event].indexOf(listener);
82
109
  if (index !== -1) {
83
110
  this._listeners[event].splice(index, 1);
84
111
  }
85
112
  }
86
- };
87
- StatsigClientBase.prototype.emit = function (data) {
88
- var _a;
89
- if (this._listeners[data.event]) {
90
- this._listeners[data.event].forEach(function (listener) { return listener(data); });
91
- }
92
- (_a = this._listeners['*']) === null || _a === void 0 ? void 0 : _a.forEach(function (listener) { return listener(data); });
93
- };
94
- StatsigClientBase.prototype._setStatus = function (newStatus) {
95
- this.loadingStatus = newStatus;
96
- this.emit({ event: 'status_change', loadingStatus: newStatus });
97
- };
98
- StatsigClientBase.prototype._getDataFromProviders = function (user) {
113
+ }
114
+ $on(event, listener) {
115
+ listener.__isInternal = true;
116
+ this.on(event, listener);
117
+ }
118
+ $emt(event) {
99
119
  var _a;
100
- for (var _i = 0, _b = this._dataProviders; _i < _b.length; _i++) {
101
- var provider = _b[_i];
102
- var data = (_a = provider.getData) === null || _a === void 0 ? void 0 : _a.call(provider, this._sdkKey, user);
103
- if (data) {
104
- return { data: data, source: provider.source };
120
+ const barrier = (listener) => {
121
+ try {
122
+ listener(event);
105
123
  }
106
- }
107
- return { data: null, source: 'NoValues' };
108
- };
109
- StatsigClientBase.prototype._getDataFromProvidersAsync = function (user) {
110
- var _a, e_1, _b, _c;
111
- var _d;
112
- return __awaiter(this, void 0, void 0, function () {
113
- var _e, _f, _g, provider, data, e_1_1;
114
- return __generator(this, function (_h) {
115
- switch (_h.label) {
116
- case 0:
117
- _h.trys.push([0, 6, 7, 12]);
118
- _e = true, _f = __asyncValues(this._dataProviders);
119
- _h.label = 1;
120
- case 1: return [4 /*yield*/, _f.next()];
121
- case 2:
122
- if (!(_g = _h.sent(), _a = _g.done, !_a)) return [3 /*break*/, 5];
123
- _c = _g.value;
124
- _e = false;
125
- provider = _c;
126
- return [4 /*yield*/, ((_d = provider.getDataAsync) === null || _d === void 0 ? void 0 : _d.call(provider, this._sdkKey, user))];
127
- case 3:
128
- data = _h.sent();
129
- if (data) {
130
- return [2 /*return*/, { data: data, source: provider.source }];
131
- }
132
- _h.label = 4;
133
- case 4:
134
- _e = true;
135
- return [3 /*break*/, 1];
136
- case 5: return [3 /*break*/, 12];
137
- case 6:
138
- e_1_1 = _h.sent();
139
- e_1 = { error: e_1_1 };
140
- return [3 /*break*/, 12];
141
- case 7:
142
- _h.trys.push([7, , 10, 11]);
143
- if (!(!_e && !_a && (_b = _f.return))) return [3 /*break*/, 9];
144
- return [4 /*yield*/, _b.call(_f)];
145
- case 8:
146
- _h.sent();
147
- _h.label = 9;
148
- case 9: return [3 /*break*/, 11];
149
- case 10:
150
- if (e_1) throw e_1.error;
151
- return [7 /*endfinally*/];
152
- case 11: return [7 /*endfinally*/];
153
- case 12: return [2 /*return*/, { data: null, source: 'NoValues' }];
154
- }
155
- });
156
- });
157
- };
158
- StatsigClientBase.prototype._getDataPostInitFromProviders = function (currentData, user) {
159
- var _a, e_2, _b, _c;
160
- var _d;
161
- return __awaiter(this, void 0, void 0, function () {
162
- var _e, _f, _g, provider, data, e_2_1;
163
- return __generator(this, function (_h) {
164
- switch (_h.label) {
165
- case 0:
166
- _h.trys.push([0, 6, 7, 12]);
167
- _e = true, _f = __asyncValues(this._dataProviders);
168
- _h.label = 1;
169
- case 1: return [4 /*yield*/, _f.next()];
170
- case 2:
171
- if (!(_g = _h.sent(), _a = _g.done, !_a)) return [3 /*break*/, 5];
172
- _c = _g.value;
173
- _e = false;
174
- provider = _c;
175
- return [4 /*yield*/, ((_d = provider.getDataPostInit) === null || _d === void 0 ? void 0 : _d.call(provider, this._sdkKey, currentData, user))];
176
- case 3:
177
- data = _h.sent();
178
- if (data) {
179
- return [2 /*return*/, { data: data, source: provider.source }];
180
- }
181
- _h.label = 4;
182
- case 4:
183
- _e = true;
184
- return [3 /*break*/, 1];
185
- case 5: return [3 /*break*/, 12];
186
- case 6:
187
- e_2_1 = _h.sent();
188
- e_2 = { error: e_2_1 };
189
- return [3 /*break*/, 12];
190
- case 7:
191
- _h.trys.push([7, , 10, 11]);
192
- if (!(!_e && !_a && (_b = _f.return))) return [3 /*break*/, 9];
193
- return [4 /*yield*/, _b.call(_f)];
194
- case 8:
195
- _h.sent();
196
- _h.label = 9;
197
- case 9: return [3 /*break*/, 11];
198
- case 10:
199
- if (e_2) throw e_2.error;
200
- return [7 /*endfinally*/];
201
- case 11: return [7 /*endfinally*/];
202
- case 12: return [2 /*return*/, { data: null, source: 'NoValues' }];
203
- }
204
- });
205
- });
206
- };
207
- StatsigClientBase.prototype._saveToDataProviders = function (currentData, user) {
208
- var _this = this;
209
- (function () { return __awaiter(_this, void 0, void 0, function () {
210
- var latest, data, _a, _b, _c, provider, e_3_1;
211
- var _d, e_3, _e, _f;
212
- var _g, _h;
213
- return __generator(this, function (_j) {
214
- switch (_j.label) {
215
- case 0: return [4 /*yield*/, this._getDataPostInitFromProviders(currentData, user)];
216
- case 1:
217
- latest = _j.sent();
218
- data = (_g = latest.data) !== null && _g !== void 0 ? _g : currentData;
219
- if (!data) {
220
- return [2 /*return*/];
221
- }
222
- _j.label = 2;
223
- case 2:
224
- _j.trys.push([2, 8, 9, 14]);
225
- _a = true, _b = __asyncValues(this._dataProviders);
226
- _j.label = 3;
227
- case 3: return [4 /*yield*/, _b.next()];
228
- case 4:
229
- if (!(_c = _j.sent(), _d = _c.done, !_d)) return [3 /*break*/, 7];
230
- _f = _c.value;
231
- _a = false;
232
- provider = _f;
233
- return [4 /*yield*/, ((_h = provider.setDataPostInit) === null || _h === void 0 ? void 0 : _h.call(provider, this._sdkKey, data, user))];
234
- case 5:
235
- _j.sent();
236
- _j.label = 6;
237
- case 6:
238
- _a = true;
239
- return [3 /*break*/, 3];
240
- case 7: return [3 /*break*/, 14];
241
- case 8:
242
- e_3_1 = _j.sent();
243
- e_3 = { error: e_3_1 };
244
- return [3 /*break*/, 14];
245
- case 9:
246
- _j.trys.push([9, , 12, 13]);
247
- if (!(!_a && !_d && (_e = _b.return))) return [3 /*break*/, 11];
248
- return [4 /*yield*/, _e.call(_b)];
249
- case 10:
250
- _j.sent();
251
- _j.label = 11;
252
- case 11: return [3 /*break*/, 13];
253
- case 12:
254
- if (e_3) throw e_3.error;
255
- return [7 /*endfinally*/];
256
- case 13: return [7 /*endfinally*/];
257
- case 14: return [2 /*return*/];
124
+ catch (error) {
125
+ if (listener.__isInternal === true) {
126
+ this._errorBoundary.logError(`__emit:${event.name}`, error);
127
+ return;
258
128
  }
259
- });
260
- }); })().catch(function (error) {
261
- _this.emit({ event: 'error', error: error });
262
- });
263
- };
264
- StatsigClientBase.prototype._enqueueExposure = function (options, exposure) {
265
- if (options.disableExposureLog === true) {
129
+ Log_1.Log.error(`An error occurred in a StatsigClientEvent listener. This is not an issue with Statsig.`, event);
130
+ }
131
+ };
132
+ if (this._listeners[event.name]) {
133
+ this._listeners[event.name].forEach((l) => barrier(l));
134
+ }
135
+ (_a = this._listeners['*']) === null || _a === void 0 ? void 0 : _a.forEach(barrier);
136
+ }
137
+ _setStatus(newStatus, values) {
138
+ this.loadingStatus = newStatus;
139
+ this.$emt({ name: 'values_updated', status: newStatus, values });
140
+ }
141
+ _enqueueExposure(name, exposure, options) {
142
+ if ((options === null || options === void 0 ? void 0 : options.disableExposureLog) === true) {
143
+ this._logger.incrementNonExposureCount(name);
266
144
  return;
267
145
  }
268
146
  this._logger.enqueue(exposure);
269
- };
270
- return StatsigClientBase;
271
- }());
147
+ }
148
+ }
272
149
  exports.StatsigClientBase = StatsigClientBase;