40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
export const LOCAL_DRAFT_SCHEMA_VERSION = 1;
|
|
|
|
export interface LocalDraftEnvelope<Draft> {
|
|
schemaVersion: typeof LOCAL_DRAFT_SCHEMA_VERSION;
|
|
serverVersion: number;
|
|
updatedAt: string;
|
|
draft: Draft;
|
|
}
|
|
|
|
export function adminDraftKey(guideId: string, section: string): string {
|
|
return `buzz-sheet:admin-draft:${guideId}:${section}`;
|
|
}
|
|
|
|
export function serializeLocalDraft<Draft>(draft: Draft, serverVersion: number): string {
|
|
return JSON.stringify({
|
|
schemaVersion: LOCAL_DRAFT_SCHEMA_VERSION,
|
|
serverVersion,
|
|
updatedAt: new Date().toISOString(),
|
|
draft,
|
|
} satisfies LocalDraftEnvelope<Draft>);
|
|
}
|
|
|
|
export function parseLocalDraft<Draft>(serialized: string, parseDraft: (value: unknown) => Draft | null): LocalDraftEnvelope<Draft> | null {
|
|
try {
|
|
const value: unknown = JSON.parse(serialized);
|
|
if (!value || typeof value !== "object") return null;
|
|
const envelope = value as Record<string, unknown>;
|
|
if (envelope.schemaVersion !== LOCAL_DRAFT_SCHEMA_VERSION || typeof envelope.serverVersion !== "number" || typeof envelope.updatedAt !== "string") return null;
|
|
const draft = parseDraft(envelope.draft);
|
|
return draft === null ? null : {
|
|
schemaVersion: LOCAL_DRAFT_SCHEMA_VERSION,
|
|
serverVersion: envelope.serverVersion,
|
|
updatedAt: envelope.updatedAt,
|
|
draft,
|
|
};
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|