Architecture.fr - dsblank/gramps-connect GitHub Wiki

🌐 English · Deutsch · Español · Nederlands · 简体中文

Architecture

Gramps Connect est un frontend React (app/) qui parle à un backend gramps-web-api via son API REST — il ne fork pas et ne remplace pas gramps-web-api, c'est un client différent pour le même serveur. Deux mécanismes rendent possible pour ce frontend de sembler à la fois rapide et collaboratif : un cache local, et une requête légère de synchronisation en direct superposée à un endpoint que gramps-web-api fournit déjà.

Cache local

Un build WASM de SQLite s'exécute dans le navigateur, reflétant les données du serveur dans des tables locales et les conservant dans OPFS (le propre système de fichiers privé du navigateur) pour qu'une visite répétée puisse complètement éviter le réseau. Les données sont récupérées via les endpoints rapides /api/<type>/query/ de gramps-web-api, avec traitement SQL poussé côté serveur — les mêmes endpoints vers lesquels compilent les conditions GOQL et les clauses where= des Gramplets — plutôt qu'en paginant à travers des réponses REST complètes par objet.

Le gain est ce que décrit l'Aperçu : une fois qu'une partie de l'arbre a été consultée, parcourir, trier et rechercher dans cette partie redeviennent instantanés ensuite, même sur des arbres avec des dizaines de milliers de personnes, où ce genre de recherche peut sinon prendre bien plus d'une minute contre un backend REST simple et non indexé.

C'est aussi pourquoi la version pour ordinateur à admin/admin fixe et un vrai déploiement serveur peuvent partager exactement le même code frontend sans traitement spécial : le cache se soucie seulement de parler à un /api/ de forme gramps-web-api, pas de qui l'héberge.

Un piège à connaître : le cache côté navigateur est indexé par un nom de fichier fixe par vue, pas par URL de backend ou ID d'arbre. Changer de backend visé, ou réimporter/recréer un arbre contre le même backend, peut laisser un profil de navigateur servir des lignes en cache obsolètes sans invalidation automatique — la seule vérification effectuée porte sur la compatibilité de schéma, pas l'identité des données. Si les données semblent un jour obsolètes après un changement de backend, les effacer manuellement : DevTools → Application → Storage → effacer les données du site (ou spécifiquement OPFS).

Synchronisation en direct

Le client interroge l'endpoint déjà existant GET /api/transactions/history/ de gramps-web-api (le journal d'audit/annulation des modifications d'objets qu'il fournit déjà, rien d'ajouté pour l'occasion) à intervalle court. Pour chaque objet que cet endpoint signale comme modifié, Gramps Connect récupère à nouveau et met à jour seulement cette ligne dans le cache local.

C'est délibérément simple : aucune connexion persistante de type WebSocket ni de capture de changement de données spécifique à Postgres n'est requise, juste un simple GET authentifié sur une minuterie — cela fonctionne donc contre n'importe quel backend gramps-web-api, pas seulement un avec Postgres derrière. C'est ainsi que « quelqu'un d'autre corrige une date et votre écran se met à jour tout seul » (voir Travailler ensemble) fonctionne réellement, et c'est aussi ainsi que les fixtures de développement peuvent exercer la synchronisation sans avoir besoin d'une véritable instance Postgres — même les fixtures en pur SQLite le prennent en charge, puisque ce n'est qu'une requête.

Ce que la synchronisation en direct ne fait pas encore : il n'y a pas de couche de présence (qui consulte ou modifie quoi en ce moment) ni de navigateur d'historique côté utilisateur — voir Feuille de route et limitations connues.

Organisation du dépôt

  • app/ — le client React de production : les dix vues de type d'objet (personne, famille, événement, lieu, dépôt, source, citation, media, note, étiquette — voir Modèle de données et édition), le filtrage where_expr/GOQL, un cache WASM SQLite conservé dans OPFS, et la synchronisation en direct, derrière une couche de store basée sur useSyncExternalStore (app/src/store/) avec @tanstack/react-virtual pour le défilement.
  • dev-fixtures/ — de véritables backends gramps-web-api pour faire tourner app/ localement contre eux ; pas partie du produit livré, juste ce qui rend le développement local possible sans configurer un serveur à la main. Voir Développement pour les trois variantes (layer2-local-cache/api-fixture, api-fixture-example, et layer3-sync/api-fixture) et à quoi chacune sert.
  • packages/gramps-date/ — un portage TypeScript du propre modèle Date de Gramps, de la conversion de calendrier, et de l'affichage de date sensible à la locale, utilisé par app/ pour pouvoir rendre, analyser ou construire une structure Date de Gramps sans un aller-retour réseau lent par objet via le propre afficheur de date Python de Gramps pour chaque ligne d'un tableau. Il couvre les dix calendriers de Gramps (y compris les calendriers lunaires chinois, coréen et vietnamien de Gramps 6.2), la saisie et la validation de date structurée, ainsi que l'affichage et l'analyse des dates de Gramps dans les 43 langues de date de Gramps (l'anglais intégré, les autres chargées à la demande), leurs chaînes étant générées à partir d'un Gramps réel par son scripts/generate_gramps_locales.py. C'est une traduction des propres gramps/gen/lib/date.py/gcalendar.py/_datedisplay.py/ _dateparser.py du cœur de Gramps, de Python vers TypeScript, vérifiée dans sa suite de tests par recoupement avec la sortie de Gramps lui-même et les jeux de dates de ses tests unitaires ; les bogues de Gramps qu'il corrige au lieu de les recopier sont listés dans son GRAMPS_BUGS.md. Voir son propre README pour l'histoire complète de provenance et de licence (c'est du code GPL-2.0-or-later intégré dans ce projet AGPL-3.0-or-later, de la même façon que le propre portage gcalendar.js de gramps-web le fait déjà).
  • standalone/ — le build basé sur PyInstaller de gramps-connect-desktop : un lanceur Python (launcher.py) qui regroupe le frontend construit de app/ avec gramps-web-api et SQLite en une seule application à fenêtre native (ou repli navigateur). Voir Installation.
  • deploy/ — le déploiement conteneurisé multi-utilisateur (app/
    • gramps-web-api + Postgres + Caddy + Redis/Celery). Voir Déploiement.
  • gramplet_examples/ et gramplet-store/ — des Gramplets d'exemple et le contenu source du catalogue de la boutique de Gramplets intégrée à l'application. Voir Gramplets.

Un workspace npm de premier niveau (packages/*, app) relie app/ et packages/gramps-date comme de véritables dépendances de workspace. Les endpoints rapides /query/ dont dépend app/ vivent en réalité dans gramps-web-api lui-même (un dépôt séparé, étendu directement dedans, rétrocompatible), via gramps-object-query-language, la propre implémentation de GOQL — pas dans ce dépôt.

Les extensions exécutent du Python dans le navigateur

Les Gramplets — les extensions de l'application — s'exécutent sous Pyodide (CPython compilé en WebAssembly) directement dans l'onglet de navigateur, contre des wheels construits localement de gramps.gen.lib (le propre modèle de données de Gramps, de sorte que le code Python d'un Gramplet voit de vrais objets Person/Family/…, pas une réimplémentation). Aucune exécution côté serveur et rien d'installé sur votre machine — voir Développement pour comment ces wheels sont construits, et Gramplets pour comment l'API en bac à sable (people(), filter(), db, row(), html(), …) est assemblée.

⚠️ **GitHub.com Fallback** ⚠️