@statsig/client-core 0.0.1-beta.25 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statsig/client-core",
3
- "version": "0.0.1-beta.25",
3
+ "version": "0.0.1-beta.26",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -3,6 +3,8 @@ export type StatsigGlobal = {
3
3
  [key: string]: unknown;
4
4
  instances?: Record<string, StatsigClientInterface>;
5
5
  lastInstance?: StatsigClientInterface;
6
+ acInstances?: Record<string, unknown>;
7
+ srInstances?: Record<string, unknown>;
6
8
  };
7
9
  declare global {
8
10
  let __STATSIG__: StatsigGlobal | undefined;
@@ -21,6 +21,7 @@ export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterfa
21
21
  getExperiment(name: string, user: StatsigUser, options?: ExperimentEvaluationOptions): Experiment;
22
22
  getLayer(name: string, user: StatsigUser, options?: LayerEvaluationOptions): Layer;
23
23
  logEvent(event: StatsigEvent, user: StatsigUser): void;
24
+ logEvent(eventName: string, user: StatsigUser, value?: string | number, metadata?: Record<string, string>): void;
24
25
  }
25
26
  export type PrecomputedEvaluationsContext = {
26
27
  sdkKey: string;
@@ -44,5 +45,6 @@ export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInte
44
45
  getExperiment(name: string, options?: ExperimentEvaluationOptions): Experiment;
45
46
  getLayer(name: string, options?: LayerEvaluationOptions): Layer;
46
47
  logEvent(event: StatsigEvent): void;
48
+ logEvent(eventName: string, value?: string | number, metadata?: Record<string, string>): void;
47
49
  }
48
50
  export type StatsigClientInterface = OnDeviceEvaluationsInterface | PrecomputedEvaluationsInterface;
@@ -41,4 +41,5 @@ export declare class EventLogger {
41
41
  private _getStorageKey;
42
42
  private _normalizeAndAppendEvent;
43
43
  private _appendAndResetNonExposedChecks;
44
+ private _getCurrentPageUrl;
44
45
  }
@@ -13,7 +13,6 @@ exports.EventLogger = void 0;
13
13
  const Hashing_1 = require("./Hashing");
14
14
  const Log_1 = require("./Log");
15
15
  const StatsigEvent_1 = require("./StatsigEvent");
16
- const StatsigMetadata_1 = require("./StatsigMetadata");
17
16
  const StorageProvider_1 = require("./StorageProvider");
18
17
  const TypedJsonParse_1 = require("./TypedJsonParse");
19
18
  const UrlOverrides_1 = require("./UrlOverrides");
@@ -225,8 +224,12 @@ class EventLogger {
225
224
  event.user = Object.assign({}, event.user);
226
225
  delete event.user.privateAttributes;
227
226
  }
228
- const { sdkType, sdkVersion } = StatsigMetadata_1.StatsigMetadataProvider.get();
229
- this._queue.push(Object.assign(Object.assign({}, event), { statsigMetadata: { sdkType, sdkVersion } }));
227
+ const extras = {};
228
+ const currentPage = this._getCurrentPageUrl();
229
+ if (currentPage) {
230
+ extras.statsigMetadata = { currentPage };
231
+ }
232
+ this._queue.push(Object.assign(Object.assign({}, event), extras));
230
233
  }
231
234
  _appendAndResetNonExposedChecks() {
232
235
  if (Object.keys(this._nonExposedChecks).length === 0) {
@@ -242,5 +245,20 @@ class EventLogger {
242
245
  });
243
246
  this._nonExposedChecks = {};
244
247
  }
248
+ _getCurrentPageUrl() {
249
+ var _a;
250
+ if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.includeCurrentPageUrlWithEvents) === false) {
251
+ return;
252
+ }
253
+ if (typeof window === 'undefined' || typeof window.location !== 'object') {
254
+ return;
255
+ }
256
+ try {
257
+ return window.location.href.split(/[?#]/)[0];
258
+ }
259
+ catch (_b) {
260
+ return;
261
+ }
262
+ }
245
263
  }
246
264
  exports.EventLogger = EventLogger;
