crunchit
Version:
Autotrack the events from your users
156 lines (150 loc) • 4.31 kB
JavaScript
const { v4: uuidv4 } = require("uuid");
class BatchProcessor {
constructor(
batchSize = 10,
interval = 5000,
distinctId,
app_id,
sessionId,
timeout
) {
this.batchSize = batchSize;
this.batch = [];
this.interval = interval;
``;
this.distinctId = distinctId;
this.sessionId = sessionId;
this.app_id = app_id;
this.API_URL = "https://events-backend-5dzspnb6za-uc.a.run.app/";
this.timeout = timeout;
this.timeoutRef = setTimeout(() => {
let sessionId = uuidv4();
window.sessionStorage.setItem("CRUNCH_SESSION_ID", sessionId);
}, this.timeout);
// ! Try to load any saved batch from window.localStorage
const savedBatch = window?.localStorage.getItem("batch");
if (savedBatch) {
this.batch = JSON.parse(savedBatch);
}
// ! Set up the interval to automatically send the batch
this.intervalId = setInterval(() => {
this.sendBatch();
}, this.interval);
}
addAutoCaptureActivity(xpath, activity) {
let activityToBatch = {
type: "AUTO",
activity,
xpath,
distinctId: this.distinctId,
id: this.sessionId,
};
this.addToBatch(activityToBatch);
}
addManualCaptureActivity(activity) {
let activityToBatch = {
type: "MANUAL",
activity,
distinctId: this.distinctId,
id: this.sessionId,
};
this.addToBatch(activityToBatch);
}
resetTimeout() {
clearTimeout(this.timeoutRef);
this.timeoutRef = setTimeout(() => {
let sessionId = uuidv4();
window.sessionStorage.setItem("CRUNCH_SESSION_ID", sessionId);
}, this.timeout);
}
// ! Add an item to the batch
addToBatch(item) {
let timestamp = new Date() * 1;
// ! If the new event has come at least 200ms after the last one, then add to batch
if (this.batch.length > 0) {
if (
timestamp - this.batch[this.batch.length - 1].activity.timestamp >=
200
) {
this.batch.push(item);
// console.log(this.batch);
}
} else {
this.batch.push(item);
// console.log(this.batch);
}
// ! If the batch is now full, send it
if (this.batch.length >= this.batchSize) {
this.sendBatch();
}
this.resetTimeout();
}
// ! Send the batch to the server
sendBatch() {
if (this.batch.length === 0) {
return;
}
// ! Clear the batch from window.localStorage
window.localStorage.removeItem("batch");
// ! Send the batch data to your server (replace with your actual function to send data)
this.sendToServer(this.batch);
}
// ! Save the current batch to window.localStorage
saveBatch() {
window.localStorage.setItem("batch", JSON.stringify(this.batch));
}
// ! Send the current batch to the server
sendToServer(batch) {
let currentBatch = {
activity: batch,
};
fetch(`${this.API_URL}add-activity`, {
method: "POST",
headers: {
"Content-Type": "application/json",
project_id: this.app_id,
},
body: JSON.stringify(currentBatch),
})
.then((response) => {
// ! Clear the batch
this.batch = [];
return response.json();
})
.then((data) => {
if (window.crunchDebug) console.log("add-activity response:", data);
})
.catch((error) => {
if (window.crunchDebug) console.error("add-activity error:", error);
});
}
// ! Call this function before the browser is closed to ensure data is not lost
handleBrowserClose() {
this.saveBatch();
}
// ! Send the custom selectors given by the user to the server one by one
sendCustomLabel(item, onSuccess) {
fetch(`${this.API_URL}add-activity-name`, {
method: "POST",
headers: {
"Content-Type": "application/json",
project_id: this.app_id,
},
body: JSON.stringify(item),
})
.then((response) => {
// ! Clear the batch
onSuccess();
return response.json();
})
.then((data) => {
if (window.crunchDebug)
console.log("add-activity-name response:", data);
})
.catch((error) => {
if (window.crunchDebug)
console.error("add-activity-name error:", error);
});
}
}
module.exports = BatchProcessor;