···8899export { isMobile } from "../routes/+layout.svelte";
10101111+/**
1212+ * Trims {@paramstr} to {@param maxLength}, adding ellipses if it was too long.
1313+ * @param str The string to trim
1414+ * @param maxLength The maximum number of characters to allow before trimming.
1515+ * @returns The trimmed string.
1616+ */
1117export function trim(str: string, maxLength: number) {
1218 if (str.length <= maxLength) return str;
1319 return str.slice(0, maxLength - 3) + "...";
1420}
15212222+/**
2323+ * Displays a warning toast to the user.
2424+ * @param message The message to display on the toast.
2525+ * @param details Any extra details to show in the toast modal.
2626+ */
1627export function warn(message: string, details?: string | string[]) {
1728 addToast({ data: { icon: faTriangleExclamation, color: "peach", title: trim(message, 40), details } });
1829}
19303131+/**
3232+ * Displays an error toast to the user.
3333+ * @param message The message to display on the toast.
3434+ * @param details Any extra details to show in the toast modal.
3535+ */
2036export function error(message: string, details?: string | string[]) {
2137 addToast({ data: { icon: faCircleXmark, color: "red", title: trim(message, 40), details } });
2238}
23394040+/**
4141+ * A simple async sleep function that resolves after {@param ms} milliseconds.
4242+ * @param ms The number of milliseconds to sleep for.
4343+ */
2444export function sleep(ms: number) {
2545 return new Promise((resolve) => setTimeout(resolve, ms));
2646}
27474848+/**
4949+ * A exponential backoff utility class used for managing retry attempts.
5050+ */
2851export class Backoff {
5252+ /**
5353+ * The current delay before the next retry attempt, in milliseconds.
5454+ */
2955 public currentDelay: number;
5656+5757+ /**
5858+ * The initial delay, set when the class is instantiated or reset.
5959+ */
3060 public initialDelay: number;
6161+6262+ /**
6363+ * The maximum delay allowed.
6464+ */
3165 public maxDelay: number;
32663333- public constructor(initialDelay: number = 1000, maxDelay: number = 30000) {
6767+ public constructor(initialDelay: number = 1000, maxDelay: number = 30 * 1000) {
3468 this.currentDelay = initialDelay;
3569 this.initialDelay = initialDelay;
3670 this.maxDelay = maxDelay;
3771 }
38727373+ /**
7474+ * Resets the backoff delay to the initial value.
7575+ */
3976 public reset() {
4077 this.currentDelay = this.initialDelay;
4178 }
42798080+ /**
8181+ * Waits for the current delay duration, and then doubles it.
8282+ */
4383 public async wait() {
4484 await sleep(this.currentDelay);
4585 this.currentDelay = Math.min(this.currentDelay * 2, this.maxDelay);