feat(housekeeping): persist operator preferences

This commit is contained in:
Simo committed 2026-08-26 22:17:52 +02:00
1 parent 86a2d9d069
commit 2eb0456999
8 files changed
+566

No files matched your search

@@ -0,0 +1,62 @@
import { z } from "zod";
export interface HousekeepingPreferences {
schemaVersion: 1;
pinnedRouteIds: string[];
pinnedCommandIds: string[];
shortcutOrder: string[];
widgetOrder: string[];
enabledOptionalWidgetIds: string[];
}
const uniqueIdentifiers = z
.array(z.string().trim().min(1))
.superRefine((values, context) => {
const seen = new Set<string>();
for (const [index, value] of values.entries()) {
if (seen.has(value)) {
context.addIssue({
code: "custom",
message: "duplicate preference identifier",
path: [index],
});
}
seen.add(value);
}
});
export const housekeepingPreferencesSchema: z.ZodType<HousekeepingPreferences> =
z
.object({
schemaVersion: z.literal(1),
pinnedRouteIds: uniqueIdentifiers,
pinnedCommandIds: uniqueIdentifiers,
shortcutOrder: uniqueIdentifiers,
widgetOrder: uniqueIdentifiers,
enabledOptionalWidgetIds: uniqueIdentifiers,
})
.strict();
export function defaultHousekeepingPreferences(): HousekeepingPreferences {
return {
schemaVersion: 1,
pinnedRouteIds: [],
pinnedCommandIds: [],
shortcutOrder: [],
widgetOrder: [],
enabledOptionalWidgetIds: [],
};
}
export function parseHousekeepingPreferences(
serialized: string,
): HousekeepingPreferences {
let value: unknown;
try {
value = JSON.parse(serialized);
} catch {
throw new Error("invalid housekeeping preferences JSON");
}
return housekeepingPreferencesSchema.parse(value);
}