Extract two pure helpers so they're testable without zustand/expo: - settings-merge.ts: clampPageSize + forward-compatible mergeStoredSettings (the upgrade path where stored data predates a new notification category must yield the default, not undefined). stores/settings.ts now delegates. - notify-format.ts: sanitizeBody (strip C0/DEL control chars, trim, cap at 200) used for server-supplied notification text. stores/events.ts now imports it. Behavior unchanged; typecheck clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
26 lines
979 B
TypeScript
26 lines
979 B
TypeScript
// Pure settings helpers extracted from stores/settings.ts so the clamp + the
|
|
// forward-compatible merge (the upgrade path: stored data from an older app
|
|
// version that predates a newer notification category) are unit-testable without
|
|
// pulling in zustand / expo-secure-store.
|
|
|
|
export function clampPageSize(size: number): number {
|
|
return Math.max(10, Math.min(200, size))
|
|
}
|
|
|
|
/**
|
|
* Merge stored settings over defaults. Stored values win, but any top-level field
|
|
* or notification category missing from storage falls back to its default — so a
|
|
* user upgrading to a build with a new setting gets that setting's default rather
|
|
* than `undefined`. Defaults are passed in to keep this module dependency-free.
|
|
*/
|
|
export function mergeStoredSettings<T extends { notifications: Record<string, boolean> }>(
|
|
defaults: T,
|
|
parsed: Partial<T>,
|
|
): T {
|
|
return {
|
|
...defaults,
|
|
...parsed,
|
|
notifications: { ...defaults.notifications, ...parsed.notifications },
|
|
}
|
|
}
|