perf(hydration): implement cache-first site discovery and SWR event loading

- Refactored lookup_site_domain_v3 to be cache-first, unblocking root layout.
- Implemented Stale-While-Revalidate (SWR) pattern for load_ae_obj_id__event.
- Added global hydration overlay and loading spinner to +layout.svelte.
- Updated site domain whitelist to persist critical account/styling metadata in Dexie.
- Refactored root load function to return immediately if cached site data is found.
This commit is contained in:
Scott Idem
2026-01-26 16:41:14 -05:00
parent c95b866969
commit 359eb9cf3f
5 changed files with 157 additions and 67 deletions

View File

@@ -91,7 +91,7 @@ export async function lookup_site_domain({
} as any;
}
// Updated 2026-01-07
// Updated 2026-01-26 (Cache-First Optimization)
export async function lookup_site_domain_v3({
api_cfg,
fqdn,
@@ -104,12 +104,34 @@ export async function lookup_site_domain_v3({
log_lvl?: number;
}): Promise<ae_SiteDomain | null> {
if (log_lvl) {
console.log(`*** lookup_site_domain_v3() *** fqdn=${fqdn}`);
console.log(`*** lookup_site_domain_v3() *** fqdn=${fqdn} (Cache-First)`);
}
// 1. FAST PATH: Check local cache first
let cached = null;
try {
cached = await db_core.site_domain.where('fqdn').equals(fqdn).first();
if (cached) {
if (log_lvl) console.log('BOOTSTRAP: Cache hit. Returning cached site domain immediately.');
// Trigger background refresh to keep cache fresh, but don't await it
_refresh_site_domain_v3_background({ api_cfg, fqdn, view, log_lvl: 0 });
return cached as any;
}
} catch (err) {
console.warn('BOOTSTRAP: Cache read failed.', err);
}
// 2. SLOW PATH: Wait for API if cache is empty
return await _refresh_site_domain_v3_background({ api_cfg, fqdn, view, log_lvl });
}
/**
* Internal helper to perform the actual API fetch and cache update
*/
async function _refresh_site_domain_v3_background({ api_cfg, fqdn, view, log_lvl }: any) {
try {
// CRITICAL: For the unauthenticated Bootstrap lookup, we must NOT send
// any existing auth tokens or account IDs that might be in the global config.
const guest_api_cfg = { ...api_cfg };
guest_api_cfg.headers = { ...api_cfg.headers };
@@ -134,30 +156,19 @@ export async function lookup_site_domain_v3({
and: [{ field: 'fqdn', op: 'eq', value: fqdn }]
};
if (log_lvl) {
console.log(`BOOTSTRAP SEARCH: fqdn=${fqdn}`);
console.log(`BOOTSTRAP HEADERS:`, guest_api_cfg.headers);
console.log(`BOOTSTRAP QUERY:`, JSON.stringify(search_query));
}
// We use search because we are looking up by a unique field (fqdn) rather than ID.
// The backend should return a list, but since FQDN is unique, it will have 1 item.
const result_li = await api.search_ae_obj_v3({
api_cfg: guest_api_cfg,
obj_type: 'site_domain',
search_query,
view, // This view should ideally join with site and account for the root lookup
view,
enabled: 'enabled',
hidden: 'all',
limit: 1,
log_lvl
});
if (log_lvl) console.log(`BOOTSTRAP RESULT:`, result_li);
if (result_li && result_li.length > 0) {
const result = result_li[0];
// Standardize and save to cache
const processed_obj_li = await process_ae_obj__site_domain_props({
obj_li: [result],
log_lvl
@@ -172,12 +183,9 @@ export async function lookup_site_domain_v3({
return result;
}
} catch (error: any) {
console.log('Site domain lookup V3 failed.', error);
if (log_lvl) console.log('Site domain refresh V3 failed.', error);
}
if (log_lvl) console.log('Attempting to load site domain from local cache (V3 fallback)...');
const cached = await db_core.site_domain.where('fqdn').equals(fqdn).first();
return (cached as any) || null;
return null;
}
export async function load_ae_obj_id__site({
@@ -661,6 +669,10 @@ const properties_to_save__site_domain = [
'site_domain_id_random',
'site_id',
'site_id_random',
'account_id',
'account_id_random',
'account_code',
'account_name',
'fqdn',
'access_key',
'enable',
@@ -671,6 +683,11 @@ const properties_to_save__site_domain = [
'sort',
'group',
'notes',
'header_image_path',
'style_href',
'google_tracking_id',
'access_code_kv_json',
'cfg_json',
'created_on',
'updated_on',
'tmp_sort_1',