Files
kandev/apps/web/lib/user-settings-sync.ts
T
Carlos Florêncio b9eb6ae058 refactor(web): remove legacy settings migration (#1704)
* refactor(web): remove legacy settings migration

* fix(web): hydrate portable settings from boot state

* fix(web): preserve sidebar sync contracts

* fix(web): retain portable settings filters

* fix(web): retry sidebar settings writes

* fix(web): retain sidebar boot settings

* fix(websocket): avoid shutdown teardown leaks

* fix(boot): normalize sidebar task preferences

* fix(settings): preserve saved views during hydration

* fix(jira): avoid duplicate saved-view syncs

* fix(jira): preserve saved views on fetch failure

* fix(jira): retry saved-view hydration failures

* refactor(jira): simplify hydration request cleanup

* fix(websocket): close late clients after hub shutdown
2026-07-16 00:06:41 +01:00

42 lines
1.2 KiB
TypeScript

import { updateUserSettings } from "@/lib/api/domains/settings-api";
import { ApiError } from "@/lib/api/client";
import type { UserSettingsUpdatePayload } from "@/lib/types/http-user-settings";
const MAX_SYNC_ATTEMPTS = 3;
const BASE_SYNC_RETRY_DELAY_MS = 100;
export async function updateUserSettingsWithRetry(
payload: UserSettingsUpdatePayload,
): Promise<void> {
let lastError: unknown;
for (let attempt = 0; attempt < MAX_SYNC_ATTEMPTS; attempt += 1) {
try {
await updateUserSettings(payload);
return;
} catch (error) {
if (error instanceof ApiError) throw error;
lastError = error;
if (attempt < MAX_SYNC_ATTEMPTS - 1) {
await new Promise((resolve) =>
setTimeout(resolve, BASE_SYNC_RETRY_DELAY_MS * 2 ** attempt),
);
}
}
}
throw lastError;
}
export function createQueuedUserSettingsSync<T>(
buildPayload: (value: T) => UserSettingsUpdatePayload,
): (value: T) => Promise<void> {
let queue = Promise.resolve();
return (value: T) => {
const payload = buildPayload(value);
queue = queue
.catch(() => undefined)
.then(() => updateUserSettingsWithRetry(payload))
.catch(() => undefined);
return queue;
};
}