import { packageStorage } from 'kody:runtime' import { createMigrationRunner } from 'kody:@kentcdodds/package-app-kit/storage-migrations' export type Note = { id: string text: string createdAt: string } /** Document shape after schema v1. */ type NotesDocument = { items: Array } const notesKey = '__PACKAGE_ID__-notes' const legacyNotesKey = '__PACKAGE_ID__-notes-v1' const schemaVersionKey = '__PACKAGE_ID__-schema-version' function getStorage() { return packageStorage() } /** * Demo schema bump: legacy flat array key → `{ items: Note[] }` document. * Runner is isolate-memoized; safe to await on every notes read/write. */ const ensureNotesSchema = (() => { let ensure: ReturnType | null = null return () => { if (!ensure) { const storage = getStorage() ensure = createMigrationRunner({ storage, versionKey: schemaVersionKey, migrations: [ { version: 1, name: 'notes-array-to-document', async up(s: any) { const legacy = await s.get(legacyNotesKey) const existing = await s.get(notesKey) if (Array.isArray(legacy)) { await s.set(notesKey, { items: legacy } satisfies NotesDocument) await s.delete?.(legacyNotesKey) } else if (Array.isArray(existing)) { await s.set(notesKey, { items: existing } satisfies NotesDocument) } else if (existing == null) { await s.set(notesKey, { items: [] } satisfies NotesDocument) } }, }, ], }) } return ensure() } })() async function readDocument(): Promise { await ensureNotesSchema() const stored = await getStorage().get(notesKey) if (stored && typeof stored === 'object' && Array.isArray((stored as NotesDocument).items)) { return stored as NotesDocument } return { items: [] } } export async function listNotes(): Promise> { const doc = await readDocument() return doc.items } export async function addNote(text: string) { const storage = getStorage() const doc = await readDocument() const note: Note = { id: crypto.randomUUID(), text, createdAt: new Date().toISOString(), } const next: NotesDocument = { items: [note, ...doc.items] } await storage.set(notesKey, next) return note } export async function deleteNote(id: string) { const storage = getStorage() const doc = await readDocument() const items = doc.items.filter((note) => note.id !== id) await storage.set(notesKey, { items } satisfies NotesDocument) return { ok: items.length !== doc.items.length } }