diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-12-07 19:03:12 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-12-07 19:03:12 +0900 |
| commit | d91888da7199cdde7662910debfffaa758b8a128 (patch) | |
| tree | 6f31882306d6908286bf455fd1c5979ce6a43cf5 /src/client/db/index.ts | |
| parent | 463952d9ab01b80f71d7e32f98da908723303079 (diff) | |
| download | kioku-d91888da7199cdde7662910debfffaa758b8a128.tar.gz kioku-d91888da7199cdde7662910debfffaa758b8a128.tar.zst kioku-d91888da7199cdde7662910debfffaa758b8a128.zip | |
feat(client): add Dexie.js setup for IndexedDB local storage
Set up Dexie database with LocalDeck, LocalCard, and LocalReviewLog
tables for offline support. Each entity includes _synced flag for
tracking synchronization status.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/db/index.ts')
| -rw-r--r-- | src/client/db/index.ts | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/client/db/index.ts b/src/client/db/index.ts new file mode 100644 index 0000000..4c381d2 --- /dev/null +++ b/src/client/db/index.ts @@ -0,0 +1,129 @@ +import Dexie, { type EntityTable } from "dexie"; + +/** + * Card states for FSRS algorithm + */ +export const CardState = { + New: 0, + Learning: 1, + Review: 2, + Relearning: 3, +} as const; + +export type CardStateType = (typeof CardState)[keyof typeof CardState]; + +/** + * Rating values for reviews + */ +export const Rating = { + Again: 1, + Hard: 2, + Good: 3, + Easy: 4, +} as const; + +export type RatingType = (typeof Rating)[keyof typeof Rating]; + +/** + * Local deck stored in IndexedDB + * Includes _synced flag for offline sync tracking + */ +export interface LocalDeck { + id: string; + userId: string; + name: string; + description: string | null; + newCardsPerDay: number; + createdAt: Date; + updatedAt: Date; + deletedAt: Date | null; + syncVersion: number; + _synced: boolean; +} + +/** + * Local card stored in IndexedDB + * Includes _synced flag for offline sync tracking + */ +export interface LocalCard { + id: string; + deckId: string; + front: string; + back: string; + + // FSRS fields + state: CardStateType; + due: Date; + stability: number; + difficulty: number; + elapsedDays: number; + scheduledDays: number; + reps: number; + lapses: number; + lastReview: Date | null; + + createdAt: Date; + updatedAt: Date; + deletedAt: Date | null; + syncVersion: number; + _synced: boolean; +} + +/** + * Local review log stored in IndexedDB + * Includes _synced flag for offline sync tracking + * ReviewLog is append-only (no conflicts possible) + */ +export interface LocalReviewLog { + id: string; + cardId: string; + userId: string; + rating: RatingType; + state: CardStateType; + scheduledDays: number; + elapsedDays: number; + reviewedAt: Date; + durationMs: number | null; + syncVersion: number; + _synced: boolean; +} + +/** + * Kioku local database using Dexie (IndexedDB wrapper) + * + * This database stores decks, cards, and review logs locally for offline support. + * Each entity has a _synced flag to track whether it has been synchronized with the server. + */ +export class KiokuDatabase extends Dexie { + decks!: EntityTable<LocalDeck, "id">; + cards!: EntityTable<LocalCard, "id">; + reviewLogs!: EntityTable<LocalReviewLog, "id">; + + constructor() { + super("kioku"); + + this.version(1).stores({ + // Primary key is 'id', indexed fields follow + // userId: for filtering by user + // updatedAt: for sync ordering + // Note: _synced is not indexed (boolean fields can't be indexed in IndexedDB) + // Use .filter() to find unsynced items + decks: "id, userId, updatedAt", + + // deckId: for filtering cards by deck + // due: for finding due cards + // state: for filtering by card state + cards: "id, deckId, updatedAt, due, state", + + // cardId: for finding reviews for a card + // userId: for filtering by user + // reviewedAt: for ordering reviews + reviewLogs: "id, cardId, userId, reviewedAt", + }); + } +} + +/** + * Singleton instance of the Kioku database + */ +export const db = new KiokuDatabase(); |
