@base44-preview/sdk 0.8.48-pr.280.dac0f98 → 0.8.48-pr.281.97e1467

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/dist/client.js CHANGED
@@ -14,9 +14,6 @@ import { createAppModule } from "./modules/app.js";
14
14
  import { createUsersModule } from "./modules/users.js";
15
15
  import { RoomsSocket } from "./utils/socket-utils.js";
16
16
  import { createAnalyticsModule } from "./modules/analytics.js";
17
- import { createExperimentsModule } from "./modules/experiments.js";
18
- import { createExposureTracker } from "./modules/experiment-exposures.js";
19
- import { EXPERIMENTS_CONTEXT_HEADER, getBrowserExperimentsContext, readExperimentsContext } from "./modules/experiments-context.js";
20
17
  import { createActorsModule, resolveActorsHost, } from "./modules/actors.js";
21
18
  /**
22
19
  * Creates a Base44 client.
@@ -56,11 +53,10 @@ import { createActorsModule, resolveActorsHost, } from "./modules/actors.js";
56
53
  * ```
57
54
  */
58
55
  export function createClient(config) {
59
- var _a, _b, _c, _d, _e, _f, _g;
56
+ var _a, _b, _c, _d;
60
57
  const { serverUrl = "https://base44.app", appId, analytics, token, serviceToken, requiresAuth = false, appBaseUrl, options, functionsVersion, headers: optionalHeaders, } = config;
61
58
  // Normalize appBaseUrl to always be a string (empty if not provided or invalid)
62
59
  const normalizedAppBaseUrl = typeof appBaseUrl === "string" ? appBaseUrl : "";
63
- const experimentsContext = (_a = config.experiments) !== null && _a !== void 0 ? _a : getBrowserExperimentsContext(appId);
64
60
  const socketConfig = {
65
61
  serverUrl,
66
62
  mountPath: "/ws-user-apps/socket.io/",
@@ -77,14 +73,9 @@ export function createClient(config) {
77
73
  }
78
74
  return socket;
79
75
  };
80
- const { [EXPERIMENTS_CONTEXT_HEADER]: inheritedExperimentsContext, ...requestHeaders } = optionalHeaders !== null && optionalHeaders !== void 0 ? optionalHeaders : {};
81
76
  const headers = {
82
- ...requestHeaders,
77
+ ...optionalHeaders,
83
78
  "X-App-Id": String(appId),
84
- ...(experimentsContext ? {
85
- "Base44-Visitor-Id": experimentsContext.identity.visitorId,
86
- "Base44-Experiment-Preview": JSON.stringify((_b = experimentsContext.preview) !== null && _b !== void 0 ? _b : {}),
87
- } : {}),
88
79
  };
89
80
  const functionHeaders = functionsVersion
90
81
  ? {
@@ -130,24 +121,10 @@ export function createClient(config) {
130
121
  baseURL: `${serverUrl}/api`,
131
122
  headers,
132
123
  });
133
- const exposureTracker = createExposureTracker({
134
- axiosClient,
135
- appId,
136
- enabled: (_c = analytics === null || analytics === void 0 ? void 0 : analytics.enabled) !== null && _c !== void 0 ? _c : true,
137
- source: typeof window === "undefined" ? "backend" : "browser",
138
- pageUrl: experimentsContext === null || experimentsContext === void 0 ? void 0 : experimentsContext.pageUrl,
139
- });
140
- const experiments = createExperimentsModule({
141
- getAuth: () => userAuthModule,
142
- trackExposure: exposureTracker.track,
143
- flushExposures: exposureTracker.flush,
144
- context: experimentsContext,
145
- });
146
124
  const userAuthModule = createAuthModule(axiosClient, functionsAxiosClient, appId, {
147
125
  appBaseUrl: normalizedAppBaseUrl,
148
126
  serverUrl,
149
127
  token,
150
- onAuthStateChange: experiments.onAuthStateChange,
151
128
  });
152
129
  // Apply the access token before any module that may issue authenticated
153
130
  // requests during construction (notably analytics, which fires an init
@@ -159,19 +136,11 @@ export function createClient(config) {
159
136
  userAuthModule.setToken(accessToken);
160
137
  }
161
138
  }
