mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 18:30:32 -06:00
Co-authored-by: Johannes <johannes@formbricks.com> Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
120 lines
3.9 KiB
TypeScript
120 lines
3.9 KiB
TypeScript
import { FormbricksAPI } from "@formbricks/api";
|
|
import { TResponseUpdate } from "@formbricks/types/responses";
|
|
import { SurveyState } from "./surveyState";
|
|
import { delay } from "./utils/promises";
|
|
|
|
interface QueueConfig {
|
|
apiHost: string;
|
|
environmentId: string;
|
|
retryAttempts: number;
|
|
onResponseSendingFailed?: (responseUpdate: TResponseUpdate) => void;
|
|
onResponseSendingFinished?: () => void;
|
|
setSurveyState?: (state: SurveyState) => void;
|
|
}
|
|
|
|
export class ResponseQueue {
|
|
private queue: TResponseUpdate[] = [];
|
|
private config: QueueConfig;
|
|
private surveyState: SurveyState;
|
|
private isRequestInProgress = false;
|
|
private api: FormbricksAPI;
|
|
|
|
constructor(config: QueueConfig, surveyState: SurveyState) {
|
|
this.config = config;
|
|
this.surveyState = surveyState;
|
|
this.api = new FormbricksAPI({
|
|
apiHost: config.apiHost,
|
|
environmentId: config.environmentId,
|
|
});
|
|
}
|
|
|
|
add(responseUpdate: TResponseUpdate) {
|
|
// update survey state
|
|
this.surveyState.accumulateResponse(responseUpdate);
|
|
if (this.config.setSurveyState) {
|
|
this.config.setSurveyState(this.surveyState);
|
|
}
|
|
// add response to queue
|
|
this.queue.push(responseUpdate);
|
|
this.processQueue();
|
|
}
|
|
|
|
async processQueue() {
|
|
if (this.isRequestInProgress) return;
|
|
if (this.queue.length === 0) return;
|
|
|
|
this.isRequestInProgress = true;
|
|
|
|
const responseUpdate = this.queue[0];
|
|
let attempts = 0;
|
|
|
|
while (attempts < this.config.retryAttempts) {
|
|
const success = await this.sendResponse(responseUpdate);
|
|
if (success) {
|
|
this.queue.shift(); // remove the successfully sent response from the queue
|
|
break; // exit the retry loop
|
|
}
|
|
console.error(`Formbricks: Failed to send response. Retrying... ${attempts}`);
|
|
await delay(1000); // wait for 1 second before retrying
|
|
attempts++;
|
|
}
|
|
|
|
if (attempts >= this.config.retryAttempts) {
|
|
// Inform the user after 2 failed attempts
|
|
console.error("Failed to send response after 2 attempts.");
|
|
// If the response fails finally, inform the user
|
|
if (this.config.onResponseSendingFailed) {
|
|
this.config.onResponseSendingFailed(responseUpdate);
|
|
}
|
|
this.isRequestInProgress = false;
|
|
} else {
|
|
if (responseUpdate.finished && this.config.onResponseSendingFinished) {
|
|
this.config.onResponseSendingFinished();
|
|
}
|
|
this.isRequestInProgress = false;
|
|
this.processQueue(); // process the next item in the queue if any
|
|
}
|
|
}
|
|
|
|
async sendResponse(responseUpdate: TResponseUpdate): Promise<boolean> {
|
|
try {
|
|
if (this.surveyState.responseId !== null) {
|
|
await this.api.client.response.update({ ...responseUpdate, responseId: this.surveyState.responseId });
|
|
} else {
|
|
const response = await this.api.client.response.create({
|
|
...responseUpdate,
|
|
surveyId: this.surveyState.surveyId,
|
|
userId: this.surveyState.userId || null,
|
|
singleUseId: this.surveyState.singleUseId || null,
|
|
data: { ...responseUpdate.data, ...responseUpdate.hiddenFields },
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error("Could not create response");
|
|
}
|
|
if (this.surveyState.displayId) {
|
|
try {
|
|
await this.api.client.display.update(this.surveyState.displayId, {
|
|
responseId: response.data.id,
|
|
});
|
|
} catch (error) {
|
|
console.error(`Failed to update display, proceeding with the response. ${error}`);
|
|
}
|
|
}
|
|
this.surveyState.updateResponseId(response.data.id);
|
|
if (this.config.setSurveyState) {
|
|
this.config.setSurveyState(this.surveyState);
|
|
}
|
|
}
|
|
return true;
|
|
} catch (error) {
|
|
console.error(error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// update surveyState
|
|
updateSurveyState(surveyState: SurveyState) {
|
|
this.surveyState = surveyState;
|
|
}
|
|
}
|