All of the changes from today (Wednesday February 25, 2026) need to be reviewed. We spent over 6 hours trying to fix the page loading when viewing a fresh Session ID and Presentation ID. OpenAI and Gemini failed hard!!! I am at a lost and frustrated. I will probably need to deal with this myself. :-/

This commit is contained in:
Scott Idem
2026-02-25 18:34:21 -05:00
parent 17620b6fbc
commit 7b5c7528b6
22 changed files with 1674 additions and 2828 deletions

View File

@@ -92,6 +92,53 @@ export function createLiveQueryStore<T>(query: () => T | Promise<T>) {
The `createLiveQueryStore` function creates a readable store that automatically updates whenever the data in the `friends` table changes. The `$friends` variable in the component will always contain the latest data from the database.
## Page Load Strategies (Avoiding the "Waterfall")
When loading data for a primary page view (e.g., viewing a specific Journal, Session, or Person), you must choose a synchronization strategy to ensure the UI renders correctly on the first load.
### ❌ The "Fire & Forget" Anti-Pattern (AVOID)
Triggering a background load in `+page.ts` without `await` leads to race conditions.
1. `+page.svelte` mounts immediately.
2. `liveQuery` runs against an empty IndexedDB.
3. API data arrives later and writes to IndexedDB.
4. **Failure:** Svelte 5 + Dexie `liveQuery` may not automatically detect this first "cold start" update without a manual refresh.
### ✅ The "Blocking Loader" Pattern (RECOMMENDED)
Ensure the data is in IndexedDB **before** the component mounts.
1. In `+page.ts`, `await` the API load function.
2. In `+page.svelte`, the `liveQuery` will see the data immediately upon mount.
**Example (+page.ts):**
```typescript
export async function load({ params }) {
// Blocking await ensures IDB is populated
await journals_func.load_ae_obj_id__journal({
journal_id: params.journal_id,
try_cache: true
});
return {};
}
```
### ✅ The "Hydrate & Subscribe" Pattern (ADVANCED)
If you must use non-blocking loads, you must pass the initial data to the component to "hydrate" the state before the subscription takes over.
1. In `+page.ts`, `await` the load and **return the object**.
2. In `+page.svelte`, use the returned object as a fallback or initial state.
**Example (+page.svelte):**
```svelte
<script>
let { data } = $props();
let lq__obj = $derived(liveQuery(async () => db.table.get(id)));
</script>
<!-- Use fallback to handle the gap before liveQuery emits -->
{#if $lq__obj || data.initial_obj}
<View object={$lq__obj ?? data.initial_obj} />
{/if}
```
## Svelte 5 Binding Pitfalls
### 1. `props_invalid_value` (The "Expression Binding" Error)
@@ -156,18 +203,3 @@ let results = await db.table.where('id').equals(id).reverse().sortBy('sort_key')
let results = await db.table.where('id').equals(id).sortBy('sort_key');
return results.reverse();
```
## Current Data Flow in `ae_journals` Module
The `ae_journals` module currently uses a manual, API-first caching strategy. It does not use Dexie.js's `liveQuery` function for reactivity.
### Data Flow
1. **Fetch from API:** The `load_ae_obj_id__journal` and `load_ae_obj_li__journal` functions are used to fetch data from the API.
2. **Process Data:** The `process_ae_obj__journal_props` and `process_ae_obj__journal_entry_props` functions are used to process the data before it's saved to the database. This includes parsing Markdown, creating temporary sorting fields, and combining passcodes.
3. **Save to IndexedDB:** The `db_save_ae_obj_li__ae_obj` function is used to save the processed data to the `journal` and `journal_entry` tables in the `ae_journals_db` IndexedDB database.
4. **Manual Store Updates:** The Svelte stores in `src/lib/ae_journals/ae_journals_stores.ts` are manually updated with the fetched data.
### Future Improvements
The current implementation could be improved by refactoring it to use Dexie.js's `liveQuery` function. This would simplify the code, reduce boilerplate, and improve the reactivity of the application. By using `liveQuery`, the UI would automatically update whenever the data in the IndexedDB database changes, without the need for manual store updates.