import { browser } from "$app/environment"; import { invalidate } from "$app/navigation"; import { base } from "$app/paths"; import { UrlDependency } from "$lib/types/UrlDependency"; import type { ObjectId } from "mongodb"; import { getContext, setContext } from "svelte"; import { type Writable, writable, get } from "svelte/store"; type SettingsStore = { shareConversationsWithModelAuthors: boolean; hideEmojiOnSidebar: boolean; ethicsModalAccepted: boolean; ethicsModalAcceptedAt: Date | null; activeModel: string; customPrompts: Record; recentlySaved: boolean; assistants: Array; }; type SettingsStoreWritable = Writable & { instantSet: (settings: Partial) => Promise; }; export function useSettingsStore() { return getContext("settings"); } export function createSettingsStore(initialValue: Omit) { const baseStore = writable({ ...initialValue, recentlySaved: false }); let timeoutId: NodeJS.Timeout; async function setSettings(settings: Partial) { baseStore.update((s) => ({ ...s, ...settings, })); clearTimeout(timeoutId); if (browser) { timeoutId = setTimeout(async () => { await fetch(`${base}/settings`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...get(baseStore), ...settings, }), }); invalidate(UrlDependency.ConversationList); // set savedRecently to true for 3s baseStore.update((s) => ({ ...s, recentlySaved: true, })); setTimeout(() => { baseStore.update((s) => ({ ...s, recentlySaved: false, })); }, 3000); invalidate(UrlDependency.ConversationList); }, 300); // debounce server calls by 300ms } } async function instantSet(settings: Partial) { baseStore.update((s) => ({ ...s, ...settings, })); if (browser) { await fetch(`${base}/settings`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...get(baseStore), ...settings, }), }); invalidate(UrlDependency.ConversationList); } } const newStore = { subscribe: baseStore.subscribe, set: setSettings, instantSet, update: (fn: (s: SettingsStore) => SettingsStore) => { setSettings(fn(get(baseStore))); }, } satisfies SettingsStoreWritable; setContext("settings", newStore); return newStore; }