@statsig/client-core 3.31.0 → 3.31.1

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": "3.31.0",
3
+ "version": "3.31.1",
4
4
  "license": "ISC",
5
5
  "homepage": "https://github.com/statsig-io/js-client-monorepo",
6
6
  "repository": {
@@ -2,7 +2,7 @@ import { DownloadConfigSpecsResponse } from './DownloadConfigSpecsResponse';
2
2
  import { ErrorBoundary } from './ErrorBoundary';
3
3
  import { DynamicConfigEvaluationOptions, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, LayerEvaluationOptions, ParameterStoreEvaluationOptions } from './EvaluationOptions';
4
4
  import { AnyInitializeResponse, ClientInitializeResponseOptions } from './InitializeResponse';
5
- import { StatsigSession } from './SessionID';
5
+ import { StatsigSession, StatsigSession as StatsigSessionType } from './SessionID';
6
6
  import { StatsigClientEventEmitterInterface } from './StatsigClientEventEmitter';
7
7
  import { EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
8
8
  import { StatsigEvent } from './StatsigEvent';
@@ -48,6 +48,7 @@ export type PrecomputedEvaluationsContext = Flatten<CommonContext & {
48
48
  export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
49
49
  readonly dataAdapter: EvaluationsDataAdapter;
50
50
  getContext(): PrecomputedEvaluationsContext;
51
+ getContextHandle(): PrecomputedEvaluationsContextHandle;
51
52
  updateUserSync(user: StatsigUser): StatsigUpdateDetails;
52
53
  updateUserAsync(user: StatsigUser): Promise<StatsigUpdateDetails>;
53
54
  checkGate(name: string, options?: FeatureGateEvaluationOptions): boolean;
@@ -60,3 +61,35 @@ export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInte
60
61
  logEvent(eventName: string, value?: string | number, metadata?: Record<string, string>): void;
61
62
  }
62
63
  export type StatsigClientInterface = OnDeviceEvaluationsInterface | PrecomputedEvaluationsInterface;
64
+ /**
65
+ * A handle to the PrecomputedEvaluationsContext that computes fields lazily on access.
66
+ * This avoids unnecessary computation (e.g., cloning the user) when only certain fields are needed.
67
+ * The handle is created once and reused; individual getters fetch current values on each access.
68
+ */
69
+ export declare class PrecomputedEvaluationsContextHandle {
70
+ private _sdkKey;
71
+ private _getOptions;
72
+ private _getErrorBoundary;
73
+ private _getValues;
74
+ private _getUser;
75
+ private _getSdkInstanceID;
76
+ constructor(sdkKey: string, getOptions: () => AnyStatsigOptions, getErrorBoundary: () => ErrorBoundary, getValues: () => AnyInitializeResponse | null, getUser: () => StatsigUser, getSdkInstanceID: () => string);
77
+ get sdkKey(): string;
78
+ get options(): AnyStatsigOptions;
79
+ get errorBoundary(): ErrorBoundary;
80
+ get values(): AnyInitializeResponse | null;
81
+ get user(): StatsigUser;
82
+ /**
83
+ * Gets the current session.
84
+ * @param {boolean} [bumpSession=true] - Whether to bump/update the session timing. Set to false to read without affecting session state.
85
+ */
86
+ getSession(bumpSession?: boolean): StatsigSessionType;
87
+ get stableID(): string | null;
88
+ get sdkInstanceID(): string;
89
+ /**
90
+ * Returns the full PrecomputedEvaluationsContext object.
91
+ * Use this when you need all fields at once.
92
+ * @param {boolean} [bumpSession=true] - Whether to bump the session when building the context.
93
+ */
94
+ toContext(bumpSession?: boolean): PrecomputedEvaluationsContext;
95
+ }
@@ -1,2 +1,73 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrecomputedEvaluationsContextHandle = void 0;
4
+ const Log_1 = require("./Log");
5
+ const SafeJs_1 = require("./SafeJs");
6
+ const SessionID_1 = require("./SessionID");
7
+ const StableID_1 = require("./StableID");
8
+ /**
9
+ * A handle to the PrecomputedEvaluationsContext that computes fields lazily on access.
10
+ * This avoids unnecessary computation (e.g., cloning the user) when only certain fields are needed.
11
+ * The handle is created once and reused; individual getters fetch current values on each access.
12
+ */
13
+ class PrecomputedEvaluationsContextHandle {
14
+ constructor(sdkKey, getOptions, getErrorBoundary, getValues, getUser, getSdkInstanceID) {
15
+ this._sdkKey = sdkKey;
16
+ this._getOptions = getOptions;
17
+ this._getErrorBoundary = getErrorBoundary;
18
+ this._getValues = getValues;
19
+ this._getUser = getUser;
20
+ this._getSdkInstanceID = getSdkInstanceID;
21
+ }
22
+ get sdkKey() {
23
+ return this._sdkKey;
24
+ }
25
+ get options() {
26
+ return this._getOptions();
27
+ }
28
+ get errorBoundary() {
29
+ return this._getErrorBoundary();
30
+ }
31
+ get values() {
32
+ return this._getValues();
33
+ }
34
+ get user() {
35
+ let user = (0, SafeJs_1._cloneObject)('StatsigUser', this._getUser());
36
+ if (user == null) {
37
+ Log_1.Log.error('Failed to clone user');
38
+ user = {};
39
+ }
40
+ return user;
41
+ }
42
+ /**
43
+ * Gets the current session.
44
+ * @param {boolean} [bumpSession=true] - Whether to bump/update the session timing. Set to false to read without affecting session state.
45
+ */
46
+ getSession(bumpSession = true) {
47
+ return SessionID_1.StatsigSession.get(this._sdkKey, bumpSession);
48
+ }
49
+ get stableID() {
50
+ return StableID_1.StableID.get(this._sdkKey);
51
+ }
52
+ get sdkInstanceID() {
53
+ return this._getSdkInstanceID();
54
+ }
55
+ /**
56
+ * Returns the full PrecomputedEvaluationsContext object.
57
+ * Use this when you need all fields at once.
58
+ * @param {boolean} [bumpSession=true] - Whether to bump the session when building the context.
59
+ */
60
+ toContext(bumpSession = true) {
61
+ return {
62
+ sdkKey: this.sdkKey,
63
+ options: this.options,
64
+ values: this.values,
65
+ user: this.user,
66
+ errorBoundary: this.errorBoundary,
67
+ session: this.getSession(bumpSession),
68
+ stableID: this.stableID,
69
+ sdkInstanceID: this.sdkInstanceID,
70
+ };
71
+ }
72
+ }
73
+ exports.PrecomputedEvaluationsContextHandle = PrecomputedEvaluationsContextHandle;
@@ -14,7 +14,7 @@ export declare const SessionID: {
14
14
  get: (sdkKey: string) => string;
15
15
  };
16
16
  export declare const StatsigSession: {
17
- get: (sdkKey: string) => StatsigSession;
17
+ get: (sdkKey: string, bumpSession?: boolean) => StatsigSession;
18
18
  overrideInitialSessionID: (override: string, sdkKey: string) => void;
19
19
  };
20
20
  export {};
package/src/SessionID.js CHANGED
@@ -15,12 +15,12 @@ exports.SessionID = {
15
15
  },
16
16
  };
17
17
  exports.StatsigSession = {
18
- get: (sdkKey) => {
18
+ get: (sdkKey, bumpSession = true) => {
19
19
  if (PROMISE_MAP[sdkKey] == null) {
20
20
  PROMISE_MAP[sdkKey] = _loadSession(sdkKey);
21
21
  }
22
22
  const session = PROMISE_MAP[sdkKey];
23
- return _bumpSession(session);
23
+ return bumpSession ? _bumpSession(session) : session;
24
24
  },
25
25
  overrideInitialSessionID: (override, sdkKey) => {
26
26
  PROMISE_MAP[sdkKey] = _overrideSessionId(override, sdkKey);
@@ -53,16 +53,14 @@ function _overrideSessionId(override, sdkKey) {
53
53
  };
54
54
  }
55
55
  function _bumpSession(session) {
56
+ var _a;
56
57
  const now = Date.now();
57
58
  const data = session.data;
58
59
  const sdkKey = session.sdkKey;
59
- if (_isIdle(data) || _hasRunTooLong(data)) {
60
+ const sessionExpired = _isIdle(data) || _hasRunTooLong(data);
61
+ if (sessionExpired) {
60
62
  data.sessionID = (0, UUID_1.getUUID)();
61
63
  data.startTime = now;
62
- const client = __STATSIG__ === null || __STATSIG__ === void 0 ? void 0 : __STATSIG__.instance(sdkKey);
63
- if (client) {
64
- client.$emt({ name: 'session_expired' });
65
- }
66
64
  }
67
65
  data.lastUpdate = now;
68
66
  _persistToStorage(data, session.sdkKey);
@@ -71,6 +69,9 @@ function _bumpSession(session) {
71
69
  const lifetime = now - data.startTime;
72
70
  session.idleTimeoutID = _createSessionTimeout(sdkKey, MAX_SESSION_IDLE_TIME);
73
71
  session.ageTimeoutID = _createSessionTimeout(sdkKey, MAX_SESSION_AGE - lifetime);
72
+ if (sessionExpired) {
73
+ (_a = __STATSIG__ === null || __STATSIG__ === void 0 ? void 0 : __STATSIG__.instance(sdkKey)) === null || _a === void 0 ? void 0 : _a.$emt({ name: 'session_expired' });
74
+ }
74
75
  return session;
75
76
  }
76
77
  function _createSessionTimeout(sdkKey, duration) {
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "3.31.0";
1
+ export declare const SDK_VERSION = "3.31.1";
2
2
  export type StatsigMetadata = {
3
3
  readonly [key: string]: string | undefined | null;
4
4
  readonly appVersion?: string;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StatsigMetadataProvider = exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = '3.31.0';
4
+ exports.SDK_VERSION = '3.31.1';
5
5
  let metadata = {
6
6
  sdkVersion: exports.SDK_VERSION,
7
7
  sdkType: 'js-mono', // js-mono is overwritten by Precomp and OnDevice clients
@@ -21,4 +21,5 @@ export type StatsigUserInternal = StatsigUser & {
21
21
  };
22
22
  export declare function _normalizeUser(original: StatsigUser, options?: AnyStatsigOptions | null, fallbackEnvironment?: string | null): StatsigUserInternal;
23
23
  export declare function _getFullUserHash(user: StatsigUser | undefined): string | null;
24
+ export declare function _getUnitIDFromUser(user: StatsigUser, idType: string): string | undefined;
24
25
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._getFullUserHash = exports._normalizeUser = void 0;
3
+ exports._getUnitIDFromUser = exports._getFullUserHash = exports._normalizeUser = void 0;
4
4
  const Hashing_1 = require("./Hashing");
5
5
  const Log_1 = require("./Log");
6
6
  const SafeJs_1 = require("./SafeJs");
@@ -23,3 +23,15 @@ function _getFullUserHash(user) {
23
23
  return user ? (0, Hashing_1._DJB2Object)(user) : null;
24
24
  }
25
25
  exports._getFullUserHash = _getFullUserHash;
26
+ function _getUnitIDFromUser(user, idType) {
27
+ var _a, _b, _c;
28
+ if (typeof idType !== 'string') {
29
+ return user.userID;
30
+ }
31
+ const lowered = idType.toLowerCase();
32
+ if (lowered !== 'userid') {
33
+ return (_b = (_a = user.customIDs) === null || _a === void 0 ? void 0 : _a[idType]) !== null && _b !== void 0 ? _b : (_c = user.customIDs) === null || _c === void 0 ? void 0 : _c[lowered];
34
+ }
35
+ return user.userID;
36
+ }
37
+ exports._getUnitIDFromUser = _getUnitIDFromUser;