/** * store_versions.ts * * Single source of truth for persisted store schema versions. * * HOW IT WORKS: * This file is imported at the top of ae_stores.ts and ae_events_stores.ts. * ES modules resolve imports before running the importing module's body, * so the version check + localStorage wipe here runs BEFORE persisted() is * called — meaning stale data is cleared before svelte-persisted-store * can hydrate from it. * * HOW TO USE: * When a store schema changes in a breaking way (type change, required * restructure, field rename that code depends on), bump the relevant version * by 1. Any client with an older version will have that store silently wiped * on next page load. They re-initialize from the new defaults. * * WHAT COUNTS AS BREAKING: * - Changing a field's type (e.g. string → object, or null → required object) * - Renaming a field that code reads directly (not just a display label) * - Restructuring a nested object that breaks existing property access * DOES NOT require a bump: * - Adding a new optional field (svelte-persisted-store deep-merges defaults) * - Removing a field (old value is ignored, no error) * - Changing a default value when the stored value being stale is acceptable * * localStorage keys: * 'ae_loc' → AE_LOC_VERSION * 'ae_events_loc' → AE_EVENTS_LOC_VERSION */ export const AE_LOC_VERSION = 2; // Bumped 2026-03-30: force-clear stale site_cfg_json (novi_idaa_api_key missing bug) export const AE_EVENTS_LOC_VERSION = 1; export const AE_IDAA_LOC_VERSION = 1; // Added 2026-03-30: was missing, no wipe mechanism existed export const AE_PRES_MGMT_LOC_VERSION = 1; // Added 2026-04-02: new standalone PersistedState store export const AE_BADGES_LOC_VERSION = 1; // Added 2026-04-02: promoted from events_loc.badges export const AE_LEADS_LOC_VERSION = 1; // Added 2026-04-03: promoted from events_loc.leads /** * IDB_CONTENT_VERSIONS — per-table Dexie content version tracking. * * NOT YET ACTIVE. Wiring task tracked in TODO__Agents.md (post June 10). * * HOW IT WILL WORK (when wired): * Each db_*.ts will call a helper (core__idb_dexie.ts) on open that checks a * lightweight `_meta` table. If the stored version for a table doesn't match * the constant here, the table is cleared and the version record is updated. * The SWR pattern then repopulates from the API on next access. * * HOW TO USE (once active): * Bump a table's version here when properties_to_save changes in a way that * makes existing cached records stale (e.g. adding/removing stored fields, * changing computed field behavior). Do NOT bump for schema-only changes * (new indexes, new tables) — those belong in db.version() Dexie migrations. * * IDAA NOTES: * IDAA tables (posts, archives) are already cleared aggressively via * indexedDB.deleteDatabase() on sign-out and on auth failure in (idaa)/+layout.svelte. * The content version check is a complementary mechanism for deploy-time resets, * NOT a replacement for the auth-driven wipe. When wiring, ensure IDAA tables are * only cleared on IDB open (not mid-session), and that the _meta table itself is * also cleared when deleteDatabase() is called. */ export const IDB_CONTENT_VERSIONS = { journals: { journal: 3, journal_entry: 3 // 2026-05-14: removed content_md_html + history_md_html from properties_to_save }, events: { event: 1, event_session: 1, event_presenter: 1, event_badge: 1, event_device: 1, event_location: 1, event_file: 1 }, core: { site_domain: 1, person: 1, user: 1 }, // IDAA modules — see IDAA NOTES above before wiring these posts: { post: 1, post_comment: 1 }, archives: { archive: 1, archive_content: 1 } }; // Version check side-effect: runs on import, before any persisted() call. // Guard presence of `localStorage` and its functions for safety (SSR, Node flags). if ( typeof localStorage !== 'undefined' && typeof (localStorage as any).getItem === 'function' && typeof (localStorage as any).removeItem === 'function' ) { _check_and_wipe('ae_loc', AE_LOC_VERSION); _check_and_wipe('ae_events_loc', AE_EVENTS_LOC_VERSION); _check_and_wipe('ae_idaa_loc', AE_IDAA_LOC_VERSION); _check_and_wipe('ae_leads_loc', AE_LEADS_LOC_VERSION); // ae_pres_mgmt_loc uses PersistedState (runed) which stores raw JSON without a __version // field. The _check_and_wipe mechanism requires __version in the stored data — do NOT // add it here until pres_mgmt_loc_defaults includes __version. For now the key is new // (no stale data exists) so no wipe is needed. } function _check_and_wipe(key: string, expected_version: number): void { try { // Defensive: ensure methods still exist at call time. if (typeof (localStorage as any).getItem !== 'function') return; const raw = localStorage.getItem(key); if (!raw) return; // No stored value — nothing to wipe. const parsed = JSON.parse(raw); if (parsed?.__version !== expected_version) { if (typeof (localStorage as any).removeItem === 'function') { localStorage.removeItem(key); } console.info( `[store_versions] '${key}' wiped — schema v${parsed?.__version ?? 'none'} → v${expected_version}` ); } } catch { // Corrupt JSON — wipe unconditionally if possible. if (typeof (localStorage as any).removeItem === 'function') { localStorage.removeItem(key); } console.warn( `[store_versions] '${key}' wiped — corrupt JSON in localStorage` ); } }