Skip to content

Commit 05bee93

Browse files
committed
processing state
1 parent 00c583d commit 05bee93

2 files changed

Lines changed: 28 additions & 15 deletions

File tree

src/modules/analytics.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,17 @@ import type { AuthModule } from "./auth.types";
1717
///////////////////////////////////////////////
1818
//// shared queue for analytics events ////
1919
///////////////////////////////////////////////
20-
type AnalyticsSharedState = {
21-
requestsQueue: TrackEventData[];
22-
};
2320

2421
const ANALYTICS_SHARED_STATE_NAME = "analytics";
2522
// shared state//
26-
const analyticsSharedState = getSharedInstance<AnalyticsSharedState>(
23+
const analyticsSharedState = getSharedInstance(
2724
ANALYTICS_SHARED_STATE_NAME,
2825
() => ({
29-
requestsQueue: [],
26+
requestsQueue: [] as TrackEventData[],
27+
isProcessing: false,
3028
})
3129
);
30+
3231
///////////////////////////////////////////////
3332

3433
export interface AnalyticsModuleArgs {
@@ -100,16 +99,24 @@ export const createAnalyticsModule = ({
10099
}
101100
};
102101

103-
if (typeof window !== "undefined") {
102+
if (typeof window !== "undefined" && enabled) {
104103
window.addEventListener("visibilitychange", () => {
105-
// flush entire queue on visibility change and hope for the best //
106-
const eventsData = analyticsSharedState.requestsQueue.splice(0);
107-
flush(eventsData);
104+
if (document.visibilityState === "hidden") {
105+
analyticsSharedState.isProcessing = false;
106+
// flush entire queue on visibility change and hope for the best //
107+
const eventsData = analyticsSharedState.requestsQueue.splice(0);
108+
flush(eventsData);
109+
} else if (document.visibilityState === "visible") {
110+
startAnalyticsProcessor(flush, {
111+
throttleTime,
112+
batchSize,
113+
});
114+
}
108115
});
109116
}
110117

111118
// start analytics processor only if it's the first instance and analytics is enabled //
112-
if (getSharedInstanceRefCount(ANALYTICS_SHARED_STATE_NAME) <= 1 && enabled) {
119+
if (enabled) {
113120
startAnalyticsProcessor(flush, {
114121
throttleTime,
115122
batchSize,
@@ -122,15 +129,18 @@ export const createAnalyticsModule = ({
122129
};
123130

124131
async function startAnalyticsProcessor(
125-
handleTrack: (trackRequest: TrackEventData[]) => Promise<void>,
132+
handleTrack: (eventsData: TrackEventData[]) => Promise<void>,
126133
options?: {
127134
throttleTime: number;
128135
batchSize: number;
129136
}
130137
) {
138+
if (analyticsSharedState.isProcessing) {
139+
return;
140+
}
141+
analyticsSharedState.isProcessing = true;
131142
const { throttleTime = 1000, batchSize = 30 } = options ?? {};
132-
while (true) {
133-
await new Promise((resolve) => setTimeout(resolve, throttleTime));
143+
while (analyticsSharedState.isProcessing) {
134144
const requests = analyticsSharedState.requestsQueue.splice(0, batchSize);
135145
if (requests.length > 0) {
136146
try {
@@ -140,13 +150,14 @@ async function startAnalyticsProcessor(
140150
console.error("Error processing analytics request:", error);
141151
}
142152
}
153+
await new Promise((resolve) => setTimeout(resolve, throttleTime));
143154
}
144155
}
145156

146157
function getEventIntrinsicData(): TrackEventIntrinsicData {
147158
return {
148159
timestamp: new Date().toISOString(),
149-
pageUrl: typeof window !== "undefined" ? window.location.href : null,
160+
pageUrl: typeof window !== "undefined" ? window.location.pathname : null,
150161
};
151162
}
152163

src/utils/singleton.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ export function getSharedInstance<T>(name: string, factory: () => T): T {
66
const windowObj: Window & {
77
base44?: { [key: string]: { instance: T; _refCount: number } };
88
} = typeof window !== "undefined" ? (window as any) : { base44: {} };
9+
910
if (!windowObj.base44) {
1011
windowObj.base44 = {};
1112
}
1213
if (!windowObj.base44[name]) {
13-
windowObj.base44[name] = { instance: factory(), _refCount: 1 };
14+
windowObj.base44[name] = { instance: factory(), _refCount: 0 };
1415
}
16+
windowObj.base44[name]._refCount++;
1517
return windowObj.base44[name].instance;
1618
}
1719

0 commit comments

Comments
 (0)