Skip to content

Commit 7f52896

Browse files
committed
feat: add server-synced user preferences infrastructure (#484)
- introduce the foundational layer for persisting user preferences to the server - add UserPreferencesSchema and shared types for user preferences - add client-only sync composable with debounced saves, route guard flush, and sendBeacon fallback - integrate server sync into useSettings and migrate to shared UserPreferences type - extract generic localStorage helpers, migrate consumers, remove usePreferencesProvider
1 parent 2af4011 commit 7f52896

12 files changed

Lines changed: 368 additions & 351 deletions
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { createDefu } from 'defu'
2+
import { createLocalStorageProvider } from '~/utils/storage'
3+
4+
const defu = createDefu((object, key, value) => {
5+
if (Array.isArray(object[key]) && Array.isArray(value)) {
6+
object[key] = value
7+
return true
8+
}
9+
})
10+
11+
export function useLocalStorageHashProvider<T extends object>(key: string, defaultValue: T) {
12+
const provider = createLocalStorageProvider<T>(key)
13+
const data = ref<T>(defaultValue)
14+
15+
onMounted(() => {
16+
const stored = provider.get()
17+
if (stored) {
18+
data.value = defu(stored, defaultValue)
19+
}
20+
})
21+
22+
function save() {
23+
provider.set(data.value)
24+
}
25+
26+
function reset() {
27+
data.value = { ...defaultValue }
28+
provider.remove()
29+
}
30+
31+
function update<K extends keyof T>(key: K, value: T[K]) {
32+
data.value[key] = value
33+
save()
34+
}
35+
36+
return {
37+
data,
38+
save,
39+
reset,
40+
update,
41+
}
42+
}

app/composables/usePackageListPreferences.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ import type {
1111
} from '#shared/types/preferences'
1212
import { DEFAULT_COLUMNS, DEFAULT_PREFERENCES } from '#shared/types/preferences'
1313

14+
const STORAGE_KEY = 'npmx-list-prefs'
15+
1416
/**
1517
* Composable for managing package list display preferences
1618
* Persists to localStorage and provides reactive state
17-
*
1819
*/
1920
export function usePackageListPreferences() {
2021
const {
2122
data: preferences,
22-
isHydrated,
2323
save,
2424
reset,
25-
} = usePreferencesProvider<PackageListPreferences>(DEFAULT_PREFERENCES)
25+
} = useLocalStorageHashProvider<PackageListPreferences>(STORAGE_KEY, DEFAULT_PREFERENCES)
2626

2727
// Computed accessors for common properties
2828
const viewMode = computed({
@@ -106,7 +106,6 @@ export function usePackageListPreferences() {
106106
return {
107107
// Raw preferences
108108
preferences,
109-
isHydrated,
110109

111110
// Individual properties with setters
112111
viewMode,

app/composables/usePreferencesProvider.ts

Lines changed: 0 additions & 109 deletions
This file was deleted.

0 commit comments

Comments
 (0)