@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.
Files changed (74) hide show
  1. package/README.md +0 -3
  2. package/package.json +1 -1
  3. package/src/$_StatsigGlobal.d.ts +9 -1
  4. package/src/$_StatsigGlobal.js +29 -12
  5. package/src/CacheKey.d.ts +4 -0
  6. package/src/CacheKey.js +27 -0
  7. package/src/ClientInterfaces.d.ts +46 -12
  8. package/src/DataAdapterCore.d.ts +31 -0
  9. package/src/DataAdapterCore.js +192 -0
  10. package/src/Diagnostics.d.ts +1 -3
  11. package/src/Diagnostics.js +4 -49
  12. package/src/DownloadConfigSpecsResponse.d.ts +41 -0
  13. package/src/DownloadConfigSpecsResponse.js +2 -0
  14. package/src/ErrorBoundary.d.ts +7 -2
  15. package/src/ErrorBoundary.js +81 -88
  16. package/src/EvaluationOptions.d.ts +20 -0
  17. package/src/EvaluationOptions.js +2 -0
  18. package/src/EvaluationTypes.d.ts +39 -0
  19. package/src/EvaluationTypes.js +2 -0
  20. package/src/EventLogger.d.ts +15 -10
  21. package/src/EventLogger.js +216 -256
  22. package/src/Hashing.d.ts +2 -1
  23. package/src/Hashing.js +26 -7
  24. package/src/InitializeResponse.d.ts +20 -0
  25. package/src/InitializeResponse.js +2 -0
  26. package/src/Log.js +15 -34
  27. package/src/NetworkConfig.d.ts +19 -0
  28. package/src/NetworkConfig.js +19 -0
  29. package/src/NetworkCore.d.ts +17 -7
  30. package/src/NetworkCore.js +173 -196
  31. package/src/OverrideAdapter.d.ts +9 -0
  32. package/src/OverrideAdapter.js +2 -0
  33. package/src/SDKType.d.ts +8 -0
  34. package/src/SDKType.js +19 -0
  35. package/src/SafeJs.d.ts +6 -0
  36. package/src/SafeJs.js +41 -0
  37. package/src/SessionID.d.ts +17 -1
  38. package/src/SessionID.js +89 -8
  39. package/src/StableID.js +24 -53
  40. package/src/StatsigClientBase.d.ts +56 -19
  41. package/src/StatsigClientBase.js +126 -48
  42. package/src/StatsigClientEventEmitter.d.ts +54 -33
  43. package/src/StatsigDataAdapter.d.ts +103 -17
  44. package/src/StatsigDataAdapter.js +2 -0
  45. package/src/StatsigEvent.d.ts +10 -18
  46. package/src/StatsigEvent.js +41 -39
  47. package/src/StatsigMetadata.d.ts +1 -1
  48. package/src/StatsigMetadata.js +7 -18
  49. package/src/StatsigOptionsCommon.d.ts +84 -20
  50. package/src/StatsigTypeFactories.d.ts +6 -0
  51. package/src/StatsigTypeFactories.js +50 -0
  52. package/src/StatsigTypes.d.ts +28 -22
  53. package/src/StatsigTypes.js +0 -29
  54. package/src/StatsigUser.d.ts +7 -8
  55. package/src/StatsigUser.js +11 -24
  56. package/src/StorageProvider.d.ts +13 -8
  57. package/src/StorageProvider.js +66 -85
  58. package/src/TypedJsonParse.d.ts +8 -0
  59. package/src/TypedJsonParse.js +27 -0
  60. package/src/UUID.js +9 -5
  61. package/src/UrlOverrides.d.ts +1 -0
  62. package/src/UrlOverrides.js +15 -0
  63. package/src/UtitlityTypes.d.ts +3 -0
  64. package/src/UtitlityTypes.js +2 -0
  65. package/src/VisibilityObserving.d.ts +9 -0
  66. package/src/VisibilityObserving.js +39 -0
  67. package/src/index.d.ts +20 -4
  68. package/src/index.js +26 -18
  69. package/src/Monitoring.d.ts +0 -3
  70. package/src/Monitoring.js +0 -33
  71. package/src/VisibilityChangeObserver.d.ts +0 -13
  72. package/src/VisibilityChangeObserver.js +0 -48
  73. package/src/__tests__/MockLocalStorage.d.ts +0 -9
  74. package/src/__tests__/MockLocalStorage.js +0 -37
