feat(speicher): Dokument-Ablage aufgeteilt — Index + ein Schlüssel je Text (D83)

werkbaum-docs ist nur noch der Index [{id,name,source?}]; der Text jedes
Dokuments liegt unter werkbaum-doc:<id>. Damit trifft eine volle Quota nur
das eine zu große Dokument statt jeden Flush, und ein kaputter Schlüssel
kostet ein Dokument statt aller (vorher: JSON.parse-Fehler -> Rückfall auf
das Beispiel, alle Dokumente unsichtbar). Der Tastendruck schreibt direkt
den Text-Schlüssel; der Voll-Flush vergleicht vor jedem Schreiben und räumt
verwaiste Schlüssel ab. Altformat migriert beim ersten Laden; die
Spiegel-Regel aus D82 gilt nur noch dieser Migration. Schema headless in
docstore.js (+10 Tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-27 06:58:10 +02:00
co-authored by Claude Fable 5
parent 4f34454075
commit 3072f3a9c0
6 changed files with 307 additions and 46 deletions
+16 -9
View File
@@ -149,15 +149,22 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
GUI-Einstellungen in `saveUI()`/`restoreState()` mitführen; `saveUI` liefert
während `restoring===true` nichts, damit das Wiederherstellen nicht sofort
zurückschreibt.
**Persistenz ist geteilt (D82):** Der Tastendruck schreibt über
`persistActiveText()` NUR den Spiegel `werkbaum-src`; das volle Array
schreibt `persistDocs()` an Flush-Punkten (Wechseln/Anlegen/Löschen/
Umbenennen, `pagehide`, verborgener Tab) — es serialisiert ALLE Dokumente,
nie wieder in einen Tastendruck-Pfad hängen. Beim Laden **gewinnt der
Spiegel** für das aktive Dokument (`loadDocs`), und zwar zwingend **vor**
`seedShippedDocs()` — danach drehte der ältere Spiegel eine frisch
nachgezogene Fassung zurück und das Dokument gälte für immer als
bearbeitet. Scheitert ein Write (Quota), meldet die persistente Warnung
**Persistenz ist geteilt (D82) und je Dokument abgelegt (D83):** Das
Schema liegt headless in `docstore.js``werkbaum-docs` ist nur der
INDEX `[{id,name,source?}]`, der Text jedes Dokuments ein eigener
Schlüssel `werkbaum-doc:<id>`. Der Tastendruck schreibt über
`persistActiveText()`/`storeDocText()` NUR den aktiven Text (+ Spiegel
`werkbaum-src` als Rollback-Fallback); den Voll-Flush macht
`persistDocs()`/`storeDocs()` an Flush-Punkten (Wechseln/Anlegen/Löschen/
Umbenennen, `pagehide`, verborgener Tab) — mit Vergleich vor jedem
Schreiben und Abräumen verwaister Text-Schlüssel; nie wieder eine
Voll-Serialisierung in einen Tastendruck-Pfad hängen. Die „Spiegel
gewinnt"-Regel in `loadDocs` gilt NUR noch der einmaligen Migration aus
dem Altformat (Texte im Array) und muss **vor** `seedShippedDocs()`
laufen — danach drehte der ältere Spiegel eine frisch nachgezogene
Fassung zurück und das Dokument gälte für immer als bearbeitet. Ein
fehlender Text-Schlüssel ergibt ein leeres Dokument, nie den Verlust der
Liste. Scheitert ein Write (Quota), meldet die persistente Warnung
`storeFailed` (`noteStore()`, rendert nur an der Flanke) — nie wieder
still schlucken.
- Dokumente (D22): mehrere umschaltbare Notationstexte. `loadDocs()` migriert bei