# Patterns d'utilisation IndexedDB **Date** : 2024-12-19 **Auteur** : Équipe 4NK ## Introduction Ce document décrit les patterns à utiliser pour interagir avec IndexedDB dans le projet. Tous les services IndexedDB doivent utiliser `IndexedDBHelper` pour garantir la cohérence et réduire la duplication. ## Pattern recommandé : Utilisation de IndexedDBHelper ### Création d'un service IndexedDB ```typescript import { createIndexedDBHelper } from '@/lib/helpers/indexedDBHelper' const dbHelper = createIndexedDBHelper({ dbName: 'my_database', version: 1, storeName: 'my_store', keyPath: 'id', indexes: [ { name: 'timestamp', keyPath: 'timestamp', unique: false }, { name: 'type', keyPath: 'type', unique: false }, ], onUpgrade: (db, event) => { // Migration logic if needed }, }) // Utilisation await dbHelper.init() const store = await dbHelper.getStore('readwrite') await dbHelper.add({ id: '1', data: 'value' }) ``` ### Opérations courantes #### Ajouter un objet ```typescript await dbHelper.add(object) ``` #### Récupérer un objet par clé ```typescript const obj = await dbHelper.get(key) ``` #### Récupérer par index ```typescript const obj = await dbHelper.getByIndex('indexName', value) ``` #### Récupérer tous les objets ```typescript const all = await dbHelper.getAll() ``` #### Compter par index ```typescript const count = await dbHelper.countByIndex('indexName', IDBKeyRange.only(value)) ``` #### Mettre à jour un objet ```typescript await dbHelper.update(object) ``` #### Supprimer un objet ```typescript await dbHelper.delete(key) ``` #### Supprimer tous les objets ```typescript await dbHelper.clear() ``` ## Gestion des erreurs Toutes les erreurs IndexedDB sont automatiquement wrappées dans `IndexedDBError` avec : - Message d'erreur - Nom de l'opération - Nom du store (si applicable) - Cause originale ```typescript try { await dbHelper.add(object) } catch (error) { if (error instanceof IndexedDBError) { console.error(`Operation: ${error.operation}, Store: ${error.storeName}`) } throw error } ``` ## Transactions Les transactions sont gérées automatiquement par `IndexedDBHelper`. Chaque opération utilise une transaction appropriée. Pour des opérations multiples dans une seule transaction : ```typescript const store = await dbHelper.getStore('readwrite') // Toutes les opérations sur store sont dans la même transaction await store.add(object1) await store.add(object2) // Transaction se ferme automatiquement à la fin de la fonction ``` ## Migrations Les migrations sont gérées dans `onUpgrade` : ```typescript const dbHelper = createIndexedDBHelper({ // ... onUpgrade: (db, event) => { const transaction = event.target.transaction const store = transaction.objectStore('my_store') // Ajouter un index si nécessaire if (!store.indexNames.contains('newIndex')) { store.createIndex('newIndex', 'newField', { unique: false }) } }, }) ``` ## Bonnes pratiques 1. **Toujours utiliser IndexedDBHelper** : Ne pas créer de code d'initialisation IndexedDB personnalisé 2. **Gérer les erreurs** : Toujours utiliser try/catch avec IndexedDBError 3. **Typage strict** : Utiliser les génériques TypeScript pour le typage 4. **Transactions** : Regrouper les opérations liées dans une seule transaction 5. **Migrations** : Tester les migrations sur des données réelles avant déploiement ## Exemples complets ### Service de cache simple ```typescript import { createIndexedDBHelper } from '@/lib/helpers/indexedDBHelper' class MyCacheService { private dbHelper = createIndexedDBHelper({ dbName: 'my_cache', version: 1, storeName: 'items', keyPath: 'id', indexes: [ { name: 'timestamp', keyPath: 'timestamp', unique: false }, ], }) async init(): Promise { await this.dbHelper.init() } async addItem(item: MyItem): Promise { await this.dbHelper.add(item) } async getItem(id: string): Promise { return await this.dbHelper.get(id) } async getAllItems(): Promise { return await this.dbHelper.getAll() } } ```