@@ -1,15 +1,4 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
3
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
4
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -19,113 +8,117 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
19
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
20
9
  });
21
10
  };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- 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;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
11
  Object.defineProperty(exports, "__esModule", { value: true });
50
12
  exports.ErrorBoundary = exports.EXCEPTION_ENDPOINT = void 0;
51
- var Log_1 = require("./Log");
52
- var StatsigMetadata_1 = require("./StatsigMetadata");
13
+ const Log_1 = require("./Log");
14
+ const SDKType_1 = require("./SDKType");
15
+ const StatsigMetadata_1 = require("./StatsigMetadata");
53
16
  exports.EXCEPTION_ENDPOINT = 'https://statsigapi.net/v1/sdk_exception';
54
- var ErrorBoundary = /** @class */ (function () {
55
- function ErrorBoundary(_sdkKey) {
17
+ const UNKNOWN_ERROR = '[Statsig] UnknownError';
18
+ class ErrorBoundary {
19
+ constructor(_sdkKey, _options, _emitter) {
56
20
  this._sdkKey = _sdkKey;
21
+ this._options = _options;
22
+ this._emitter = _emitter;
57
23
  this._seen = new Set();
58
24
  }
59
- ErrorBoundary.prototype.capture = function (tag, task, emitter) {
60
- var _this = this;
25
+ wrap(instance) {
61
26
  try {
62
- var res = task();
27
+ const obj = instance;
28
+ _getAllInstanceMethodNames(obj).forEach((name) => {
29
+ const original = obj[name];
30
+ if ('$EB' in original) {
31
+ return;
32
+ }
33
+ obj[name] = (...args) => {
34
+ return this._capture(name, () => original.apply(instance, args));
35
+ };
36
+ obj[name].$EB = true;
37
+ });
38
+ }
39
+ catch (err) {
40
+ this._onError('eb:wrap', err);
41
+ }
42
+ }
43
+ logError(tag, error) {
44
+ this._onError(tag, error);
45
+ }
46
+ _capture(tag, task) {
47
+ try {
48
+ const res = task();
63
49
  if (res && res instanceof Promise) {
64
- return res.catch(function (err) { return _this._onError(tag, err, emitter); });
50
+ return res.catch((err) => this._onError(tag, err));
65
51
  }
66
52
  return res;
67
53
  }
68
54
  catch (error) {
69
- this._onError(tag, error, emitter);
55
+ this._onError(tag, error);
70
56
  return null;
71
57
  }
72
- };
73
- ErrorBoundary.prototype._onError = function (tag, error, emitter) {
74
- var _this = this;
58
+ }
59
+ _onError(tag, error) {
75
60
  try {
76
- Log_1.Log.warn("Caught error in ".concat(tag), { error: error });
77
- var impl = function () { return __awaiter(_this, void 0, void 0, function () {
78
- var unwrapped, isError, name, statsigMetadata, info, body;
79
- return __generator(this, function (_a) {
80
- switch (_a.label) {
81
- case 0:
82
- unwrapped = (error !== null && error !== void 0 ? error : Error('[Statsig] Error was empty'));
83
- isError = unwrapped instanceof Error;
84
- name = isError ? unwrapped.name : 'No Name';
85
- if (this._seen.has(name)) {
86
- return [2 /*return*/];
87
- }
88
- this._seen.add(name);
89
- statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
90
- info = isError ? unwrapped.stack : _getDescription(unwrapped);
91
- body = JSON.stringify(__assign({ tag: tag, exception: name, info: info }, statsigMetadata));
92
- return [4 /*yield*/, fetch(exports.EXCEPTION_ENDPOINT, {
93
- method: 'POST',
94
- headers: {
95
- 'STATSIG-API-KEY': this._sdkKey,
96
- 'STATSIG-SDK-TYPE': String(statsigMetadata.sdkType),
97
- 'STATSIG-SDK-VERSION': String(statsigMetadata.sdkVersion),
98
- 'Content-Type': 'application/json',
99
- },
100
- body: body,
101
- })];
102
- case 1:
103
- _a.sent();
104
- emitter === null || emitter === void 0 ? void 0 : emitter({ event: 'error', error: error });
105
- return [2 /*return*/];
106
- }
61
+ Log_1.Log.warn(`Caught error in ${tag}`, { error });
62
+ const impl = () => __awaiter(this, void 0, void 0, function* () {
63
+ var _a, _b, _c, _d, _e, _f, _g;
64
+ const unwrapped = (error ? error : Error(UNKNOWN_ERROR));
65
+ const isError = unwrapped instanceof Error;
66
+ const name = isError ? unwrapped.name : 'No Name';
67
+ if (this._seen.has(name)) {
68
+ return;
69
+ }
70
+ this._seen.add(name);
71
+ if ((_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.networkConfig) === null || _b === void 0 ? void 0 : _b.preventAllNetworkTraffic) {
72
+ (_c = this._emitter) === null || _c === void 0 ? void 0 : _c.call(this, { name: 'error', error });
73
+ return;
74
+ }
75
+ const sdkType = SDKType_1.SDKType._get(this._sdkKey);
76
+ const statsigMetadata = StatsigMetadata_1.StatsigMetadataProvider.get();
77
+ const info = isError ? unwrapped.stack : _getDescription(unwrapped);
78
+ const body = JSON.stringify(Object.assign({ tag, exception: name, info }, Object.assign(Object.assign({}, statsigMetadata), { sdkType })));
79
+ const func = (_f = (_e = (_d = this._options) === null || _d === void 0 ? void 0 : _d.networkConfig) === null || _e === void 0 ? void 0 : _e.networkOverrideFunc) !== null && _f !== void 0 ? _f : fetch;
80
+ yield func(exports.EXCEPTION_ENDPOINT, {
81
+ method: 'POST',
82
+ headers: {
83
+ 'STATSIG-API-KEY': this._sdkKey,
84
+ 'STATSIG-SDK-TYPE': String(sdkType),
85
+ 'STATSIG-SDK-VERSION': String(statsigMetadata.sdkVersion),
86
+ 'Content-Type': 'application/json',
87
+ },
88
+ body,
107
89
  });
108
- }); };
90
+ (_g = this._emitter) === null || _g === void 0 ? void 0 : _g.call(this, { name: 'error', error });
91
+ });
109
92
  impl()
110
- .then(function () {
93
+ .then(() => {
111
94
  /* noop */
112
95
  })
113
- .catch(function () {
96
+ .catch(() => {
114
97
  /* noop */
115
98
  });
116
99
  }
117
100
  catch (_error) {
118
101
  /* noop */
119
102
  }
120
- };
121
- return ErrorBoundary;
122
- }());
103
+ }
104
+ }
123
105
  exports.ErrorBoundary = ErrorBoundary;
124
106
  function _getDescription(obj) {
125
107
  try {
126
108
  return JSON.stringify(obj);
127
109
  }
128
110
  catch (_a) {
129
- return '[Statsig] Failed to get string for error.';
111
+ return UNKNOWN_ERROR;
112
+ }
113
+ }
114
+ function _getAllInstanceMethodNames(instance) {
115
+ const names = new Set();
116
+ let proto = Object.getPrototypeOf(instance);
117
+ while (proto && proto !== Object.prototype) {
118
+ Object.getOwnPropertyNames(proto)
119
+ .filter((prop) => typeof (proto === null || proto === void 0 ? void 0 : proto[prop]) === 'function')
120
+ .forEach((name) => names.add(name));
121
+ proto = Object.getPrototypeOf(proto);
130
122
  }
123
+ return Array.from(names);
131
124
  }
@@ -0,0 +1,20 @@
1
+ export type EvaluationOptionsCommon = {
2
+ /**
3
+ * Prevents an exposure log being created for this check.
4
+ *
5
+ * default: `false`
6
+ */
7
+ disableExposureLog?: boolean;
8
+ };
9
+ export type FeatureGateEvaluationOptions = EvaluationOptionsCommon & {};
10
+ export type DynamicConfigEvaluationOptions = EvaluationOptionsCommon & {};
11
+ export type ExperimentEvaluationOptions = EvaluationOptionsCommon & {
12
+ /**
13
+ * Provide a map of values to be used across checks
14
+ *
15
+ * @requires {@link @statsig/js-user-persisted-storage}
16
+ * @see {@link https://docs.statsig.com/client/concepts/persistent_assignment#example-usage}
17
+ */
18
+ userPersistedValues?: unknown;
19
+ };
20
+ export type LayerEvaluationOptions = EvaluationOptionsCommon & {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,39 @@
1
+ import { Flatten } from './UtitlityTypes';
2
+ type EvaluationBase<T> = {
3
+ id_type: string;
4
+ name: string;
5
+ rule_id: string;
6
+ secondary_exposures: SecondaryExposure[];
7
+ value: T;
8
+ };
9
+ export type SecondaryExposure = {
10
+ gate: string;
11
+ gateValue: string;
12
+ ruleID: string;
13
+ };
14
+ export type GateEvaluation = EvaluationBase<boolean>;
15
+ export type ExperimentEvaluation = Flatten<EvaluationBase<Record<string, unknown>> & {
16
+ group_name?: string;
17
+ group: string;
18
+ id_type: string;
19
+ is_device_based: boolean;
20
+ is_experiment_active?: boolean;
21
+ is_user_in_experiment?: boolean;
22
+ }>;
23
+ export type DynamicConfigEvaluation = ExperimentEvaluation;
24
+ export type LayerEvaluation = Flatten<Omit<ExperimentEvaluation, 'id_type'> & {
25
+ allocated_experiment_name: string;
26
+ explicit_parameters: string[];
27
+ undelegated_secondary_exposures?: SecondaryExposure[];
28
+ }>;
29
+ export type AnyEvaluation = GateEvaluation | ExperimentEvaluation | DynamicConfigEvaluation | LayerEvaluation;
30
+ export type EvaluationDetails = {
31
+ reason: string;
32
+ lcut?: number;
33
+ receivedAt?: number;
34
+ };
35
+ export type DetailedEvaluation<T extends AnyEvaluation> = {
36
+ evaluation: T | null;
37
+ details: EvaluationDetails;
38
+ };
39
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,38 +1,43 @@
1
1
  import { NetworkCore } from './NetworkCore';
2
2
  import { StatsigClientEmitEventFunc } from './StatsigClientBase';
3
3
  import { StatsigEventInternal } from './StatsigEvent';
4
- import { StatsigOptionsCommon } from './StatsigOptionsCommon';
5
- import { Visibility } from './VisibilityChangeObserver';
4
+ import { NetworkConfigCommon, StatsigOptionsCommon } from './StatsigOptionsCommon';
6
5
  export declare class EventLogger {
7
6
  private _sdkKey;
8
7
  private _emitter;
9
8
  private _network;
10
9
  private _options;
11
10
  private _queue;
12
- private _flushTimer;
13
- private _lastExposureMap;
11
+ private _flushIntervalId;
12
+ private _lastExposureTimeMap;
13
+ private _nonExposedChecks;
14
14
  private _maxQueueSize;
15
- private _failedLogs;
16
15
  private _hasRunQuickFlush;
17
16
  private _creationTime;
18
- constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon | null);
17
+ private _isLoggingDisabled;
18
+ private _logEventUrl;
19
+ constructor(_sdkKey: string, _emitter: StatsigClientEmitEventFunc, _network: NetworkCore, _options: StatsigOptionsCommon<NetworkConfigCommon> | null);
20
+ setLoggingDisabled(isDisabled: boolean): void;
19
21
  enqueue(event: StatsigEventInternal): void;
22
+ incrementNonExposureCount(name: string): void;
20
23
  reset(): void;
21
- onVisibilityChanged(visibility: Visibility): void;
22
24
  shutdown(): Promise<void>;
25
+ flush(): Promise<void>;
23
26
  /**
24
27
  * We 'Quick Flush' following the very first event enqueued
25
28
  * within the quick flush window
26
29
  */
27
30
  private _quickFlushIfNeeded;
28
31
  private _shouldLogEvent;
29
- private _flushAndForget;
30
- private _flush;
31
32
  private _sendEvents;
32
33
  private _sendEventsViaPost;
33
34
  private _sendEventsViaBeacon;
34
- private _isBeaconSupported;
35
+ private _getRequestData;
35
36
  private _saveFailedLogsToStorage;
36
37
  private _retryFailedLogs;
37
38
  private _getStorageKey;
39
+ private _normalizeAndAppendEvent;
40
+ private _appendAndResetNonExposedChecks;
41
+ private _getCurrentPageUrl;
42
+ private _startBackgroundFlushInterval;
38
43
  }