Files
OSIT-AE-App-Svelte/documentation/SVELTE_DEXIE_GUIDE.md
Scott Idem 064942c647 docs: Reorganize documentation files
- Centralize project-wide documentation into a new /documentation directory.
- Remove old, deprecated README guideline files.
- Create a comprehensive AETHER_API_OBJECTS.md file detailing all API data models.
2025-11-20 14:26:30 -05:00

109 lines
6.0 KiB
Markdown

# Svelte and Dexie.js Integration Guide
This document provides a guide to integrating Svelte (with a focus on Runes) and Dexie.js for building reactive web applications. It covers key concepts and best practices for managing reactivity between Svelte components and the Dexie.js database.
## Svelte 5 Migration Guide
Svelte 5 introduces "runes" as a new way to manage reactivity. This is a major change from previous versions of Svelte, and it's important to understand the breaking changes before migrating.
### Key Breaking Changes
- **`let` is no longer reactive:** In Svelte 4, any `let` variable declared in the top-level scope of a component was automatically reactive. In Svelte 5, you must explicitly declare reactive state using the `$state` rune.
- **`$:` is replaced by `$derived` and `$effect`:** The `$` label is no longer used for reactive statements. Instead, you should use the `$derived` rune for computed values and the `$effect` rune for side effects.
- **`export let` is replaced by `$props`:** Component props are now declared using the `$props` rune, which provides a more flexible and explicit way to define component APIs.
- **Event handling:** The `on:` directive is replaced by event attributes (e.g., `onclick`). Component events are now handled using callback props instead of `createEventDispatcher`.
- **Slots are replaced by snippets:** The `<slot>` element is replaced by the `{#snippet ...}` block, which provides a more powerful and flexible way to pass content to components.
For a complete list of breaking changes, refer to the [Svelte 5 migration guide](https://svelte.dev/docs/svelte/v5-migration-guide).
## Dexie.js Quick Reference
Dexie.js is a lightweight, minimalistic wrapper for IndexedDB that makes it easier to work with client-side databases.
### Key Classes and Methods
- **`Dexie`:** The main class for creating and managing IndexedDB databases.
- `new Dexie(databaseName)`: Creates a new database instance.
- `version(versionNumber).stores({ ... })`: Defines the database schema.
- **`Table`:** Represents an object store (table) in the database.
- `add(item)`: Adds a new item to the table.
- `put(item)`: Adds or updates an item in the table.
- `update(key, changes)`: Updates an existing item.
- `delete(key)`: Deletes an item by its primary key.
- `get(key)`: Retrieves an item by its primary key.
- `where(index)`: Starts a query using an index.
- `toArray()`: Retrieves all items from the table as an array.
- **`Collection`:** Represents a collection of items resulting from a query.
- `toArray()`: Retrieves all items in the collection as an array.
- `first()`: Retrieves the first item in the collection.
- `last()`: Retrieves the last item in the collection.
- `each(callback)`: Iterates over each item in the collection.
- `modify(changes)`: Updates all items in the collection.
- `delete()`: Deletes all items in the collection.
For a complete list of API methods, refer to the [Dexie.js API Reference](https://dexie.org/docs/API-Reference).
## Integrating Svelte Runes and Dexie.js
The combination of Svelte Runes and Dexie.js allows for the creation of highly reactive and efficient web applications.
### The `liveQuery` Function
Dexie.js provides a `liveQuery` function that returns an observable of the query result. This observable can be used to automatically update the UI whenever the data in the database changes.
### Using `liveQuery` with Svelte Runes
To use `liveQuery` with Svelte Runes, you can create a custom readable store that wraps the `liveQuery` observable. This store can then be used in your Svelte components to display and interact with the data.
**1. Create a `liveQuery` store:**
```typescript
import { liveQuery } from 'dexie';
import { readable } from 'svelte/store';
import { db } from './db'; // Your Dexie database instance
export function createLiveQueryStore<T>(query: () => T | Promise<T>) {
return readable<T | undefined>(undefined, (set) => {
const subscription = liveQuery(query).subscribe({
next: (result) => set(result),
error: (error) => console.error(error)
});
return () => subscription.unsubscribe();
});
}
```
**2. Use the `createLiveQueryStore` in your component:**
```html
<script>
import { createLiveQueryStore } from './stores';
import { db } from './db';
const friends = createLiveQueryStore(() => db.friends.toArray());
</script>
<ul>
{#if $friends} {#each $friends as friend}
<li>{friend.name}</li>
{/each} {/if}
</ul>
```
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.
## 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.