@statsig/client-core 0.0.1-beta.22 → 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 +1 -1
- package/src/$_StatsigGlobal.d.ts +2 -1
- package/src/$_StatsigGlobal.js +0 -1
- package/src/ClientInterfaces.d.ts +15 -2
- package/src/InitializeResponse.d.ts +18 -0
- package/src/InitializeResponse.js +2 -0
- package/src/NetworkCore.js +13 -11
- package/src/SessionID.d.ts +1 -1
- package/src/SessionID.js +47 -5
- package/src/StatsigClientBase.d.ts +10 -2
- package/src/StatsigClientBase.js +27 -7
- package/src/StatsigClientEventEmitter.d.ts +3 -0
- package/src/StatsigMetadata.js +1 -1
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
package/package.json
CHANGED
package/src/$_StatsigGlobal.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { StatsigClientInterface } from
|
|
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;
|
package/src/$_StatsigGlobal.js
CHANGED
|
@@ -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 : {};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { DynamicConfigEvaluationOptions, ExperimentEvaluationOptions, FeatureGateEvaluationOptions, LayerEvaluationOptions } from './EvaluationOptions';
|
|
2
|
+
import { InitializeResponseWithUpdates } from './InitializeResponse';
|
|
2
3
|
import { StatsigClientEventEmitterInterface } from './StatsigClientEventEmitter';
|
|
3
4
|
import { EvaluationsDataAdapter, SpecsDataAdapter } from './StatsigDataAdapter';
|
|
4
5
|
import { StatsigEvent } from './StatsigEvent';
|
|
5
|
-
import { StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
|
|
6
|
+
import { StatsigOptionsCommon, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
|
|
6
7
|
import { DynamicConfig, Experiment, FeatureGate, Layer } from './StatsigTypes';
|
|
7
8
|
import { StatsigUser } from './StatsigUser';
|
|
8
9
|
export interface StatsigClientCommonInterface extends StatsigClientEventEmitterInterface {
|
|
9
10
|
initializeSync(): void;
|
|
10
11
|
initializeAsync(): Promise<void>;
|
|
11
12
|
shutdown(): Promise<void>;
|
|
13
|
+
flush(): Promise<void>;
|
|
12
14
|
updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
|
|
13
15
|
}
|
|
14
16
|
export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterface {
|
|
@@ -20,9 +22,20 @@ export interface OnDeviceEvaluationsInterface extends StatsigClientCommonInterfa
|
|
|
20
22
|
getLayer(name: string, user: StatsigUser, options?: LayerEvaluationOptions): Layer;
|
|
21
23
|
logEvent(event: StatsigEvent, user: StatsigUser): void;
|
|
22
24
|
}
|
|
25
|
+
export type PrecomputedEvaluationsContext = {
|
|
26
|
+
sdkKey: string;
|
|
27
|
+
options: StatsigOptionsCommon;
|
|
28
|
+
values: InitializeResponseWithUpdates | null;
|
|
29
|
+
user: StatsigUser;
|
|
30
|
+
};
|
|
31
|
+
export type PrecomputedEvaluationsAsyncContext = {
|
|
32
|
+
sessionID: string;
|
|
33
|
+
stableID: string;
|
|
34
|
+
} & PrecomputedEvaluationsContext;
|
|
23
35
|
export interface PrecomputedEvaluationsInterface extends StatsigClientCommonInterface {
|
|
24
36
|
readonly dataAdapter: EvaluationsDataAdapter;
|
|
25
|
-
|
|
37
|
+
getAsyncContext(): Promise<PrecomputedEvaluationsAsyncContext>;
|
|
38
|
+
getContext(): PrecomputedEvaluationsContext;
|
|
26
39
|
updateUserSync(user: StatsigUser): void;
|
|
27
40
|
updateUserAsync(user: StatsigUser): Promise<void>;
|
|
28
41
|
checkGate(name: string, options?: FeatureGateEvaluationOptions): boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DynamicConfigEvaluation, GateEvaluation, LayerEvaluation } from './EvaluationTypes';
|
|
2
|
+
type SessionReplayFields = {
|
|
3
|
+
can_record_session?: boolean;
|
|
4
|
+
session_recording_rate?: number;
|
|
5
|
+
};
|
|
6
|
+
export type InitializeResponseWithUpdates = SessionReplayFields & {
|
|
7
|
+
feature_gates: Record<string, GateEvaluation>;
|
|
8
|
+
dynamic_configs: Record<string, DynamicConfigEvaluation>;
|
|
9
|
+
layer_configs: Record<string, LayerEvaluation>;
|
|
10
|
+
time: number;
|
|
11
|
+
has_updates: true;
|
|
12
|
+
hash_used: 'none' | 'sha256' | 'djb2';
|
|
13
|
+
derived_fields?: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
export type InitializeResponse = InitializeResponseWithUpdates | {
|
|
16
|
+
has_updates: false;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
package/src/NetworkCore.js
CHANGED
|
@@ -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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
});
|
package/src/SessionID.d.ts
CHANGED
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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
|
+
}
|
|
@@ -9,17 +9,25 @@ import { DataAdapterResult, EvaluationsDataAdapter, SpecsDataAdapter } from './S
|
|
|
9
9
|
import { StatsigEventInternal } from './StatsigEvent';
|
|
10
10
|
import { StatsigOptionsCommon, StatsigRuntimeMutableOptions } from './StatsigOptionsCommon';
|
|
11
11
|
export type StatsigClientEmitEventFunc = (event: StatsigClientEvent) => void;
|
|
12
|
+
export type StatsigContext = {
|
|
13
|
+
sdkKey: string;
|
|
14
|
+
options: StatsigOptionsCommon;
|
|
15
|
+
sessionID: string;
|
|
16
|
+
values: unknown;
|
|
17
|
+
};
|
|
12
18
|
export declare abstract class StatsigClientBase<TAdapter extends EvaluationsDataAdapter | SpecsDataAdapter> implements StatsigClientEventEmitterInterface {
|
|
13
|
-
protected readonly _sdkKey: string;
|
|
14
19
|
loadingStatus: StatsigLoadingStatus;
|
|
15
20
|
readonly dataAdapter: TAdapter;
|
|
21
|
+
protected readonly _sdkKey: string;
|
|
22
|
+
protected readonly _options: StatsigOptionsCommon;
|
|
16
23
|
protected readonly _errorBoundary: ErrorBoundary;
|
|
17
24
|
protected readonly _logger: EventLogger;
|
|
18
25
|
protected readonly _overrideAdapter: OverrideAdapter | null;
|
|
19
26
|
private _listeners;
|
|
20
|
-
constructor(
|
|
27
|
+
constructor(sdkKey: string, adapter: TAdapter, network: NetworkCore, options: StatsigOptionsCommon | null);
|
|
21
28
|
updateRuntimeOptions(options: StatsigRuntimeMutableOptions): void;
|
|
22
29
|
flush(): Promise<void>;
|
|
30
|
+
shutdown(): Promise<void>;
|
|
23
31
|
on<T extends StatsigClientEventName>(event: T, listener: StatsigClientEventCallback<T>): void;
|
|
24
32
|
off<T extends StatsigClientEventName>(event: T, listener: StatsigClientEventCallback<T>): void;
|
|
25
33
|
protected _emit(event: StatsigClientEvent): void;
|
package/src/StatsigClientBase.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
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.StatsigClientBase = void 0;
|
|
4
13
|
require("./$_StatsigGlobal");
|
|
@@ -8,36 +17,47 @@ const Log_1 = require("./Log");
|
|
|
8
17
|
const StableID_1 = require("./StableID");
|
|
9
18
|
const StorageProvider_1 = require("./StorageProvider");
|
|
10
19
|
class StatsigClientBase {
|
|
11
|
-
constructor(
|
|
20
|
+
constructor(sdkKey, adapter, network, options) {
|
|
12
21
|
var _a, _b, _c;
|
|
13
|
-
this._sdkKey = _sdkKey;
|
|
14
22
|
this.loadingStatus = 'Uninitialized';
|
|
15
23
|
this._listeners = {};
|
|
24
|
+
this._sdkKey = sdkKey;
|
|
25
|
+
this._options = options !== null && options !== void 0 ? options : {};
|
|
16
26
|
(options === null || options === void 0 ? void 0 : options.disableStorage) && StorageProvider_1.Storage.setDisabled(true);
|
|
17
27
|
(options === null || options === void 0 ? void 0 : options.overrideStableID) &&
|
|
18
|
-
StableID_1.StableID.setOverride(options.overrideStableID,
|
|
28
|
+
StableID_1.StableID.setOverride(options.overrideStableID, sdkKey);
|
|
19
29
|
Log_1.Log.level = (_a = options === null || options === void 0 ? void 0 : options.logLevel) !== null && _a !== void 0 ? _a : Log_1.LogLevel.Warn;
|
|
20
30
|
this._overrideAdapter = (_b = options === null || options === void 0 ? void 0 : options.overrideAdapter) !== null && _b !== void 0 ? _b : null;
|
|
21
|
-
this._logger = new EventLogger_1.EventLogger(
|
|
22
|
-
this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(
|
|
31
|
+
this._logger = new EventLogger_1.EventLogger(sdkKey, this._emit.bind(this), network, options);
|
|
32
|
+
this._errorBoundary = new ErrorBoundary_1.ErrorBoundary(sdkKey);
|
|
23
33
|
__STATSIG__ = __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {};
|
|
24
34
|
const instances = (_c = __STATSIG__.instances) !== null && _c !== void 0 ? _c : {};
|
|
25
|
-
|
|
35
|
+
const inst = this;
|
|
36
|
+
instances[sdkKey] = inst;
|
|
26
37
|
__STATSIG__.instances = instances;
|
|
38
|
+
__STATSIG__.lastInstance = inst;
|
|
27
39
|
this.dataAdapter = adapter;
|
|
28
|
-
this.dataAdapter.attach(
|
|
40
|
+
this.dataAdapter.attach(sdkKey, options);
|
|
29
41
|
}
|
|
30
42
|
updateRuntimeOptions(options) {
|
|
31
43
|
if (options.disableLogging != null) {
|
|
44
|
+
this._options.disableLogging = options.disableLogging;
|
|
32
45
|
this._logger.setLoggingDisabled(options.disableLogging);
|
|
33
46
|
}
|
|
34
47
|
if (options.disableStorage != null) {
|
|
48
|
+
this._options.disableStorage = options.disableStorage;
|
|
35
49
|
StorageProvider_1.Storage.setDisabled(options.disableStorage);
|
|
36
50
|
}
|
|
37
51
|
}
|
|
38
52
|
flush() {
|
|
39
53
|
return this._logger.flush();
|
|
40
54
|
}
|
|
55
|
+
shutdown() {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
this._emit({ name: 'pre_shutdown' });
|
|
58
|
+
yield this._logger.shutdown();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
41
61
|
on(event, listener) {
|
|
42
62
|
if (!this._listeners[event]) {
|
|
43
63
|
this._listeners[event] = [];
|
|
@@ -13,6 +13,7 @@ type EventNameToEventDataMap = {
|
|
|
13
13
|
logs_flushed: {
|
|
14
14
|
events: Record<string, unknown>[];
|
|
15
15
|
};
|
|
16
|
+
pre_shutdown: object;
|
|
16
17
|
gate_evaluation: {
|
|
17
18
|
gate: FeatureGate;
|
|
18
19
|
};
|
|
@@ -35,6 +36,8 @@ type EventNameToEventDataMap = {
|
|
|
35
36
|
*
|
|
36
37
|
* `logs_flushed` - When queued StatsigEvents are flushed to Statsig servers.
|
|
37
38
|
*
|
|
39
|
+
* `pre_shutdown` - Fired just before the SDK is shutdown
|
|
40
|
+
*
|
|
38
41
|
* `gate_evaluation` - Fired when any gate is checked from the Statsig client.
|
|
39
42
|
*
|
|
40
43
|
* `dynamic_config_evaluation` - Fired when any dyanamic config is checked from the Statsig client.
|
package/src/StatsigMetadata.js
CHANGED
|
@@ -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.
|
|
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
|
package/src/index.d.ts
CHANGED
|
@@ -10,10 +10,12 @@ export * from './ErrorBoundary';
|
|
|
10
10
|
export * from './EvaluationOptions';
|
|
11
11
|
export * from './EvaluationTypes';
|
|
12
12
|
export * from './Hashing';
|
|
13
|
+
export * from './InitializeResponse';
|
|
13
14
|
export * from './Log';
|
|
14
15
|
export * from './Monitoring';
|
|
15
16
|
export * from './NetworkCore';
|
|
16
17
|
export * from './OverrideAdapter';
|
|
18
|
+
export * from './SessionID';
|
|
17
19
|
export * from './StableID';
|
|
18
20
|
export * from './StatsigClientBase';
|
|
19
21
|
export * from './StatsigClientEventEmitter';
|
package/src/index.js
CHANGED
|
@@ -30,10 +30,12 @@ __exportStar(require("./ErrorBoundary"), exports);
|
|
|
30
30
|
__exportStar(require("./EvaluationOptions"), exports);
|
|
31
31
|
__exportStar(require("./EvaluationTypes"), exports);
|
|
32
32
|
__exportStar(require("./Hashing"), exports);
|
|
33
|
+
__exportStar(require("./InitializeResponse"), exports);
|
|
33
34
|
__exportStar(require("./Log"), exports);
|
|
34
35
|
__exportStar(require("./Monitoring"), exports);
|
|
35
36
|
__exportStar(require("./NetworkCore"), exports);
|
|
36
37
|
__exportStar(require("./OverrideAdapter"), exports);
|
|
38
|
+
__exportStar(require("./SessionID"), exports);
|
|
37
39
|
__exportStar(require("./StableID"), exports);
|
|
38
40
|
__exportStar(require("./StatsigClientBase"), exports);
|
|
39
41
|
__exportStar(require("./StatsigClientEventEmitter"), exports);
|