Architecture.de - dsblank/gramps-connect GitHub Wiki
🌐 English · Español · Français · Nederlands · 简体中文
Gramps Connect ist ein React-Frontend (app/), das über dessen REST-API
mit einem gramps-web-api-Backend spricht — es forkt gramps-web-api
nicht und ersetzt es nicht, es ist ein anderer Client für denselben
Server. Zwei Mechanismen machen es möglich, dass sich dieses Frontend
gleichzeitig schnell und kollaborativ anfühlt: ein lokaler Cache und ein
leichtgewichtiges Live-Sync-Polling, aufgesetzt auf einen Endpunkt, den
gramps-web-api bereits mitbringt.
Ein WASM-Build von SQLite läuft im Browser, spiegelt Serverdaten in
lokale Tabellen und speichert sie dauerhaft in
OPFS
(dem eigenen privaten Dateisystem des Browsers), sodass ein
wiederholter Besuch das Netzwerk komplett überspringen kann. Daten
werden über die schnellen, SQL-heruntergedrückten
/api/<type>/query/-Endpunkte von gramps-web-api abgerufen —
dieselben Endpunkte, zu denen GOQL-Bedingungen und
Gramplet-where=-Klauseln kompilieren — statt sich durch
vollständige, seitenweise REST-Antworten pro Objekt zu blättern.
Der Lohn ist das, was die Übersicht beschreibt: sobald ein Teil des Stammbaums einmal angesehen wurde, fühlen sich Durchsuchen, Sortieren und Suchen in diesem Teil danach sofort an, selbst bei Stammbäumen mit Zehntausenden von Personen, wo diese Art der Suche gegen ein schlichtes, unindiziertes REST-Backend sonst gut und gerne über eine Minute dauern kann.
Das ist auch, warum die feste admin/admin-Desktop-Version und eine
echte Server-Bereitstellung genau denselben Frontend-Code ohne
Sonderbehandlung teilen können: dem Cache ist nur wichtig, dass er mit
einem gramps-web-api-förmigen /api/ spricht, nicht, wer es hostet.
Eine Falle, die man kennen sollte: der browserseitige Cache ist nach einem festen Dateinamen pro Ansicht geschlüsselt, nicht nach Backend-URL oder Stammbaum-ID. Zu wechseln, auf welches Backend man zeigt, oder einen Stammbaum gegen dasselbe Backend neu zu importieren/ neu anzulegen, kann ein Browser-Profil mit veralteten zwischen- gespeicherten Zeilen ohne automatische Invalidierung zurücklassen — die einzige durchgeführte Prüfung ist Schema-Kompatibilität, nicht Datenidentität. Sehen Daten nach einem Backend-Wechsel jemals veraltet aus, von Hand leeren: DevTools → Application → Storage → Website-Daten löschen (oder gezielt OPFS).
Der Client fragt den bereits bestehenden Endpunkt
GET /api/transactions/history/ von gramps-web-api ab (das
Prüf-/Rückgängig-Protokoll für Objektänderungen, das er ohnehin schon
mitbringt, nichts eigens dafür Hinzugefügtes) in kurzen Abständen. Für
jedes Objekt, das dieser Endpunkt als geändert meldet, ruft Gramps
Connect nur diese eine Zeile im lokalen Cache erneut ab und
aktualisiert sie.
Das ist absichtlich einfach gehalten: keine dauerhafte, WebSocket-
artige Verbindung und keine Postgres-spezifische Änderungserfassung
nötig, nur ein schlichtes, authentifiziertes GET auf einem Timer —
funktioniert also gegen jedes gramps-web-api-Backend, nicht nur
eines mit Postgres dahinter. So funktioniert tatsächlich „jemand
anderes korrigiert ein Datum und der eigene Bildschirm aktualisiert
sich von selbst“ (siehe
Gemeinsam arbeiten), und so können auch die
Dev-Fixtures Synchronisierung ausüben, ohne
eine echte Postgres-Instanz zu brauchen — sogar die reinen
SQLite-Varianten unterstützen es, da es nur eine Abfrage ist.
Was Live-Synchronisierung noch nicht tut: es gibt keine Präsenzschicht (wer gerade was ansieht oder bearbeitet) und keinen benutzerseitigen Verlaufs-Browser — siehe Roadmap und bekannte Einschränkungen.
-
app/— der produktive React-Client: alle zehn Objekttyp-Ansichten (Person, Familie, Ereignis, Ort, Aufbewahrungsort, Quelle, Fundstelle, Medien, Notiz, Etikett — siehe Datenmodell und Bearbeitung),where_expr/GOQL-Filterung, ein in OPFS gespeicherter WASM-SQLite- Cache und Live-Synchronisierung, hinter einer aufuseSyncExternalStorebasierenden Store-Schicht (app/src/store/) mit@tanstack/react-virtualfürs Scrollen. -
dev-fixtures/— echtegramps-web-api-Backends, umapp/lokal dagegen laufen zu lassen; nicht Teil des ausgelieferten Produkts, sondern das, was lokale Entwicklung ohne von Hand konfigurierten Server erst möglich macht. Siehe Entwicklung für die drei Varianten (layer2-local-cache/api-fixture,api-fixture-exampleundlayer3-sync/api-fixture) und wofür jede da ist. -
packages/gramps-date/— ein TypeScript-Port von Gramps' eigenemDate-Modell, Kalenderumrechnung und lokalisierter Datumsanzeige, vonapp/verwendet, um eine Gramps-Date-Struktur zu rendern, zu parsen oder zu bauen, ohne einen langsamen Netzwerk-Umweg pro Objekt über Gramps' eigenen Python-Datumsanzeiger für jede Zeile einer Tabelle. Es deckt alle zehn Gramps-Kalender ab (einschließlich der chinesischen, koreanischen und vietnamesischen Mondkalender von Gramps 6.2), strukturierte Datumseingabe und -validierung sowie Gramps' Datumsanzeige und -erkennung in allen 43 Datumssprachen von Gramps (Englisch eingebaut, die übrigen bei Bedarf nachgeladen), deren Zeichenketten seinscripts/generate_gramps_locales.pyaus einem laufenden Gramps erzeugt. Es ist eine Übersetzung von Gramps' eigenemgramps/gen/lib/date.py/gcalendar.py/_datedisplay.py/_dateparser.pyaus Python nach TypeScript, in seiner Testsuite gegen Gramps' eigene Ausgabe und die Datumssätze aus Gramps' Unit-Tests gegengeprüft; Gramps-Fehler, die es behebt statt sie zu übernehmen, sind in seinerGRAMPS_BUGS.mdaufgeführt. Siehe seine eigene README für die vollständige Herkunfts- und Lizenzgeschichte (es ist GPL-2.0-or-later-Code, eingefaltet in dieses AGPL-3.0-or-later-Projekt, genau wie es der eigenegcalendar.js-Port von gramps-web bereits tut). -
standalone/— der PyInstaller-basierte Build von gramps-connect-desktop: ein Python-Launcher (launcher.py), der das gebaute Frontend vonapp/mitgramps-web-apiund SQLite zu einer einzigen App mit nativem Fenster (oder Browser-Rückfall) bündelt. Siehe Installation. -
deploy/— die containerisierte Mehrbenutzer-Bereitstellung (app/+gramps-web-api+ Postgres + Caddy + Redis/Celery). Siehe Bereitstellung. -
gramplet_examples/undgramplet-store/— Beispiel- Gramplets und der Quellinhalt für den Katalog des In-App- Gramplet-Stores. Siehe Gramplets.
Ein npm-Workspace auf oberster Ebene (packages/*, app) verbindet
app/ und packages/gramps-date als echte Workspace-Abhängigkeiten.
Die schnellen /query/-Endpunkte, von denen app/ lebt, liegen
tatsächlich in gramps-web-api selbst (ein separates Repository, direkt
darin erweitert, abwärtskompatibel), über
gramps-object-query-language,
GOQLs eigener Implementierung — nicht in diesem Repository.
Gramplets — die Add-ons der App — laufen unter
Pyodide (nach WebAssembly kompiliertes CPython)
direkt im Browser-Tab, gegen lokal gebaute Wheels von gramps.gen.lib
(Gramps' eigenem Datenmodell, sodass der Python-Code eines Gramplets
echte Person/Family/…-Objekte sieht, keine Neuimplementierung).
Keine serverseitige Ausführung und nichts auf dem eigenen Rechner
installiert — siehe
Entwicklung dafür, wie diese
Wheels gebaut werden, und Gramplets dafür, wie die
sandboxed API (people(), filter(), db, row(), html(), …)
zusammengesetzt ist.