-
Notifications
You must be signed in to change notification settings - Fork 1
Under the Hood.de
Implementierungsnotizen, die nicht in den erzählerischen Bogen von Architektur passen — Details, die man kennen sollte, wenn etwas zu debuggen ist, geprüft wird, was die App wo speichert, oder man sich fragt, warum sie sich auf eine bestimmte Weise verhält.
Beide sind auf Browser-Profil + Ursprung eingegrenzt, nicht darauf, wer angemeldet ist. Meldet sich Benutzer A ab und Benutzer B im selben Browser an (derselbe Rechner, dasselbe Browser-Profil), startet der Tab von Benutzer B mit dem, was dieser Ursprung an Speicher bereits enthielt — sofern die App es nicht ausdrücklich leert oder mit einem Namensraum versieht. Gramps Connect teilt seinen clientseitigen Speicher genau entlang dieser Linie auf die beiden APIs auf:
sessionStorage (app/src/auth/auth.ts) hält Zugriffstoken,
Refresh-Token und Benutzername. logout() leert ausdrücklich alle
drei, und sessionStorage selbst übersteht einen geschlossenen Tab
ohnehin nicht — eine frische Anmeldung startet also immer sauber, und
hier läuft nichts zwischen Benutzern durch.
localStorage hält Oberflächen-Einstellungen, und — anders als die
Auth-Token — nichts davon wird bei der Abmeldung gelöscht:
| Schlüssel | Geltungsbereich | Datei |
|---|---|---|
gramps-connect_home_person |
pro Stammbaum (geschlüsselt nach getTreeId()) |
app/src/store/homePersonPreference.ts |
gramps-connect_column_widths |
global | app/src/store/columnWidths.ts |
gramps-connect_tree_manual_expand |
global | app/src/store/treeExpandPreference.ts |
gramps-connect_aside_widths |
global | app/src/App.tsx |
gramps-connect:map-viewport |
global | app/src/components/visuals/MapCanvas.tsx |
gramps-connect_browser_notifications_enabled |
global | app/src/store/browserNotifications.ts |
Keiner davon ist nach Benutzer mit einem Namensraum versehen, und nur
home_person nach Stammbaum. Praktischer Effekt: auf einem geteilten
Rechner erbt die nächste Person, die sich anmeldet (selbst in einem
anderen Stammbaum, bei den globalen Schlüsseln), die Spaltenbreiten,
Bereichsgrößen, den Kartenausschnitt und die Benachrichtigungs-
Einstellung der vorherigen Person — und, falls es derselbe Stammbaum
ist, auch deren Ausgangsperson. Nichts Sensibles wird dabei offengelegt
(hier liegen keine Stammbaumdaten oder Zugangsdaten, nur
Anzeigeeinstellungen), aber es ist ein echtes Verhalten, das jemandem
auffallen und wonach gefragt werden könnte.
Wird jemals eine Trennung pro Benutzer gewünscht, ist die Lösung
dasselbe Muster, das homePersonPreference.ts bereits für die
Abgrenzung pro Stammbaum verwendet — das gespeicherte Objekt nach
Benutzer-ID (oder Benutzername) schlüsseln, statt nach oder zusätzlich
zu Stammbaum-ID.
Der Abruf pro Datensatz (fetchObjectExtended,
app/src/store/objectDetail.ts) des oberen rechten (und unteren
„Referenz-Detail“-)Bereichs wird von einem kleinen, speicherinternen
Stale-while-revalidate-Cache unterstützt, geschlüsselt nach Ansicht +
Handle und auf 50 Einträge begrenzt (LRU-verdrängt). Von einem
Datensatz wegzunavigieren und zu ihm zurückzukehren, zeichnet den
zuletzt bekannten Detailstand sofort neu, statt einen Ladekreisel zu
zeigen — die zugrunde liegenden Listenansichten (DataTable) haben das
bereits über ihren dauerhaften ViewStore/SQLite-Cache getan (siehe
Architektur); das schließt dieselbe Lücke für den
Detailbereich, der vorher bei jedem einzelnen Mount von Grund auf neu
abgerufen hat.
Es ist kein echter Cache im Sinne von „den Abruf überspringen“: jeder
Mount ruft weiterhin fetchObjectExtended genau wie vorher auf und
überschreibt den Cache-Eintrag mit dem frischen Ergebnis. Wie die
localStorage-Schlüssel oben ist es ein modulweiter Cache — nicht bei
Abmeldung oder Stammbaum-Wechsel geleert.
Der Bereich ruft außerdem erneut ab, wann immer
Live-Synchronisierung irgendeine
Stammbaum-Änderung meldet, nicht nur eine Änderung an der eigenen
(Ansicht, Handle). Der normale Weg der Live-Synchronisierung erhöht nur
die Revision eines ViewStore für eine Änderung, die zu dessen eigener
Tabelle/Handle passt, was für Listenansichten präzise, hier aber nicht
ausreichend ist: eine Bearbeitung an einem anderen, in die aufgelösten
Referenzen dieses Datensatzes eingebetteten Datensatz (der Text einer
Notiz, das über extend=all/Backlinks hereingezogene Datum eines
Ereignisses) würde sonst keinen erneuten Abruf auslösen und bliebe
veraltet, bis der Bereich neu gemountet wird. Bei jeder
Stammbaum-Änderung erneut abzurufen, tauscht etwas zusätzlichen
Abfrageverkehr gegen Korrektheit, statt neu herzuleiten, welche Handles
eingebettet sind — diese Form variiert je nach Objekttyp (siehe
Datenmodell und Bearbeitung).
Gramps Connect is part of the family of Gramps-based software.
Using the app
- Overview
- Installing
- Deploying
- Messaging
- GOQL (advanced search)
- Gramplets & Add-on Store
- Data Model & Editing
- FAQ
Building & contributing