story-research-zapwall/docs/patterns/indexedDB-patterns.md
2026-01-07 11:00:13 +01:00

182 lines
4.1 KiB
Markdown

# 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<MyType>(key)
```
#### Récupérer par index
```typescript
const obj = await dbHelper.getByIndex<MyType>('indexName', value)
```
#### Récupérer tous les objets
```typescript
const all = await dbHelper.getAll<MyType>()
```
#### 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<void> {
await this.dbHelper.init()
}
async addItem(item: MyItem): Promise<void> {
await this.dbHelper.add(item)
}
async getItem(id: string): Promise<MyItem | null> {
return await this.dbHelper.get<MyItem>(id)
}
async getAllItems(): Promise<MyItem[]> {
return await this.dbHelper.getAll<MyItem>()
}
}
```