Implemented offline-first fast-paths and hardened API/Layout resilience. Added reactive offline banner, root error page, and ghost site fallbacks to handle server downtime and connection loss without crashing.

This commit is contained in:
Scott Idem
2026-01-16 16:41:32 -05:00
parent 8b611e7875
commit a10accfaaf
14 changed files with 536 additions and 564 deletions

View File

@@ -31,6 +31,7 @@
import 'highlight.js/styles/github-dark.css';
import { browser } from '$app/environment';
import { online } from 'svelte/reactivity/window';
import xml from 'highlight.js/lib/languages/xml'; // for HTML
import css from 'highlight.js/lib/languages/css';
import javascript from 'highlight.js/lib/languages/javascript';
@@ -110,6 +111,10 @@
let flag_denied: boolean = $state(false); // Access Denied
// let flag_reason: string = $state(''); // Reason: New version, Expired Cache, Access Denied
// Connection Status
let is_offline = $derived(browser && online.current === false);
let api_unreachable = $derived($ae_loc?.account_id === 'ghost');
// BEGIN: Sanity Checks:
// Added 2025-07-15
if (!$ae_loc?.sys_menu) {
@@ -773,6 +778,30 @@
<!-- <link rel="manifest" href="/manifest.json"> -->
</svelte:head>
{#if browser && (is_offline || api_unreachable)}
<div
class="fixed top-0 left-0 right-0 z-[100] p-4 bg-orange-600 text-white text-center shadow-2xl flex flex-row items-center justify-center gap-4"
>
<span class="text-xl font-bold">
{#if is_offline}
<span class="fas fa-wifi-slash mr-2"></span>
Connection Offline
{:else}
<span class="fas fa-server mr-2"></span>
API Server Unreachable
{/if}
</span>
<span class="hidden md:inline">Viewing cached data. Changes may not be saved.</span>
<button
class="btn btn-sm variant-filled-white text-orange-600 font-bold"
onclick={() => window.location.reload()}
>
<RefreshCw class="inline-block mr-1 size-4" />
Retry Connection
</button>
</div>
{/if}
{#if $ae_loc?.site_google_tracking_id && $ae_loc?.site_google_tracking_id.length > 0}
<Analytics bind:site_google_tracking_id={$ae_loc.site_google_tracking_id} />
{/if}