Migrer vers 0.2.0
Ce qui change pour une application en 0.1.x, dans l'ordre, et ce qui ne demande aucune attention.
La 0.2.0 ajoute la checklist et élargit la persistance pour lui faire place. Si vous ne passez pas
de prop storage, la mise à jour se résume à un changement de version. Si vous fournissiez votre
propre GuideStorage, une signature change et une clé de stockage se déplace.
Ce qu’on peut ignorer
Rien n’a changé du côté des visites. Tour, Step, GuideProvider, GuideTour, useTour,
useGuideStep, les politiques de cible absente, la comparaison de routes, la navigation déléguée,
translate et les labels de GuideTour sont tels quels. Les événements de visite sont
inchangés, et les trois événements de checklist sont des ajouts à l’union GuideEvent, pas des
remplacements.
La checklist est facultative. Ne pas monter ChecklistProvider laisse votre application exactement
où elle était.
pnpm up @apollovisionlabs/guide-core @apollovisionlabs/guide-mui
Sans version figée, parce que cette page traite de la sortie de la 0.1.x et non d’une version cible
précise. @apollovisionlabs/guide-mui a dépassé la 0.2.0 depuis : la 0.3.0 ajoute une prop labels
à Checklist et ChecklistLauncher pour que leurs propres textes se traduisent. C’est un ajout de
prop, sans rupture, donc cela ne change rien à cette migration ; voir
Checklist.
Rupture 1 : GuideStorage devient générique
La 0.1.x figeait l’interface sur une forme :
// 0.1.x
interface GuideStorage {
read(tourId: string): Promise<TourProgress | null>
write(tourId: string, progress: TourProgress): Promise<void>
}
La 0.2.0 rend les deux méthodes génériques sur la valeur stockée, et la clé devient une simple chaîne que l’appelant a déjà préfixée :
// 0.2.0
interface GuideStorage {
read<T>(key: string): Promise<T | null>
write<T>(key: string, value: T): Promise<void>
}
Une implémentation écrite contre l’ancienne signature ne compile plus. La correction est mécanique : rendre les deux méthodes génériques et cesser de supposer que la clé est un identifiant de visite.
Avant :
import type { GuideStorage, TourProgress } from '@apollovisionlabs/guide-core'
export function createApiStorage(baseUrl: string): GuideStorage {
return {
async read(tourId: string): Promise<TourProgress | null> {
const response = await fetch(`${baseUrl}/tours/${tourId}/progress`)
if (response.status === 404) return null
return (await response.json()) as TourProgress
},
async write(tourId: string, progress: TourProgress): Promise<void> {
await fetch(`${baseUrl}/tours/${tourId}/progress`, {
method: 'PUT',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(progress),
})
},
}
}
Après :
import type { GuideStorage } from '@apollovisionlabs/guide-core'
export function createApiStorage(baseUrl: string): GuideStorage {
return {
async read<T>(key: string): Promise<T | null> {
const response = await fetch(`${baseUrl}/guide/${encodeURIComponent(key)}`)
if (response.status === 404) return null
return (await response.json()) as T
},
async write<T>(key: string, value: T): Promise<void> {
await fetch(`${baseUrl}/guide/${encodeURIComponent(key)}`, {
method: 'PUT',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(value),
})
},
}
}
Trois choses ont bougé. Le paramètre est une clé, pas un identifiant de visite : une route construite
comme /tours/<id> ne décrit plus ce qui arrive. La valeur est opaque, donc une colonne nommée
d’après stepIndex n’a plus la bonne forme : stockez du JSON indexé par (utilisateur, clé). Et la
même instance recevra des clés checklist:<id> dès que vous monterez un ChecklistProvider avec
elle, ce qui est tout l’intérêt du changement : une implémentation, deux fonctionnalités.
Rupture 2 : la clé de stockage a changé
La 0.1.x stockait la progression d’une visite sous l’identifiant de visite nu. La 0.2.0 la stocke
sous tour:<id>.
La progression écrite par la 0.1.x se retrouve donc à une clé que plus personne ne lit. Rien ne
casse : lire tour:product dans un stockage qui ne contient que product renvoie null,
c’est-à-dire exactement le cas de la première visite, que le provider gère déjà. Un utilisateur en
plein milieu d’une visite au moment de la mise à jour recommence cette visite une fois, depuis sa
première étape. Un utilisateur qui avait terminé une visite la reverra si votre application la lui
propose.
Vous pouvez laisser les anciennes entrées où elles sont et accepter ce redémarrage unique, ce que la
bibliothèque suppose. Si ce redémarrage n’est pas acceptable chez vous, migrez les enregistrements
de votre côté en recopiant chaque <id> vers tour:<id> avant que la nouvelle version n’atteigne
les utilisateurs. Il n’y a pas d’aide de migration dans la bibliothèque, et le cas localStorage
tient en une courte boucle sur votre propre espace de nommage.
Changement de comportement : les valeurs stockées sont validées
Celui-ci ne change aucune signature : rien ne vous en avertira à la compilation.
La 0.1.x passait tel quel à l’état de la visite ce que le stockage renvoyait, en vérifiant seulement
que status valait in-progress. La 0.2.0 vérifie d’abord la forme, avec isTourProgress, et
rejette tout ce qui échoue. La progression de checklist reçoit le même traitement via
isChecklistProgress.
La conséquence : une entrée corrompue, tronquée, modifiée à la main ou écrite par une version de votre propre code qui stockait autre chose est désormais ignorée, et la visite repart de sa première étape au lieu de reprendre sur une valeur qu’il ne fallait pas croire. Si vous observiez en 0.1.x des reprises occasionnelles sur un index d’étape impossible, c’est la cause, et elle est corrigée.
Les deux gardes sont exportées, pour que votre propre code de stockage puisse poser la même question que les providers :
import { isTourProgress } from '@apollovisionlabs/guide-core'
const stored = await storage.read<unknown>('tour:product')
if (!isTourProgress(stored)) {
// rien d'exploitable à cette clé
}
Dans l’ordre
- Passez les deux paquets à leur version courante.
- Si vous fournissez un
GuideStoragemaison, élargissezreadetwriteà la signature générique et traitez le paramètre comme une clé opaque. Lancez le typecheck : rien d’autre n’a changé dans le cœur, donc un typecheck propre signifie que la signature est réglée. - Tranchez sur les clés de visite orphelines : accepter un redémarrage par utilisateur en cours de
visite, ou recopier
<id>verstour:<id>dans votre stockage avant la mise en production. - Vérifiez que rien chez vous ne dépendait d’une entrée corrompue reprise telle quelle. En pratique, il s’agit de confirmer qu’une visite repartant du début est acceptable quand une valeur stockée est illisible.
- Éventuellement, ajoutez la checklist. C’est un nouveau provider et deux nouveaux composants, et elle partage l’instance de stockage que vous avez déjà.
Pour aller plus loin
- Persistance pour le contrat complet et un exemple de stockage maison.
- Checklist pour la fonctionnalité qu’ajoute la 0.2.0.
- Référence de l’API pour tous les symboles exportés.