feat(helpers): lire plusieurs collections Astro dans un même build (0.18.0) - #81
Merged
Conversation
….18.0) Les helpers lisaient COLLECTION_NAME — une constante de module figée à l'import — derrière un cache scalaire. Sur un site qui interroge plusieurs collections dans le même build, la première lue était rendue à toutes les requêtes suivantes, sans erreur ni avertissement. Le besoin vient de mathieu-drouet.com, qui tient une collection par locale (`series` pour l'anglais, `series_fr` pour le français) : c'est le blocage qui arrêtait l'étape 2 de sa convergence vers le plugin (izo/mathieu-drouet.com#237). getSeriesList, getSeriesBySlug, getSections, getSubSeries, getAllTags et getAllCollections acceptent désormais une collection en dernier argument ; querySeries la reçoit via l'option `collectionName`. Le cache est indexé par collection. `collectionName` ne se confond pas avec l'option `collection` de querySeries, qui filtre sur le premier segment du slug à l'intérieur d'une collection. L'une choisit la collection, l'autre filtre dedans. Rétrocompatible : tous les arguments sont optionnels et retombent sur le comportement antérieur. Les 203 tests existants passent sans modification. 9 tests ajoutés, dont un qui compte les lectures réelles par collection — un cache scalaire fait passer les tests de résultat tout en servant le mauvais corpus, donc seul le compte de lectures prouve l'indexation. Vérifié failable : 7 des 9 échouent sur le code d'avant. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4BcSyfb5ikENAuHaQL5hb
Complète la même version : un consommateur qui a ses propres règles de visibilité, de tri ou de pagination ne peut hériter d'aucun helper filtrant. `getSeriesList()` écarte les sections et les brouillons, trie par date ; qui ne veut pas de ces règles n'avait d'autre choix que `getCollection()` en direct — et réimplémentait le cache que ce module tient déjà. C'est le cas de mathieu-drouet.com : il exclut les séries privées de tous ses listings, une notion qui n'a pas vocation à remonter ici (ADR-001), et qui l'obligeait à dupliquer toute la couche de lecture pour l'appliquer. Le tableau rendu est celui du cache — documenté comme tel : le muter corromprait les lectures suivantes. 3 tests ajoutés (15 au total sur ce fichier), dont un qui vérifie que le brut contient bien ce que getSeriesList écarte, et un qui vérifie que les deux partagent le cache. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4BcSyfb5ikENAuHaQL5hb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Débloque l'étape 2 de la convergence de
mathieu-drouet.comvers le plugin (izo/mathieu-drouet.com#237). Mouvement C au sens de l'ADR-001 : le bloc qui bloque la migration est porté ici d'abord, puis consommé par le site.Le défaut
COLLECTION_NAMEest une constante de module, lue une fois à l'import depuisimport.meta.env.HYPERFOCALE_COLLECTION_NAME. Le cache_seriesCacheétait scalaire, sans clé de collection.Conséquence sur un site qui interroge plusieurs collections dans le même build : la première collection lue est rendue à toutes les requêtes suivantes, sans erreur ni avertissement. Sur un site bilingue, cela rend des titres anglais sur les pages françaises — le pire mode de défaillance possible, puisque rien ne le signale.
C'est le cas de
mathieu-drouet.com, qui tientseries(EN) etseries_fr(FR) et les interroge toutes deux au même build.Le correctif
Nom de collection Astro en dernier argument, optionnel partout :
getSeriesList()(collectionName?)getSeriesBySlug(slug)(slug, collectionName?)getSections()(collectionName?)getSubSeries(containerId)(containerId, collectionName?)getAllTags()(collectionName?)getAllCollections()(collectionName?)querySeries(options)options.collectionNameLe cache passe de
Series[] \| nullàMap<string, Series[]>— une lecture par collection et par build.collectionNamene se confond pas aveccollection: cette dernière filtre sur le premier segment du slug (music,fashion) à l'intérieur d'une collection. L'une choisit la collection, l'autre filtre dedans. Les deux se combinent, et un test le vérifie explicitement — la proximité des deux noms est le piège le plus probable pour un lecteur pressé.Vérification
tests/unit/multi-collection.test.ts)npm run typechecknpm run buildLe test qui compte le plus est celui qui compte les lectures réelles par collection. Un cache scalaire fait passer tous les tests de résultat tout en servant le mauvais corpus : seul le compte de lectures (
getCollectionFetchCount, et la liste des noms demandés) prouve l'indexation. Les tests de résultat seuls auraient validé le bug.Rétro-compatibilité
Aucun changement cassant. Tous les arguments sont optionnels et retombent sur le comportement antérieur : un site existant ne voit aucune différence. Version mineure — 0.18.0.
Hors périmètre
La sémantique
collectiondes helpers média (matchMedia,findManifest) est inchangée : là, le mot désigne le répertoire souspublic/content/, pas la collection Astro. Le plugin confond aujourd'hui les deux notions — elles coïncident sur un site mono-collection, plus sur un site multilingue. À traiter séparément si un consommateur en a besoin ;mathieu-drouet.comne consomme pas ces helpers (système médias propre, R2 +images.json).🤖 Generated with Claude Code
https://claude.ai/code/session_01G4BcSyfb5ikENAuHaQL5hb