@shopana/ga
Version:
Type-safe Google Analytics 4 (GA4) tracking library for React and Next.js with ecommerce support, event batching, and SSR compatibility
64 lines • 1.84 kB
JavaScript
const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
export class TransactionRegistry {
constructor(ttlMs = DEFAULT_TTL_MS) {
this.transactions = new Map();
this.isCleared = false;
this.ttlMs = ttlMs;
this.scheduleCleanup();
}
has(transactionId) {
const timestamp = this.transactions.get(transactionId);
if (!timestamp) {
return false;
}
if (Date.now() - timestamp > this.ttlMs) {
this.transactions.delete(transactionId);
return false;
}
return true;
}
add(transactionId) {
this.transactions.set(transactionId, Date.now());
}
clear() {
this.isCleared = true;
this.transactions.clear();
if (this.cleanupTimer) {
clearTimeout(this.cleanupTimer);
this.cleanupTimer = undefined;
}
}
guard(transactionId, warn = console.warn) {
if (this.has(transactionId)) {
warn(`[GA] duplicate transaction detected: ${transactionId}`);
}
else {
this.add(transactionId);
}
}
scheduleCleanup() {
if (this.isCleared) {
return;
}
const timer = setTimeout(() => {
if (!this.isCleared) {
this.cleanup();
this.scheduleCleanup();
}
}, 60 * 60 * 1000);
this.cleanupTimer = timer;
if (this.isCleared) {
clearTimeout(timer);
this.cleanupTimer = undefined;
}
}
cleanup() {
const now = Date.now();
for (const [id, timestamp] of this.transactions.entries()) {
if (now - timestamp > this.ttlMs) {
this.transactions.delete(id);
}
}
}
}
//# sourceMappingURL=TransactionRegistry.js.map