Appearance
Préférences des applis : lire, écrire et observer
Les préférences sont les réglages de l'appli choisis par le streamer. Leur schéma vient de preferences.config.js ; les valeurs effectives se lisent dans kapp.preferences (alias k.preferences). Ce parcours concerne les applis, pas les widgets.
Pour des scores, compteurs et données métier qui évoluent pendant le jeu, utilise plutôt les stockages V2. L'écriture des préférences reste possible lorsqu'il s'agit bien de modifier un réglage.
Trouver le bon contrat
| Besoin | Fiche |
|---|---|
| Déclarer le formulaire, traduire ses libellés, réutiliser un modèle | Schéma et présentation |
| Choisir un champ et connaître la valeur reçue | Types et options |
| Définir une liste, ses valeurs initiales et ses nouveaux éléments | Groupes et collections |
| Masquer, désactiver ou rendre obligatoire un champ | Conditions et chemins |
| Comprendre les réglages effectifs et les écritures conditionnelles | Variantes |
| Préserver les réglages lors d'une nouvelle version | Migrations |
| Configurer une annonce et ses tags | Préférences d'annonce |
| Choisir un média ou placer une zone | Médias et placements |
| Ajouter un panneau HTML personnalisé | Prefs panels |
Lecture et application initiale
kapp.preferences.get() renvoie tout l'arbre hydraté ; get('theme.color') renvoie une valeur, ou undefined si le chemin manque. Les indices numériques sont acceptés : get('items[0].title') et get('items.0.title'). Les marqueurs de formulaire @self et @parent ne s'utilisent pas ici.
Le global prefs et kapp.preferences.preferences donnent l'arbre courant. Le SDK remplace cet objet au rafraîchissement : une variable qui conserve un ancien objet ou une valeur extraite ne se met pas à jour toute seule.
Dans script.js, chargé par le bootstrap après l'initialisation du SDK :
js
function applyPreferences() {
const color = kapp.preferences.get('theme.color') ?? '#9146FF';
document.documentElement.style.setProperty('--app-accent', color);
}
applyPreferences(); // L'événement UPDATED ne rejoue pas l'état initial.
kapp.preferences.events.on(kapp.preferences.EVENTS.UPDATED, applyPreferences);
// Si ce composant est détruit avant l'appli :
// kapp.preferences.events.off(kapp.preferences.EVENTS.UPDATED, applyPreferences);Le callback est appelé après le rechargement de tout l'arbre. on, once et off sont disponibles ; garde la même fonction pour te désabonner. Les objets hydratés (média, viewer, annonce…) ne sont pas nécessairement identiques à leurs valeurs stockées : voir le catalogue des types.
Écriture confirmée
await kapp.preferences.set(changes) attend un tableau de { path, data } et renvoie { changeset, errors }. Après le await, les lectures locales incluent l'écriture confirmée. Vérifie les erreurs individuelles ; un résultat ne garantit pas que tous les champs demandés ont été acceptés.
js
// Fragment à appeler dans une fonction async ; theme.color existe dans le schéma.
const { changeset, errors } = await kapp.preferences.set([
{ path: 'theme.color', data: '#9146FF' },
]);
if (errors.length) console.warn('Réglages refusés', errors);
console.info('Couleur effective', kapp.preferences.get('theme.color'));
console.info('Chemins signalés', Object.keys(changeset));Une mutation directe comme prefs.theme.color = 'red' ne persiste rien. Une panne réseau peut aussi rejeter la Promise : laisse le traitement d'erreur de ton action l'afficher, sans rejouer aveuglément l'écriture.
Comprendre changeset
Le résultat de set() et le callback UPDATED utilisent PreferenceChangedPaths = Record<string, true> | [], pas le tableau d'écritures ChangeSet[].
| Valeur | Interprétation |
|---|---|
{ "theme.color": true } | Carte de chemins modifiés, sans nouvelles valeurs. Relire les valeurs nécessaires. |
[] dans le résultat d'écriture | Aucun changement effectif. |
[] dans un événement de resynchronisation | Rafraîchissement sans détail des chemins : relire les réglages utilisés. |
{ "": true } | Rafraîchissement global ; la clé vide n'est pas un champ à traiter séparément. |
Utilise Object.keys(changeset), jamais changeset.map(). La recette ci-dessus relit les valeurs dans tous les cas. Une écriture sans changement effectif ne génère pas de notification ; les événements de resynchronisation restent possibles.
La destination d'une écriture dépend de la variante gagnante. Les collections ont aussi des identités internes : voir leurs règles de lecture et d'écriture.