@@ -25,10 +25,39 @@ export declare abstract class StatsigClientBase<TAdapter extends EvaluationsData
25
25
  protected readonly _overrideAdapter: OverrideAdapter | null;
26
26
  private _listeners;
27
27
  constructor(sdkKey: string, adapter: TAdapter, network: NetworkCore, options: StatsigOptionsCommon | 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
+ */
28
33
  updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
34
+ /**
35
+ * Flushes any currently queued events.
36
+ */
29
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
+ */
30
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
+ */
31
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
+ */
32
61
  off<T extends StatsigClientEventName>(event: T, listener: StatsigClientEventCallback<T>): void;
33
62
  protected _emit(event: StatsigClientEvent): void;
34
63
  protected _setStatus(newStatus: StatsigLoadingStatus, values: DataAdapterResult | null): void;
@@ -43,6 +43,11 @@ class StatsigClientBase {
43
43
  this.dataAdapter = adapter;
44
44
  this.dataAdapter.attach(sdkKey, options);
45
45
  }
46
+ /**
47
+ * 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.
48
+ *
49
+ * @param {StatsigRuntimeMutableOptions} options - The configuration options that dictate the runtime behavior of the SDK.
50
+ */
46
51
  updateRuntimeOptions(options) {
47
52
  if (options.disableLogging != null) {
48
53
  this._options.disableLogging = options.disableLogging;
@@ -53,21 +58,45 @@ class StatsigClientBase {
53
58
  StorageProvider_1.Storage.setDisabled(options.disableStorage);
54
59
  }
55
60
  }
61
+ /**
62
+ * Flushes any currently queued events.
63
+ */
56
64
  flush() {
57
65
  return this._logger.flush();
58
66
  }
67
+ /**
68
+ * Gracefully shuts down the SDK, ensuring that all pending events are send before the SDK stops.
69
+ * This function emits a 'pre_shutdown' event and then waits for the logger to complete its shutdown process.
70
+ *
71
+ * @returns {Promise<void>} A promise that resolves when all shutdown procedures, including logging shutdown, have been completed.
72
+ */
59
73
  shutdown() {
60
74
  return __awaiter(this, void 0, void 0, function* () {
61
75
  this._emit({ name: 'pre_shutdown' });
62
76
  yield this._logger.shutdown();
63
77
  });
64
78
  }
79
+ /**
80
+ * Subscribes a callback function to a specific {@link StatsigClientEvent} or all StatsigClientEvents if the wildcard '*' is used.
81
+ * Once subscribed, the listener callback will be invoked whenever the specified event is emitted.
82
+ *
83
+ * @param {StatsigClientEventName} event - The name of the event to subscribe to, or '*' to subscribe to all events.
84
+ * @param {StatsigClientEventCallback<T>} listener - The callback function to execute when the event occurs. The function receives event-specific data as its parameter.
85
+ * @see {@link off} for unsubscribing from events.
86
+ */
65
87
  on(event, listener) {
66
88
  if (!this._listeners[event]) {
67
89
  this._listeners[event] = [];
68
90
  }
69
91
  this._listeners[event].push(listener);
70
92
  }
93
+ /**
94
+ * Unsubscribes a previously registered callback function from a specific {@link StatsigClientEvent} or all StatsigClientEvents if the wildcard '*' is used.
95
+ *
96
+ * @param {StatsigClientEventName} event - The name of the event from which to unsubscribe, or '*' to unsubscribe from all events.
97
+ * @param {StatsigClientEventCallback<T>} listener - The callback function to remove from the event's notification list.
98
+ * @see {@link on} for subscribing to events.
99
+ */
71
100
  off(event, listener) {
72
101
  if (this._listeners[event]) {
73
102
  const index = this._listeners[event].indexOf(listener);
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StatsigMetadataProvider = void 0;
4
- const SDK_VERSION = '0.0.1-beta.25';
4
+ const SDK_VERSION = '0.0.1-beta.26';
5
5
  let metadata = {
6
6
  sdkVersion: SDK_VERSION,
7
7
  sdkType: 'js-mono', // js-mono is overwritten by Precomp and OnDevice clients
@@ -71,6 +71,12 @@ export type StatsigOptionsCommon = StatsigRuntimeMutableOptions & {
71
71
  * returned to the caller of a check api (checkGate/getExperiment etc).
72
72
  */
73
73
  overrideAdapter?: OverrideAdapter;
74
+ /**
75
+ * (Web only) Should the 'current page' url be included with logged events.
76
+ *
77
+ * default: true
78
+ */
79
+ includeCurrentPageUrlWithEvents?: boolean;
74
80
  };
75
81
  export type StatsigEnvironment = {
76
82
  tier?: string;
@@ -0,0 +1,6 @@
1
+ import { DynamicConfigEvaluation, EvaluationDetails, GateEvaluation, LayerEvaluation } from './EvaluationTypes';
2
+ import { AnyConfigBasedStatsigType, DynamicConfig, FeatureGate, Layer } from './StatsigTypes';
3
+ export declare function _makeFeatureGate(name: string, details: EvaluationDetails, evaluation: GateEvaluation | null): FeatureGate;
4
+ export declare function _makeDynamicConfig(name: string, details: EvaluationDetails, evaluation: DynamicConfigEvaluation | null): DynamicConfig;
5
+ export declare function _makeLayer(name: string, details: EvaluationDetails, evaluation: LayerEvaluation | null, exposeFunc?: (param: string) => void): Layer;
6
+ export declare function _mergeOverride<T extends AnyConfigBasedStatsigType>(original: T, overridden: T | null | undefined, value: Record<string, unknown>, exposeFunc?: (param: string) => void): T;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._mergeOverride = exports._makeLayer = exports._makeDynamicConfig = exports._makeFeatureGate = void 0;
4
+ const DEFAULT_RULE = 'default';
5
+ function _makeFeatureGate(name, details, evaluation) {
6
+ var _a;
7
+ return {
8
+ name,
9
+ details,
10
+ ruleID: (_a = evaluation === null || evaluation === void 0 ? void 0 : evaluation.rule_id) !== null && _a !== void 0 ? _a : DEFAULT_RULE,
11
+ value: (evaluation === null || evaluation === void 0 ? void 0 : evaluation.value) === true,
12
+ __evaluation: evaluation,
13
+ };
14
+ }
15
+ exports._makeFeatureGate = _makeFeatureGate;
16
+ function _makeDynamicConfig(name, details, evaluation) {
17
+ var _a, _b;
18
+ return {
19
+ name,
20
+ details,
21
+ value: (_a = evaluation === null || evaluation === void 0 ? void 0 : evaluation.value) !== null && _a !== void 0 ? _a : {},
22
+ ruleID: (_b = evaluation === null || evaluation === void 0 ? void 0 : evaluation.rule_id) !== null && _b !== void 0 ? _b : DEFAULT_RULE,
23
+ groupName: null,
24
+ get: _makeTypedGet(evaluation === null || evaluation === void 0 ? void 0 : evaluation.value),
25
+ __evaluation: evaluation,
26
+ };
27
+ }
28
+ exports._makeDynamicConfig = _makeDynamicConfig;
29
+ function _makeLayer(name, details, evaluation, exposeFunc) {
30
+ var _a, _b, _c;
31
+ return {
32
+ name,
33
+ details,
34
+ get: _makeTypedGet(evaluation === null || evaluation === void 0 ? void 0 : evaluation.value, exposeFunc),
35
+ ruleID: (_a = evaluation === null || evaluation === void 0 ? void 0 : evaluation.rule_id) !== null && _a !== void 0 ? _a : DEFAULT_RULE,
36
+ groupName: (_b = evaluation === null || evaluation === void 0 ? void 0 : evaluation.group_name) !== null && _b !== void 0 ? _b : null,
37
+ __value: (_c = evaluation === null || evaluation === void 0 ? void 0 : evaluation.value) !== null && _c !== void 0 ? _c : {},
38
+ __evaluation: evaluation,
39
+ };
40
+ }
41
+ exports._makeLayer = _makeLayer;
42
+ function _mergeOverride(original, overridden, value, exposeFunc) {
43
+ return Object.assign(Object.assign(Object.assign({}, original), overridden), { get: _makeTypedGet(value, exposeFunc) });
44
+ }
45
+ exports._mergeOverride = _mergeOverride;
46
+ function _isTypeMatch(a, b) {
47
+ const typeOf = (x) => (Array.isArray(x) ? 'array' : typeof x);
48
+ return typeOf(a) === typeOf(b);
49
+ }
50
+ function _makeTypedGet(value, exposeFunc) {
51
+ return (param, fallback) => {
52
+ var _a;
53
+ const found = (_a = value === null || value === void 0 ? void 0 : value[param]) !== null && _a !== void 0 ? _a : null;
54
+ if (found == null) {
55
+ return (fallback !== null && fallback !== void 0 ? fallback : null);
56
+ }
57
+ if (fallback != null && !_isTypeMatch(found, fallback)) {
58
+ return (fallback !== null && fallback !== void 0 ? fallback : null);
59
+ }
60
+ exposeFunc === null || exposeFunc === void 0 ? void 0 : exposeFunc(param);
61
+ return found;
62
+ };
63
+ }
@@ -1,30 +1,33 @@
1
- import { DynamicConfigEvaluation, EvaluationDetails, ExperimentEvaluation, GateEvaluation, LayerEvaluation } from './EvaluationTypes';
1
+ import { EvaluationDetails, ExperimentEvaluation, GateEvaluation, LayerEvaluation } from './EvaluationTypes';
2
2
  import { Flatten } from './UtitlityTypes';
3
- type CommonFields = {
3
+ export type TypedGet = <T = unknown>(key: string, fallback?: T) => TypedReturn<T>;
4
+ export type TypedReturn<T = unknown> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends Array<unknown> ? Array<unknown> : T extends object ? object : unknown;
5
+ export type SpecType = 'gate' | 'dynamic_config' | 'experiment' | 'layer';
6
+ export type FeatureGate = Flatten<{
4
7
  readonly name: string;
5
8
  readonly ruleID: string;
6
9
  readonly details: EvaluationDetails;
7
- };
8
- export type SpecType = 'gate' | 'dynamic_config' | 'experiment' | 'layer';
9
- export type FeatureGate = Flatten<CommonFields & {
10
10
  readonly value: boolean;
11
11
  readonly __evaluation: GateEvaluation | null;
12
12
  }>;
13
- export type DynamicConfig = Flatten<CommonFields & {
14
- readonly value: Record<string, unknown>;
15
- readonly __evaluation: DynamicConfigEvaluation | null;
16
- }>;
17
- export type Experiment = Flatten<CommonFields & {
13
+ export type Experiment = Flatten<{
14
+ readonly name: string;
15
+ readonly ruleID: string;
16
+ readonly details: EvaluationDetails;
18
17
  readonly value: Record<string, unknown>;
18
+ readonly groupName: string | null;
19
19
  readonly __evaluation: ExperimentEvaluation | null;
20
+ readonly get: TypedGet;
20
21
  }>;
21
- export type Layer = Flatten<CommonFields & {
22
- readonly getValue: (parameterName: string) => unknown;
23
- readonly _value: Record<string, unknown>;
22
+ export type DynamicConfig = Flatten<Experiment>;
23
+ export type Layer = Flatten<{
24
+ readonly name: string;
25
+ readonly ruleID: string;
26
+ readonly details: EvaluationDetails;
27
+ readonly groupName: string | null;
28
+ readonly __value: Record<string, unknown>;
24
29
  readonly __evaluation: LayerEvaluation | null;
30
+ readonly get: TypedGet;
25
31
  }>;
26
- export type AnyConfig = FeatureGate | DynamicConfig | Experiment | Layer;
27
- export declare function makeFeatureGate(name: string, details: EvaluationDetails, evaluation: GateEvaluation | null): FeatureGate;
28
- export declare function makeDynamicConfig(name: string, details: EvaluationDetails, evaluation: DynamicConfigEvaluation | null): DynamicConfig;
29
- export declare function makeLayer(name: string, details: EvaluationDetails, evaluation: LayerEvaluation | null, getValue?: (param: string) => unknown): Layer;
30
- export {};
32
+ export type AnyConfigBasedStatsigType = DynamicConfig | Experiment | Layer;
33
+ export type AnyStatsigType = FeatureGate | AnyConfigBasedStatsigType;
@@ -1,38 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeLayer = exports.makeDynamicConfig = exports.makeFeatureGate = void 0;
4
- const DEFAULT_RULE = 'default';
5
- function makeFeatureGate(name, details, evaluation) {
6
- var _a;
7
- return {
8
- name,
9
- details,
10
- ruleID: (_a = evaluation === null || evaluation === void 0 ? void 0 : evaluation.rule_id) !== null && _a !== void 0 ? _a : DEFAULT_RULE,
11
- value: (evaluation === null || evaluation === void 0 ? void 0 : evaluation.value) === true,
12
- __evaluation: evaluation,
13
- };
14
- }
15
- exports.makeFeatureGate = makeFeatureGate;
16
- function makeDynamicConfig(name, details, evaluation) {
17
- var _a, _b;
18
- return {
19
- name,
20
- details,
21
- ruleID: (_a = evaluation === null || evaluation === void 0 ? void 0 : evaluation.rule_id) !== null && _a !== void 0 ? _a : DEFAULT_RULE,
22
- value: (_b = evaluation === null || evaluation === void 0 ? void 0 : evaluation.value) !== null && _b !== void 0 ? _b : {},
23
- __evaluation: evaluation,
24
- };
25
- }
26
- exports.makeDynamicConfig = makeDynamicConfig;
27
- function makeLayer(name, details, evaluation, getValue) {
28
- var _a, _b;
29
- return {
30
- name,
31
- details,
32
- getValue: getValue !== null && getValue !== void 0 ? getValue : (() => undefined),
33
- ruleID: (_a = evaluation === null || evaluation === void 0 ? void 0 : evaluation.rule_id) !== null && _a !== void 0 ? _a : DEFAULT_RULE,
34
- _value: (_b = evaluation === null || evaluation === void 0 ? void 0 : evaluation.value) !== null && _b !== void 0 ? _b : {},
35
- __evaluation: evaluation,
36
- };
37
- }
38
- exports.makeLayer = makeLayer;
package/src/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export * from './StatsigDataAdapter';
23
23
  export * from './StatsigEvent';
24
24
  export * from './StatsigMetadata';
25
25
  export * from './StatsigOptionsCommon';
26
+ export * from './StatsigTypeFactories';
26
27
  export * from './StatsigTypes';
27
28
  export * from './StatsigUser';
28
29
  export * from './StorageProvider';
package/src/index.js CHANGED
@@ -44,6 +44,7 @@ __exportStar(require("./StatsigDataAdapter"), exports);
44
44
  __exportStar(require("./StatsigEvent"), exports);
45
45
  __exportStar(require("./StatsigMetadata"), exports);
46
46
  __exportStar(require("./StatsigOptionsCommon"), exports);
47
+ __exportStar(require("./StatsigTypeFactories"), exports);
47
48
  __exportStar(require("./StatsigTypes"), exports);
48
49
  __exportStar(require("./StatsigUser"), exports);
49
50
  __exportStar(require("./StorageProvider"), exports);
@@ -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): Promise<string | null>;
7
- setItem(key: string, value: string): void;
8
- removeItem(key: string): void;
9
- }
@@ -1,47 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.MockLocalStorage = void 0;
13
- const actualLocalStorage = window.localStorage;
14
- // todo: move to test-helpers (break circular dep)
15
- class MockLocalStorage {
16
- constructor() {
17
- this.data = {};
18
- }
19
- static enabledMockStorage() {
20
- const value = new MockLocalStorage();
21
- Object.defineProperty(window, 'localStorage', {
22
- value,
23
- });
24
- return value;
25
- }
26
- static disableMockStorage() {
27
- Object.defineProperty(window, 'localStorage', {
28
- value: actualLocalStorage,
29
- });
30
- }
31
- // LocalStorage Functions
32
- clear() {
33
- this.data = {};
34
- }
35
- getItem(key) {
36
- return __awaiter(this, void 0, void 0, function* () {
37
- return Promise.resolve(this.data[key] ? this.data[key] : null);
38
- });
39
- }
40
- setItem(key, value) {
41
- this.data[key] = String(value);
42
- }
43
- removeItem(key) {
44
- delete this.data[key];
45
- }
46
- }
47
- exports.MockLocalStorage = MockLocalStorage;