Registre
Dernière version
2026-10-04
Premier commit
2026-09-29

Packages

Bibliothèque · TypeScript · npm

Les paquets npm sous ce site, sous Taverla, sous Séance et sous on-record, typés aussi loin que va le compilateur.

Des petits paquets TypeScript sans dépendance tierce à l’exécution, publiés sur npm, chacun sorti d’un projet dès qu’un deuxième en avait besoin. L’un traduit, et sait dès la compilation ce que chaque message attend ; un autre dit si quelque chose a marché, sans exception et sans null ; les suivants gardent le thème choisi sans flash, ôtent les exceptions de localStorage et du presse-papiers, et partagent le reset, l’anneau de focus et les réglages du compilateur et du linter dont part chaque projet.

  • TypeScript
  • React
  • Intl
  • Vitest
  • Biome
  • Changesets
  • GitHub Actions
Documentation (s’ouvre dans un nouvel onglet)Code source (s’ouvre dans un nouvel onglet)Les 11 paquets
Publié4 · X · 2026
@adrienlcp/i18n
Refusé3 erreurs
const EN = defineDictionary({ greeting: 'Hello {name}' })

translate('greeting', { name: 'Ada' })

translate('greeting')
Refusé par le compilateur: Expected 2 arguments, but got 1

translate('greeting', { nom: 'Ada' })
Refusé par le compilateur: 'nom' does not exist in type '{ name: string }'

translate('greting', { name: 'Ada' })
Refusé par le compilateur: not assignable to '"greeting"'

Les arguments d’un message se lisent dans le message lui-même : oubliez {name} et l’appel ne compile pas. Ni génération de code, ni plugin de build.

Paquets
11sous @adrienlcp
Dernière version
2026-10-04sur npm, avec provenance
Commits
64sur main, lus le 2026-10-04
Couverture
96 %lignes exécutées par les tests de chaque paquet, lues le 2026-10-02
Installés par
6 appsTaverla, on-record, Séance, Analytics, Scoreboard, Ce site

Tel que le compilateur le lit

Mis en page comme dans un éditeur : une ligne ondulée est un build qui refuse, une ligne violette est ce que le compilateur déduit tout seul.

  1. @adrienlcp/result
    Compile0 erreur
    const parse = (input: string): Result<number, 'not_a_number'> => {
      const value = Number(input)
      return Number.isNaN(value)
        ? Result.failure('not_a_number')
        : Result.success(value)
    }
    
    const result = parse(raw)
    if (result.status === 'failure') return result.error
    Déduit par le compilateur: 'not_a_number'
    result.data
    Déduit par le compilateur: number
    

    Result tient en trente lignes. Un succès qui ne porte rien n’a pas de clé data du tout : personne n’y lit undefined.

  2. export const themeStore = createThemePreferenceStore({
      storageKey: 'app:theme'
    })
    
    // vite.config.ts: runs before the first paint
    plugins: [themePreferencePlugin(themeStore)]
    
    themeStore.setPreference('dark')
    Déduit par le compilateur: <html data-theme="dark">
    Déduit par le compilateur: dark theme-color: media="all"
    Déduit par le compilateur: light theme-color: media="not all"
    

    Un téléphone peint sa barre d’outils avec les balises theme-color, qui suivent le système, pas le visiteur. Le paquet de thème réécrit leur media query avant le premier rendu : un choix sombre sur un téléphone clair a aussi sa barre sombre.

  3. const locale = readRecognizedText({
      key: 'app:locale',
      isRecognized: isLocale
    })
    
    if (locale.status === 'failure') {
      locale.error
      Déduit par le compilateur: 'unavailable' | 'unrecognized'
    } else {
      locale.data
      Déduit par le compilateur: 'en' | 'fr' | null
    }
    

    La fenêtre privée de Safari levait une exception à chaque écriture dans localStorage ; safe-storage y renvoie un Result, comme pour un quota plein ou une valeur rangée par une ancienne version.