162
- if (experimentsContext) {
163
- const { userId, status } = experimentsContext.identity;
164
- // The document's cookie identity may differ from this client's localStorage token.
165
- const needsClientIdentity = typeof window !== "undefined" && userAuthModule.hasToken() &&
166
- experimentsContext.config.experiments.some((experiment) => experiment.assign_by === "user");
167
- experiments.onAuthStateChange(status === "pending" || needsClientIdentity ? { status: "pending" } :
168
- userId ? { status: "authenticated", userId } : { status: "anonymous" });
169
- }
170
139
  const actorsModule = createActorsModule({
171
140
  appId,
172
141
  // serverUrl is often relative/empty (same-origin app); the proxy-fallback
173
142
  // URL needs an absolute host, so fall back to the page origin.
174
- host: resolveActorsHost(serverUrl, typeof window !== "undefined" ? (_d = window.location) === null || _d === void 0 ? void 0 : _d.origin : undefined),
143
+ host: resolveActorsHost(serverUrl, typeof window !== "undefined" ? (_a = window.location) === null || _a === void 0 ? void 0 : _a.origin : undefined),
175
144
  functionsVersion,
176
145
  getAuthToken: () => token || getAccessToken(),
177
146
  mintConnectionToken: async (actorName, room, connectionId) => {
@@ -199,7 +168,6 @@ export function createClient(config) {
199
168
  integrations: createIntegrationsModule(axiosClient, appId),
200
169
  connectors: createUserConnectorsModule(axiosClient, appId),
201
170
  auth: userAuthModule,
202
- experiments: experiments.module,
203
171
  functions: createFunctionsModule(functionsAxiosClient, appId, {
204
172
  getAuthHeaders: () => {
205
173
  const headers = {};
@@ -210,7 +178,7 @@ export function createClient(config) {
210
178
  }
211
179
  return headers;
212
180
  },
213
- baseURL: (_e = functionsAxiosClient.defaults) === null || _e === void 0 ? void 0 : _e.baseURL,
181
+ baseURL: (_b = functionsAxiosClient.defaults) === null || _b === void 0 ? void 0 : _b.baseURL,
214
182
  }),
215
183
  agents: createAgentsModule({
216
184
  axios: axiosClient,
@@ -228,14 +196,11 @@ export function createClient(config) {
228
196
  serverUrl,
229
197
  appId,
230
198
  userAuthModule,
231
- enabled: (_f = analytics === null || analytics === void 0 ? void 0 : analytics.enabled) !== null && _f !== void 0 ? _f : true,
232
- getVisitorId: experiments.visitorId,
233
- experimentsContext,
199
+ enabled: (_c = analytics === null || analytics === void 0 ? void 0 : analytics.enabled) !== null && _c !== void 0 ? _c : true,
234
200
  }),
235
201
  actors: actorsModule.module,
236
202
  cleanup: () => {
237
203
  userModules.analytics.cleanup();
238
- experiments.cleanup();
239
204
  actorsModule.closeAll();
240
205
  if (socket) {
241
206
  socket.disconnect();
@@ -260,7 +225,7 @@ export function createClient(config) {
260
225
  }
261
226
  return headers;
262
227
  },
263
- baseURL: (_g = serviceRoleFunctionsAxiosClient.defaults) === null || _g === void 0 ? void 0 : _g.baseURL,
228
+ baseURL: (_d = serviceRoleFunctionsAxiosClient.defaults) === null || _d === void 0 ? void 0 : _d.baseURL,
264
229
  }),
265
230
  agents: createAgentsModule({
266
231
  axios: serviceRoleAxiosClient,
@@ -303,10 +268,7 @@ export function createClient(config) {
303
268
  appId: String(appId),
304
269
  serverUrl,
305
270
  functionsVersion,
306
- platformHeaders: {
307
- ...headers,
308
- ...(inheritedExperimentsContext ? { [EXPERIMENTS_CONTEXT_HEADER]: inheritedExperimentsContext } : {}),
309
- },
271
+ platformHeaders: optionalHeaders,
310
272
  }),
311
273
  /**
312
274
  * Sets a new authentication token for all subsequent requests.
@@ -458,10 +420,6 @@ export function createClientFromRequest(request) {
458
420
  }
459
421
  // Prepare additional headers to propagate
460
422
  const additionalHeaders = {};
461
- const encodedExperiments = request.headers.get(EXPERIMENTS_CONTEXT_HEADER);
462
- const experimentsContext = readExperimentsContext(encodedExperiments, appId);
463
- if (experimentsContext && encodedExperiments)
464
- additionalHeaders[EXPERIMENTS_CONTEXT_HEADER] = encodedExperiments;
465
423
  if (stateHeader) {
466
424
  additionalHeaders["Base44-State"] = stateHeader;
467
425
  }
@@ -482,6 +440,5 @@ export function createClientFromRequest(request) {
482
440
  serviceToken: serviceRoleToken,
483
441
  functionsVersion: functionsVersion !== null && functionsVersion !== void 0 ? functionsVersion : undefined,
484
442
  headers: additionalHeaders,
485
- experiments: experimentsContext ? { ...experimentsContext, pageUrl: request.url ? new URL(request.url).pathname : "/" } : undefined,
486
443
  });
487
444
  }
@@ -9,8 +9,6 @@ import type { AiGatewayModule } from "./modules/ai-gateway.types.js";
9
9
  import type { AppLogsModule } from "./modules/app-logs.types.js";
10
10
  import type { AppModule } from "./modules/app.types.js";
11
11
  import type { AnalyticsModule } from "./modules/analytics.types.js";
12
- import type { ExperimentsModule } from "./modules/experiments.types.js";
13
- import type { ExperimentsContext } from "./modules/experiments-config.types.js";
14
12
  import type { ActorsModule } from "./modules/actors.types.js";
15
13
  import type { FetchWithAuthInit } from "./utils/fetch-with-auth.js";
16
14
  /**
@@ -41,9 +39,9 @@ export interface CreateClientAnalyticsConfig {
41
39
  /**
42
40
  * Whether app analytics is enabled for this client.
43
41
  *
44
- * When disabled, automatic analytics, experiment exposures and calls to
45
- * `analytics.track()` are no-ops. The SDK does not create an analytics session
46
- * identifier, start heartbeat timers, or send analytics requests.
42
+ * When disabled, automatic analytics and calls to `analytics.track()` are
43
+ * no-ops. The SDK does not create an analytics session identifier, start
44
+ * heartbeat timers, or send analytics requests.
47
45
  *
48
46
  * @defaultValue `true`
49
47
  */
@@ -81,12 +79,6 @@ export interface CreateClientConfig {
81
79
  * Omit this option to preserve the default analytics behavior.
82
80
  */
83
81
  analytics?: CreateClientAnalyticsConfig;
84
- /**
85
- * Platform-validated context for local flag evaluation. Request-scoped on servers.
86
- * Automatically read from the platform bootstrap in browsers and trusted headers
87
- * by createClientFromRequest(). Not an authorization credential.
88
- */
89
- experiments?: ExperimentsContext;
90
82
  /**
91
83
  * User authentication token. Used to authenticate as a specific user.
92
84
  *
@@ -142,8 +134,6 @@ export interface Base44Client {
142
134
  connectors: UserConnectorsModule;
143
135
  /** {@link EntitiesModule | Entities module} for CRUD operations on your data models. */
144
136
  entities: EntitiesModule;
145
- /** {@link ExperimentsModule | Experiments module} for local feature flags and exposures. */
146
- experiments: ExperimentsModule;
147
137
  /** {@link FunctionsModule | Functions module} for invoking custom backend functions. */
148
138
  functions: FunctionsModule;
149
139
  /** {@link IntegrationsModule | Integrations module} for calling pre-built integration endpoints. */
package/dist/index.d.ts CHANGED
@@ -4,9 +4,6 @@ import { getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl } from
4
4
  export { createClient, createClientFromRequest, Base44Error, getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, };
5
5
  export type { Base44Client, CreateClientAnalyticsConfig, CreateClientConfig, CreateClientOptions, Base44ErrorJSON, };
6
6
  export * from "./types.js";
7
- export { evaluateExperiments } from "./modules/experiments-evaluator.js";
8
- export type { ExperimentsConfig, ExperimentsContext, ExperimentsIdentity } from "./modules/experiments-config.types.js";
9
- export type { ExperimentsModule, ExperimentsSnapshot, } from "./modules/experiments.types.js";
10
7
  export type { DeleteManyResult, DeleteResult, EntitiesModule, EntityFilterOperators, EntityFilterQuery, EntityFilterValue, EntityHandler, EntityRecord, EntityTypeRegistry, ImportResult, RealtimeEventType, RealtimeEvent, RealtimeCallback, SortField, UpdateManyResult, } from "./modules/entities.types.js";
11
8
  export type { AuthModule, LoginResponse, RegisterParams, VerifyOtpParams, ChangePasswordParams, ResetPasswordParams, User, } from "./modules/auth.types.js";
12
9
  export type { IntegrationsModule, IntegrationEndpointFunction, CoreIntegrations, InvokeLLMParams, GenerateImageParams, GenerateImageResult, UploadFileParams, UploadFileResult, SendEmailParams, SendEmailResult, ExtractDataFromUploadedFileParams, ExtractDataFromUploadedFileResult, UploadPrivateFileParams, UploadPrivateFileResult, CreateFileSignedUrlParams, CreateFileSignedUrlResult, } from "./modules/integrations.types.js";
package/dist/index.js CHANGED
@@ -3,5 +3,4 @@ import { Base44Error } from "./utils/axios-client.js";
3
3
  import { getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, } from "./utils/auth-utils.js";
4
4
  export { createClient, createClientFromRequest, Base44Error, getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, };
5
5
  export * from "./types.js";
6
- export { evaluateExperiments } from "./modules/experiments-evaluator.js";
7
6
  export { Actor } from "./actor.js";
@@ -1,7 +1,6 @@
1
1
  import { AxiosInstance } from "axios";
2
- import { TrackEventParams, TrackEventData, AnalyticsModuleOptions, SessionContext } from "./analytics.types";
2
+ import { TrackEventParams, AnalyticsModuleOptions } from "./analytics.types";
3
3
  import type { InternalAuthModule } from "./auth.types";
4
- import type { ExperimentsContext } from "./experiments-config.types.js";
5
4
  export declare const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__";
6
5
  export declare const ANALYTICS_INITIALIZATION_EVENT_NAME = "__initialization_event__";
7
6
  export declare const ANALYTICS_SESSION_DURATION_EVENT_NAME = "__session_duration_event__";
@@ -13,22 +12,8 @@ export interface AnalyticsModuleArgs {
13
12
  appId: string;
14
13
  userAuthModule: InternalAuthModule;
15
14
  enabled: boolean;
16
- getVisitorId?: () => string | undefined;
17
- experimentsContext?: ExperimentsContext;
18
15
  }
19
- /** @internal */
20
- export declare function isAnalyticsEnabled(enabled: boolean, state?: {
21
- requestsQueue: TrackEventData[];
22
- isProcessing: boolean;
23
- isHeartBeatProcessing: boolean;
24
- wasInitializationTracked: boolean;
25
- sessionContext: SessionContext | null;
26
- sessionContextPromise: Promise<SessionContext> | null;
27
- sessionStartTime: string | null;
28
- fallbackSessionId: string | null;
29
- config: Required<AnalyticsModuleOptions>;
30
- }): boolean;
31
- export declare const createAnalyticsModule: ({ axiosClient, serverUrl, appId, userAuthModule, enabled, getVisitorId, experimentsContext, }: AnalyticsModuleArgs) => {
16
+ export declare const createAnalyticsModule: ({ axiosClient, serverUrl, appId, userAuthModule, enabled, }: AnalyticsModuleArgs) => {
32
17
  track: (params: TrackEventParams) => void;
33
18
  cleanup: () => void;
34
19
  };
@@ -42,16 +27,6 @@ export declare const createAnalyticsModule: ({ axiosClient, serverUrl, appId, us
42
27
  *
43
28
  * @internal
44
29
  */
45
- export declare function resetAnalyticsSessionContext(axiosClient?: AxiosInstance): void;
30
+ export declare function resetAnalyticsSessionContext(): void;
46
31
  export declare function getAnalyticsConfigFromUrlParams(): AnalyticsModuleOptions | undefined;
47
- export declare function getAnalyticsSessionId(state?: {
48
- requestsQueue: TrackEventData[];
49
- isProcessing: boolean;
50
- isHeartBeatProcessing: boolean;
51
- wasInitializationTracked: boolean;
52
- sessionContext: SessionContext | null;
53
- sessionContextPromise: Promise<SessionContext> | null;
54
- sessionStartTime: string | null;
55
- fallbackSessionId: string | null;
56
- config: Required<AnalyticsModuleOptions>;
57
- }): string;
32
+ export declare function getAnalyticsSessionId(): string;
@@ -1,6 +1,5 @@
1
1
  import { getSharedInstance } from "../utils/sharedInstance.js";
2
2
  import { generateUuid, isReactNative } from "../utils/common.js";
3
- import { getExperimentsRuntime } from "./experiments-runtime.types.js";
4
3
  export const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__";
5
4
  export const ANALYTICS_INITIALIZATION_EVENT_NAME = "__initialization_event__";
6
5
  export const ANALYTICS_SESSION_DURATION_EVENT_NAME = "__session_duration_event__";
@@ -18,41 +17,31 @@ const defaultConfiguration = {
18
17
  //// shared queue for analytics events ////
19
18
  ///////////////////////////////////////////////
20
19
  const ANALYTICS_SHARED_STATE_NAME = "analytics";
21
- function createAnalyticsState() {
22
- return {
23
- requestsQueue: [],
24
- isProcessing: false,
25
- isHeartBeatProcessing: false,
26
- wasInitializationTracked: false,
27
- sessionContext: null,
28
- sessionContextPromise: null,
29
- sessionStartTime: null,
30
- // Memoized session id for when `localStorage` can't persist one — see
31
- // getAnalyticsSessionId.
32
- fallbackSessionId: null,
33
- config: {
34
- ...defaultConfiguration,
35
- ...getAnalyticsConfigFromUrlParams(),
36
- },
37
- };
38
- }
39
- const analyticsSharedState = getSharedInstance(ANALYTICS_SHARED_STATE_NAME, createAnalyticsState);
40
- const serverAnalyticsStates = new WeakMap();
41
- /** @internal */
42
- export function isAnalyticsEnabled(enabled, state = analyticsSharedState) {
43
- return enabled && state.config.enabled && !isReactNative;
44
- }
45
- export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthModule, enabled, getVisitorId, experimentsContext, }) => {
46
- const state = typeof window === "undefined" ? createAnalyticsState() : analyticsSharedState;
47
- if (typeof window === "undefined")
48
- serverAnalyticsStates.set(axiosClient, state);
20
+ // shared state//
21
+ const analyticsSharedState = getSharedInstance(ANALYTICS_SHARED_STATE_NAME, () => ({
22
+ requestsQueue: [],
23
+ isProcessing: false,
24
+ isHeartBeatProcessing: false,
25
+ wasInitializationTracked: false,
26
+ sessionContext: null,
27
+ sessionStartTime: null,
28
+ // Memoized session id for when `localStorage` can't persist one — see
29
+ // getAnalyticsSessionId.
30
+ fallbackSessionId: null,
31
+ config: {
32
+ ...defaultConfiguration,
33
+ ...getAnalyticsConfigFromUrlParams(),
34
+ },
35
+ }));
36
+ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthModule, enabled, }) => {
37
+ var _a;
49
38
  // prevent overflow of events //
50
- const { maxQueueSize, throttleTime, batchSize } = state.config;
39
+ const { maxQueueSize, throttleTime, batchSize } = analyticsSharedState.config;
51
40
  // Disable analytics on React Native. It defines `window` but not `document`,
52
41
  // so the per-callsite `typeof window` guards below aren't enough to keep it
53
42
  // from touching `document` (e.g. `document.referrer` on init). Node/SSR is
54
43
  // still handled by those `window` guards, so this doesn't affect it.
55
- if (!isAnalyticsEnabled(enabled, state)) {
44
+ if (!enabled || !((_a = analyticsSharedState.config) === null || _a === void 0 ? void 0 : _a.enabled) || isReactNative) {
56
45
  return {
57
46
  track: () => { },
58
47
  cleanup: () => { },
@@ -81,17 +70,16 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
81
70
  }
82
71
  };
83
72
  const flush = async (eventsData, options = {}) => {
84
- var _a;
85
73
  if (eventsData.length === 0)
86
74
  return;
87
- const sessionContext_ = await getSessionContext(userAuthModule, state);
88
- const events = eventsData.map(transformEventDataToApiRequestData({ ...sessionContext_, session_id: (_a = getVisitorId === null || getVisitorId === void 0 ? void 0 : getVisitorId()) !== null && _a !== void 0 ? _a : sessionContext_.session_id }));
75
+ const sessionContext_ = await getSessionContext(userAuthModule);
76
+ const events = eventsData.map(transformEventDataToApiRequestData(sessionContext_));
89
77
  try {
90
78
  if (!options.isBeacon || !beaconRequest(events)) {
91
79
  await batchRequestFallback(events);
92
80
  }
93
81
  }
94
- catch (_b) {
82
+ catch (_a) {
95
83
  // do nothing
96
84
  }
97
85
  };
@@ -99,25 +87,16 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
99
87
  startAnalyticsProcessor(flush, {
100
88
  throttleTime,
101
89
  batchSize,
102
- }, state);
90
+ });
103
91
  };
104
92
  const track = (params) => {
105
- var _a;
106
- if (state.requestsQueue.length >= maxQueueSize) {
93
+ if (analyticsSharedState.requestsQueue.length >= maxQueueSize) {
107
94
  return;
108
95
  }
109
96
  const intrinsicData = getEventIntrinsicData();
110
- const preview = Object.fromEntries(Object.entries((_a = experimentsContext === null || experimentsContext === void 0 ? void 0 : experimentsContext.preview) !== null && _a !== void 0 ? _a : {}).filter(([, value]) => typeof value === "boolean"));
111
- const properties = { ...params.properties };
112
- delete properties.__b44_experiment_preview;
113
- if (Object.keys(preview).length) {
114
- // Capture now: a queued event must retain its occurrence-time preview.
115
- properties.__b44_experiment_preview = JSON.stringify(preview);
116
- }
117
- state.requestsQueue.push({
97
+ analyticsSharedState.requestsQueue.push({
118
98
  ...params,
119
99
  ...intrinsicData,
120
- properties: params.properties || Object.keys(properties).length ? properties : undefined,
121
100
  });
122
101
  startProcessing();
123
102
  };
@@ -125,16 +104,16 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
125
104
  startAnalyticsProcessor(flush, {
126
105
  throttleTime,
127
106
  batchSize,
128
- }, state);
129
- clearHeartBeatProcessor = startHeartBeatProcessor(track, state);
130
- setSessionDurationTimerStart(state);
107
+ });
108
+ clearHeartBeatProcessor = startHeartBeatProcessor(track);
109
+ setSessionDurationTimerStart();
131
110
  };
132
111
  const onDocHidden = () => {
133
- stopAnalyticsProcessor(state);
112
+ stopAnalyticsProcessor();
134
113
  clearHeartBeatProcessor === null || clearHeartBeatProcessor === void 0 ? void 0 : clearHeartBeatProcessor();
135
- trackSessionDurationEvent(track, state);
114
+ trackSessionDurationEvent(track);
136
115
  // flush entire queue on visibility change and hope for the best //
137
- const eventsData = state.requestsQueue.splice(0);
116
+ const eventsData = analyticsSharedState.requestsQueue.splice(0);
138
117
  flush(eventsData, { isBeacon: true });
139
118
  };
140
119
  const onVisibilityChange = () => {
@@ -148,7 +127,7 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
148
127
  }
149
128
  };
150
129
  const cleanup = () => {
151
- stopAnalyticsProcessor(state);
130
+ stopAnalyticsProcessor();
152
131
  clearHeartBeatProcessor === null || clearHeartBeatProcessor === void 0 ? void 0 : clearHeartBeatProcessor();
153
132
  if (typeof window !== "undefined") {
154
133
  window.removeEventListener("visibilitychange", onVisibilityChange);
@@ -157,9 +136,9 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
157
136
  // start the flusing process ///
158
137
  startProcessing();
159
138
  // start the heart beat processor //
160
- clearHeartBeatProcessor = startHeartBeatProcessor(track, state);
139
+ clearHeartBeatProcessor = startHeartBeatProcessor(track);
161
140
  // track the referrer event //
162
- trackInitializationEvent(track, state);
141
+ trackInitializationEvent(track);
163
142
  // start the visibility change listener //
164
143
  if (typeof window !== "undefined") {
165
144
  window.addEventListener("visibilitychange", onVisibilityChange);
@@ -169,50 +148,50 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
169
148
  cleanup,
170
149
  };
171
150
  };
172
- function stopAnalyticsProcessor(state) {
173
- state.isProcessing = false;
151
+ function stopAnalyticsProcessor() {
152
+ analyticsSharedState.isProcessing = false;
174
153
  }
175
- async function startAnalyticsProcessor(handleTrack, options, state) {
176
- if (state.isProcessing) {
154
+ async function startAnalyticsProcessor(handleTrack, options) {
155
+ if (analyticsSharedState.isProcessing) {
177
156
  // only one instance of the analytics processor can be running at a time //
178
157
  return;
179
158
  }
180
- state.isProcessing = true;
159
+ analyticsSharedState.isProcessing = true;
181
160
  const { throttleTime = 1000, batchSize = 30 } = options !== null && options !== void 0 ? options : {};
182
- while (state.isProcessing &&
183
- state.requestsQueue.length > 0) {
184
- const requests = state.requestsQueue.splice(0, batchSize);
161
+ while (analyticsSharedState.isProcessing &&
162
+ analyticsSharedState.requestsQueue.length > 0) {
163
+ const requests = analyticsSharedState.requestsQueue.splice(0, batchSize);
185
164
  requests.length && (await handleTrack(requests));
186
165
  await new Promise((resolve) => setTimeout(resolve, throttleTime));
187
166
  }
188
- state.isProcessing = false;
167
+ analyticsSharedState.isProcessing = false;
189
168
  }
190
- function startHeartBeatProcessor(track, state) {
169
+ function startHeartBeatProcessor(track) {
191
170
  var _a;
192
171
  // Browser-only, like the other automatic events here (initialization, session
193
172
  // duration, visibility). Outside a browser this timer fired a `me()` every
194
173
  // interval for the lifetime of a long-lived server-side client, and kept the
195
174
  // Node event loop alive. Explicit `analytics.track()` calls still work.
196
175
  if (typeof window === "undefined" ||
197
- state.isHeartBeatProcessing ||
198
- ((_a = state.config.heartBeatInterval) !== null && _a !== void 0 ? _a : 0) < 10) {
176
+ analyticsSharedState.isHeartBeatProcessing ||
177
+ ((_a = analyticsSharedState.config.heartBeatInterval) !== null && _a !== void 0 ? _a : 0) < 10) {
199
178
  return () => { };
200
179
  }
201
- state.isHeartBeatProcessing = true;
180
+ analyticsSharedState.isHeartBeatProcessing = true;
202
181
  const interval = setInterval(() => {
203
182
  track({ eventName: USER_HEARTBEAT_EVENT_NAME });
204
- }, state.config.heartBeatInterval);
183
+ }, analyticsSharedState.config.heartBeatInterval);
205
184
  return () => {
206
185
  clearInterval(interval);
207
- state.isHeartBeatProcessing = false;
186
+ analyticsSharedState.isHeartBeatProcessing = false;
208
187
  };
209
188
  }
210
- function trackInitializationEvent(track, state) {
189
+ function trackInitializationEvent(track) {
211
190
  if (typeof window === "undefined" ||
212
- state.wasInitializationTracked) {
191
+ analyticsSharedState.wasInitializationTracked) {
213
192
  return;
214
193
  }
215
- state.wasInitializationTracked = true;
194
+ analyticsSharedState.wasInitializationTracked = true;
216
195
  track({
217
196
  eventName: ANALYTICS_INITIALIZATION_EVENT_NAME,
218
197
  properties: {
@@ -220,20 +199,20 @@ function trackInitializationEvent(track, state) {
220
199
  },
221
200
  });
222
201
  }
223
- function setSessionDurationTimerStart(state) {
202
+ function setSessionDurationTimerStart() {
224
203
  if (typeof window === "undefined" ||
225
- state.sessionStartTime !== null) {
204
+ analyticsSharedState.sessionStartTime !== null) {
226
205
  return;
227
206
  }
228
- state.sessionStartTime = new Date().toISOString();
207
+ analyticsSharedState.sessionStartTime = new Date().toISOString();
229
208
  }
230
- function trackSessionDurationEvent(track, state) {
209
+ function trackSessionDurationEvent(track) {
231
210
  if (typeof window === "undefined" ||
232
- state.sessionStartTime === null)
211
+ analyticsSharedState.sessionStartTime === null)
233
212
  return;
234
213
  const sessionDuration = new Date().getTime() -
235
- new Date(state.sessionStartTime).getTime();
236
- state.sessionStartTime = null;
214
+ new Date(analyticsSharedState.sessionStartTime).getTime();
215
+ analyticsSharedState.sessionStartTime = null;
237
216
  track({
238
217
  eventName: ANALYTICS_SESSION_DURATION_EVENT_NAME,
239
218
  properties: { sessionDuration },
@@ -256,6 +235,7 @@ function transformEventDataToApiRequestData(sessionContext) {
256
235
  ...sessionContext,
257
236
  });
258
237
  }
238
+ let sessionContextPromise = null;
259
239
  /**
260
240
  * Clears the memoized analytics session context.
261
241
  *
@@ -266,24 +246,22 @@ function transformEventDataToApiRequestData(sessionContext) {
266
246
  *
267
247
  * @internal
268
248
  */
269
- export function resetAnalyticsSessionContext(axiosClient) {
270
- var _a;
271
- const state = axiosClient ? (_a = serverAnalyticsStates.get(axiosClient)) !== null && _a !== void 0 ? _a : analyticsSharedState : analyticsSharedState;
272
- state.sessionContext = null;
273
- state.sessionContextPromise = null;
249
+ export function resetAnalyticsSessionContext() {
250
+ analyticsSharedState.sessionContext = null;
251
+ sessionContextPromise = null;
274
252
  }
275
- async function getSessionContext(userAuthModule, state) {
276
- if (!state.sessionContext) {
253
+ async function getSessionContext(userAuthModule) {
254
+ if (!analyticsSharedState.sessionContext) {
277
255
  // With no token there is no identity to resolve: `me()` can only answer 401,
278
256
  // which the browser logs to the console before any handler here sees it. On
279
257
  // a public page that request is the sole reason an error appears, so skip
280
258
  // it. This is not memoized — a visitor who logs in later must still resolve.
281
259
  if (!userAuthModule.hasToken()) {
282
- return { user_id: null, session_id: getAnalyticsSessionId(state) };
260
+ return { user_id: null, session_id: getAnalyticsSessionId() };
283
261
  }
284
- if (!state.sessionContextPromise) {
285
- const sessionId = getAnalyticsSessionId(state);
286
- state.sessionContextPromise = userAuthModule
262
+ if (!sessionContextPromise) {
263
+ const sessionId = getAnalyticsSessionId();
264
+ sessionContextPromise = userAuthModule
287
265
  .me()
288
266
  .then((user) => ({
289
267
  user_id: user.id,
@@ -294,7 +272,7 @@ async function getSessionContext(userAuthModule, state) {
294
272
  session_id: sessionId,
295
273
  }));
296
274
  }
297
- const pending = state.sessionContextPromise;
275
+ const pending = sessionContextPromise;
298
276
  const context = await pending;
299
277
  // Publish only if this lookup is still the current one. A reset that lands
300
278
  // while the request is in flight nulls `sessionContextPromise`, and an
@@ -302,12 +280,12 @@ async function getSessionContext(userAuthModule, state) {
302
280
  // for the rest of the session. The awaited value is still returned: these
303
281
  // events were queued before the identity changed, so that is who they
304
282
  // belong to.
305
- if (state.sessionContextPromise === pending) {
306
- state.sessionContext = context;
283
+ if (sessionContextPromise === pending) {
284
+ analyticsSharedState.sessionContext = context;
307
285
  }
308
286
  return context;
309
287
  }
310
- return state.sessionContext;
288
+ return analyticsSharedState.sessionContext;
311
289
  }
312
290
  export function getAnalyticsConfigFromUrlParams() {
313
291
  // `window.location` is absent on React Native. This runs at module load (via
@@ -329,18 +307,15 @@ export function getAnalyticsConfigFromUrlParams() {
329
307
  // return the config object //
330
308
  return { enabled: analyticsEnable === "true" };
331
309
  }
332
- // Without persistent storage, keep the id stable within this analytics state.
333
- function getFallbackSessionId(state) {
310
+ // When the id can't be persisted (React Native has no `localStorage`), keep
311
+ // it stable for the process instead of minting a fresh one per call.
312
+ function getFallbackSessionId() {
334
313
  var _a;
335
- return ((_a = state.fallbackSessionId) !== null && _a !== void 0 ? _a : (state.fallbackSessionId = generateUuid()));
314
+ return ((_a = analyticsSharedState.fallbackSessionId) !== null && _a !== void 0 ? _a : (analyticsSharedState.fallbackSessionId = generateUuid()));
336
315
  }
337
- export function getAnalyticsSessionId(state = analyticsSharedState) {
338
- var _a;
339
- const visitorId = (_a = getExperimentsRuntime()) === null || _a === void 0 ? void 0 : _a.visitorId;
340
- if (visitorId && visitorId !== "anon")
341
- return visitorId;
316
+ export function getAnalyticsSessionId() {
342
317
  if (typeof window === "undefined") {
343
- return getFallbackSessionId(state);
318
+ return getFallbackSessionId();
344
319
  }
345
320
  try {
346
321
  const sessionId = localStorage.getItem(ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY);
@@ -351,7 +326,7 @@ export function getAnalyticsSessionId(state = analyticsSharedState) {
351
326
  }
352
327
  return sessionId;
353
328
  }
354
- catch (_b) {
355
- return getFallbackSessionId(state);
329
+ catch (_a) {
330
+ return getFallbackSessionId();
356
331
  }
357
332
  }