@statsig/client-core 0.0.1-beta.23 → 0.0.1-beta.24

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.23",
3
+ "version": "0.0.1-beta.24",
4
4
  "dependencies": {},
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -1,7 +1,8 @@
1
- import { StatsigClientInterface } from "./ClientInterfaces";
1
+ import { StatsigClientInterface } from './ClientInterfaces';
2
2
  export type StatsigGlobal = {
3
3
  [key: string]: unknown;
4
4
  instances?: Record<string, StatsigClientInterface>;
5
+ lastInstance?: StatsigClientInterface;
5
6
  };
6
7
  declare global {
7
8
  let __STATSIG__: StatsigGlobal | undefined;
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4
3
  var _a, _b, _c;
5
4
  Object.defineProperty(exports, "__esModule", { value: true });
6
5
  const _window = typeof window !== 'undefined' ? window : {};
@@ -25,12 +25,16 @@ export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterfa
25
25
  export type PrecomputedEvaluationsContext = {
26
26
  sdkKey: string;
27
27
  options: StatsigOptionsCommon;
28
- sessionID: string;
29
28
  values: InitializeResponseWithUpdates | null;
30
29
  user: StatsigUser;
31
30
  };
31
+ export type PrecomputedEvaluationsAsyncContext = {
32
+ sessionID: string;
33
+ stableID: string;
34
+ } & PrecomputedEvaluationsContext;
32
35
  export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
33
36
  readonly dataAdapter: EvaluationsDataAdapter;
37
+ getAsyncContext(): Promise<PrecomputedEvaluationsAsyncContext>;
34
38
  getContext(): PrecomputedEvaluationsContext;
35
39
  updateUserSync(user: StatsigUser): void;
36
40
  updateUserAsync(user: StatsigUser): Promise<void>;
@@ -40,7 +40,7 @@ class NetworkCore {
40
40
  }
41
41
  beacon(args) {
42
42
  return __awaiter(this, void 0, void 0, function* () {
43
- const url = this._getPopulatedURL(args);
43
+ const url = yield this._getPopulatedURL(args);
44
44
  const body = yield this._getPopulatedBody(args);
45
45
  return navigator.sendBeacon(url, body);
46
46
  });
@@ -51,7 +51,7 @@ class NetworkCore {
51
51
  const { method, body, retries } = args;
52
52
  const controller = new AbortController();
53
53
  const handle = setTimeout(() => controller.abort(`Timeout of ${this._timeout}ms expired.`), this._timeout);
54
- const url = this._getPopulatedURL(args);
54
+ const url = yield this._getPopulatedURL(args);
55
55
  let response = null;
56
56
  try {
57
57
  response = yield fetch(url, {
@@ -94,20 +94,22 @@ class NetworkCore {
94
94
  });
95
95
  }
96
96
  _getPopulatedURL(args) {
97
- const metadata = StatsigMetadata_1.StatsigMetadataProvider.get();
98
- const params = Object.assign({ k: args.sdkKey, st: metadata.sdkType, sv: metadata.sdkVersion, t: String(Date.now()), sid: SessionID_1.SessionID.get(args.sdkKey) }, args.params);
99
- const query = Object.entries(params)
100
- .map(([key, value]) => {
101
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
102
- })
103
- .join('&');
104
- return `${args.url}${query ? `?${query}` : ''}`;
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ const metadata = StatsigMetadata_1.StatsigMetadataProvider.get();
99
+ const params = Object.assign({ k: args.sdkKey, st: metadata.sdkType, sv: metadata.sdkVersion, t: String(Date.now()), sid: yield SessionID_1.SessionID.get(args.sdkKey) }, args.params);
100
+ const query = Object.entries(params)
101
+ .map(([key, value]) => {
102
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
103
+ })
104
+ .join('&');
105
+ return `${args.url}${query ? `?${query}` : ''}`;
106
+ });
105
107
  }
106
108
  _getPopulatedBody(args) {
107
109
  return __awaiter(this, void 0, void 0, function* () {
108
110
  const { data } = args;
109
111
  const stableID = yield StableID_1.StableID.get(args.sdkKey);
110
- const sessionID = SessionID_1.SessionID.get(args.sdkKey);
112
+ const sessionID = yield SessionID_1.SessionID.get(args.sdkKey);
111
113
  return JSON.stringify(Object.assign(Object.assign({}, data), { statsigMetadata: Object.assign(Object.assign({}, StatsigMetadata_1.StatsigMetadataProvider.get()), { stableID,
112
114
  sessionID }) }));
113
115
  });
@@ -1,3 +1,3 @@
1
1
  export declare const SessionID: {
2
- get: (sdkKey: string) => string;
2
+ get: (sdkKey: string) => Promise<string>;
3
3
  };
package/src/SessionID.js CHANGED
@@ -1,13 +1,55 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.SessionID = void 0;
13
+ const Hashing_1 = require("./Hashing");
14
+ const Log_1 = require("./Log");
15
+ const StorageProvider_1 = require("./StorageProvider");
4
16
  const UUID_1 = require("./UUID");
5
17
  const SESSION_ID_MAP = {};
18
+ const MAX_SESSION_IDLE_TIME = 10 * 60 * 1000; // 10 minutes
19
+ const MAX_SESSION_AGE = 4 * 60 * 60 * 1000; // 4 hours
6
20
  exports.SessionID = {
7
- get: (sdkKey) => {
8
- if (SESSION_ID_MAP[sdkKey] == null) {
9
- SESSION_ID_MAP[sdkKey] = (0, UUID_1.getUUID)();
21
+ get: (sdkKey) => __awaiter(void 0, void 0, void 0, function* () {
22
+ var _a;
23
+ let session = SESSION_ID_MAP[sdkKey];
24
+ if (session == null) {
25
+ session = (_a = (yield _loadFromStorage(sdkKey))) !== null && _a !== void 0 ? _a : {
26
+ sessionID: (0, UUID_1.getUUID)(),
27
+ startTime: Date.now(),
28
+ lastUpdate: Date.now(),
29
+ };
30
+ SESSION_ID_MAP[sdkKey] = session;
31
+ }
32
+ if (Date.now() - session.startTime > MAX_SESSION_AGE ||
33
+ Date.now() - session.lastUpdate > MAX_SESSION_IDLE_TIME) {
34
+ session.sessionID = (0, UUID_1.getUUID)();
35
+ session.startTime = Date.now();
10
36
  }
11
- return SESSION_ID_MAP[sdkKey];
12
- },
37
+ session.lastUpdate = Date.now();
38
+ _persistToStorage(session, sdkKey);
39
+ SESSION_ID_MAP[sdkKey] = session;
40
+ return session.sessionID;
41
+ }),
13
42
  };
43
+ function _getSessionIDStorageKey(sdkKey) {
44
+ return `statsig.session_id.${(0, Hashing_1.DJB2)(sdkKey)}`;
45
+ }
46
+ function _persistToStorage(session, sdkKey) {
47
+ const storageKey = _getSessionIDStorageKey(sdkKey);
48
+ (0, StorageProvider_1.setObjectInStorage)(storageKey, session).catch(() => {
49
+ Log_1.Log.warn('Failed to save SessionID');
50
+ });
51
+ }
52
+ function _loadFromStorage(sdkKey) {
53
+ const storageKey = _getSessionIDStorageKey(sdkKey);
54
+ return (0, StorageProvider_1.getObjectFromStorage)(storageKey);
55
+ }
@@ -32,8 +32,10 @@ class StatsigClientBase {
32
32
  this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(sdkKey);
33
33
  __STATSIG__ = __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {};
34
34
  const instances = (_c = __STATSIG__.instances) !== null && _c !== void 0 ? _c : {};
35
- instances[sdkKey] = this;
35
+ const inst = this;
36
+ instances[sdkKey] = inst;
36
37
  __STATSIG__.instances = instances;
38
+ __STATSIG__.lastInstance = inst;
37
39
  this.dataAdapter = adapter;
38
40
  this.dataAdapter.attach(sdkKey, options);
39
41
  }
@@ -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.23';
4
+ const SDK_VERSION = '0.0.1-beta.24';
5
5
  let metadata = {
6
6
  sdkVersion: SDK_VERSION,
7
7
  sdkType: 'js-mono', // js-mono is overwritten by Precomp and OnDevice clients