fix(idaa): harden data sync against padStart crashes and fix Archive Content sort
- Hardened object processors in Archives and Posts modules to safely handle null 'sort' values, preventing runtime TypeErrors during data synchronization. - Fixed inconsistent sorting in Archive Content list by correctly implementing descending order (sort then reverse) and adding a configuration loading guard to the liveQuery. - Standardized safe data processing patterns in SVELTE_DEXIE_GUIDE.md. - Performed minor cleanup and visibility logic hardening in Recovery Meetings module.
This commit is contained in:
@@ -92,6 +92,42 @@ 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.
|
||||
|
||||
## Safe Data Processing for IndexedDB Sorting
|
||||
|
||||
When preparing data for IndexedDB, especially when creating composite sort keys, it is critical to handle `null` or `undefined` values safely to prevent runtime crashes that can interrupt the data synchronization process.
|
||||
|
||||
### 1. Safe String Padding
|
||||
Attempting to call `.toString()` or `.padStart()` on a `null` or `undefined` value will throw a `TypeError`. This is a common pitfall when processing optional fields like `sort` or `group`.
|
||||
|
||||
**Bad Pattern (Crash Risk):**
|
||||
```typescript
|
||||
// Crashes if obj.sort is null or undefined
|
||||
obj.tmp_sort_1 = `${obj.sort.toString().padStart(3, '0')}`;
|
||||
obj.tmp_sort_2 = `${obj.sort?.toString().padStart(3, '0') ?? ''}`; // Still risky if chaining is misunderstood
|
||||
```
|
||||
|
||||
**Good Pattern (Safe):**
|
||||
```typescript
|
||||
// Safely handle null/undefined by defaulting to 0 or an empty string BEFORE string manipulation
|
||||
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
||||
```
|
||||
|
||||
### 2. Correct Sorting with Dexie
|
||||
Dexie's `sortBy()` method returns a new array sorted by the specified key. It **ignores** previous `reverse()` calls on the collection. To achieve a descending sort, you must sort first and then reverse the resulting array.
|
||||
|
||||
**Incorrect (Ascending Sort Result):**
|
||||
```typescript
|
||||
// .reverse() is ignored by .sortBy()
|
||||
let results = await db.table.where('id').equals(id).reverse().sortBy('sort_key');
|
||||
```
|
||||
|
||||
**Correct (Descending Sort Result):**
|
||||
```typescript
|
||||
// Sort ascending first, then reverse the array
|
||||
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.
|
||||
@@ -105,4 +141,4 @@ The `ae_journals` module currently uses a manual, API-first caching strategy. It
|
||||
|
||||
### 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.
|
||||
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.
|
||||
Reference in New Issue
Block a user