Ce qui est livré

  1. Le dictionnaire français est typé contre l’anglais, jusqu’à chaque paramètre : une clé oubliée ou un {nom} écrit à la place de {name} casse le build au lieu de s’afficher à l’écran.
  2. Chaque règle qu’elle impose est une erreur de compilation : ces tests-là s’écrivent en types et c’est tsc qui les vérifie.
  3. browser copie dans le presse-papiers même en HTTP simple, où l’API Clipboard n’existe pas.
  4. Versionnés avec Changesets et publiés depuis GitHub Actions avec la provenance npm, jamais depuis un portable.
  5. Ce site, Taverla, Séance et on-record les installent depuis npm, jusqu’à leurs configs TypeScript et Biome.

Les 11

Chacun à sa version sur npm, et quelle app l’installe.

    1. @adrienlcp/react-router (s’ouvre dans un nouvel onglet)

      Le fournisseur de routeur que prend chaque app.

      0.1.1Utilisé par TaverlaUtilisé par on-recordUtilisé par SéancePas utilisé par AnalyticsPas utilisé par ScoreboardUtilisé par Ce siteLivré
    2. @adrienlcp/i18n (s’ouvre dans un nouvel onglet)

      Traduit, et sait dès la compilation ce que chaque message attend.

      0.3.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsPas utilisé par ScoreboardUtilisé par Ce siteLivré
    3. @adrienlcp/theme-preference (s’ouvre dans un nouvel onglet)

      Garde le thème choisi sans flash, jusqu’à la barre du téléphone.

      0.3.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéancePas utilisé par AnalyticsPas utilisé par ScoreboardUtilisé par Ce siteLivré
    4. @adrienlcp/browser (s’ouvre dans un nouvel onglet)

      Copie dans le presse-papiers même en HTTP simple, où l’API Clipboard n’existe pas.

      0.1.1Utilisé par TaverlaUtilisé par on-recordUtilisé par SéancePas utilisé par AnalyticsPas utilisé par ScoreboardUtilisé par Ce siteLivré
    5. @adrienlcp/react (s’ouvre dans un nouvel onglet)

      Les utilitaires de contexte dont part chaque app React.

      0.3.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré
    6. @adrienlcp/react-aria (s’ouvre dans un nouvel onglet)

      L’anneau de focus et la composition de classes sur react-aria-components.

      0.1.0Utilisé par TaverlaUtilisé par on-recordPas utilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré
    7. @adrienlcp/styles (s’ouvre dans un nouvel onglet)

      Le reset et les styles partagés dont part chaque projet.

      0.5.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré
    8. @adrienlcp/result (s’ouvre dans un nouvel onglet)

      Dit si quelque chose a marché, sans exception et sans null.

      0.1.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré
    9. @adrienlcp/safe-storage (s’ouvre dans un nouvel onglet)

      Ôte les exceptions de localStorage et renvoie un Result à la place.

      0.1.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré
    10. @adrienlcp/tsconfig (s’ouvre dans un nouvel onglet)

      Les réglages du compilateur qu’étend chaque projet.

      0.1.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré
    11. @adrienlcp/biome-config (s’ouvre dans un nouvel onglet)

      Les réglages du linter et du formateur qu’étend chaque projet.

      0.1.0Utilisé par TaverlaUtilisé par on-recordUtilisé par SéanceUtilisé par AnalyticsUtilisé par ScoreboardUtilisé par Ce siteLivré

Historique

Tiré du git log, abrégé, et laissé dans sa langue : 8 commits sur 64, du plus récent au plus ancien.

  1. Darken the muted ink until it reads at WCAG AA on every surface, checked by a test
  2. Format a Temporal ZonedDateTime in {x:date}, in its own zone and calendar
  3. Check colour token contrast against WCAG from a test, through @adrienlcp/styles/contrast
  4. Add the documentation site, built from the packages' own sources
  5. Animate exits through CSS, and animate navigations with React's ViewTransition
  6. Add container query mixins and let sizes transition to keywords
  7. Hold back a package npm has never seen instead of failing the release
  8. Publish the i18n and result packagesPremier commit

Votre équipe, 2026

Je cherche mon prochain poste. Écrivez-moi, ou prenez le CV : un mis en page, et un sobre pour les logiciels de recrutement.