feat(idb): add IDB content version check system, wire to journals

Adds check_and_clear_idb_tables() helper in core__idb_dexie.ts that clears
Dexie tables when their content version changes. Version numbers live in
IDB_CONTENT_VERSIONS (store_versions.ts); state tracked in localStorage
(ae_idb_ver__{module}__{table}) so each table clears exactly once per bump.

Wired into db_journals.ts (pilot): journal_entry at v3 clears stale
content_md_html/history_md_html data cached before the properties_to_save fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-05-14 16:53:55 -04:00
parent 042265008c
commit 95a86b16fa
4 changed files with 144 additions and 0 deletions

View File

@@ -1,6 +1,53 @@
import type { Dexie, Table } from 'dexie';
import { browser } from '$app/environment';
/**
* Checks IDB table content versions and clears any tables whose version has
* changed since the last check.
*
* Version numbers live in IDB_CONTENT_VERSIONS (store_versions.ts). State is
* tracked in localStorage (ae_idb_ver__{module}__{table}) so each table is
* cleared exactly once per version bump, not on every page load.
*
* Call once at module init in each db_*.ts, after the singleton is created.
* The clear is intentionally fire-and-forget — the SWR pattern repopulates
* from the API naturally after a cache miss.
*
* A null stored version (never tracked) is treated as outdated so existing
* installs with stale cached data are cleaned up on first run.
*/
export async function check_and_clear_idb_tables({
db_instance,
module_name,
table_versions,
log_lvl = 0
}: {
db_instance: Dexie;
module_name: string;
table_versions: Record<string, number>;
log_lvl?: number;
}): Promise<void> {
if (!browser) return;
for (const [table_name, expected_version] of Object.entries(table_versions)) {
const ls_key = `ae_idb_ver__${module_name}__${table_name}`;
const stored_raw = localStorage.getItem(ls_key);
const stored_version = stored_raw !== null ? parseInt(stored_raw, 10) : null;
if (stored_version === expected_version) continue;
try {
await db_instance.table(table_name).clear();
localStorage.setItem(ls_key, String(expected_version));
console.log(
`[IDB] "${module_name}.${table_name}" cleared — v${stored_version ?? 'new'} → v${expected_version}`
);
} catch (e) {
console.warn(`[IDB] Failed to clear "${module_name}.${table_name}":`, e);
}
}
}
/**
* Extracts the primary key from an object using a prioritized list of possible key names.
* @param obj The object to extract the ID from.