Lolly
App öffnen

Datenübertragung - das lolly-backup-Bündel

Alles, was sich bei einem Lolly-Nutzer ansammelt, lebt auf seinem Gerät - kein Konto, keine Cloud. Das Datenübertragungsbündel ist der Weg, wie dieser Wert sich bewegt: exportieren Sie es auf einer Installation, tragen Sie die Datei auf beliebigem Weg (USB, AirDrop, E-Mail an sich selbst, eine Netzwerkfreigabe) und importieren Sie sie auf einer anderen. Die Datei ist der Transport. Das Ziel kann offline oder online sein. Es macht keinen Unterschied, denn nichts spricht je mit einem Server.

Die beiden Schaltflächen, die eine ganze Installation umziehen: Meine Daten exportieren schreibt ein Zip, Daten importieren liest es wieder ein signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBPrüfen Sie es selbstSignierte Datei holenDie beiden Schaltflächen, die eine ganze Installation umziehen: Meine Daten exportieren schreibt ein Zip, Daten importieren liest es wieder ein signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBPrüfen Sie es selbstSignierte Datei holen

Diese Seite ist die Formatspezifikation. Die Anleitung für Endnutzer finden Sie unter Ihre Arbeit finden und wiederherstellen → Arbeit auf ein anderes Gerät übertragen. Die Implementierung ist shells/web/src/data-transfer.ts, und tests/data-transfer.test.ts legt den Round-Trip-Vertrag fest.

Umfang. Ein Bundle enthält Nutzerdaten, keine Katalog-Tools. Katalog-Tools und Katalog-Assets werden separat synchronisiert und gelten als bereits auf dem Zielgerät vorhanden (im schlimmsten Fall in einer höheren Version); Tools, die ein Nutzer selbst erstellt hat, reisen innerhalb von profile.json mit. Ein Import installiert oder aktualisiert niemals ein Katalog-Tool.

Ziele

Der Umschlag

Ein Bundle ist eine einfache .zip-Datei. Der Download wird nach der Person benannt, der er gehört - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (zum Beispiel LollyTools-Ada-Lovelace-2026-06-26-1.zip) - sodass ein Downloads-Ordner voller Backups lesbar bleibt. Der Vor- und der Nachname stammen aus dem Profil und entfallen, wenn sie nicht gesetzt sind. Ohne Profil ergibt sich LollyTools-2026-06-26-1.zip, und ein Vorname allein ergibt LollyTools-Ada-2026-06-26-1.zip. Jeder Teil wird zu einem für Dateinamen sicheren Token bereinigt (Unicode-Buchstaben/-Ziffern bleiben erhalten, Leerzeichen/Satzzeichen werden entfernt, auf 32 Zeichen begrenzt). <n> ist eine Sequenz pro Tag und Gerät, damit wiederholte Exporte am selben Tag nicht kollidieren und in Reihenfolge bleiben. backupFilename() in shells/web/src/data-transfer.ts erzeugt den Namen. Der Inhalt der Zip-Datei ist unabhängig vom Namen identisch. Darin:

PfadErforderlichInhalt
manifest.jsonjaFormat-ID, Versionen, Anzahlen und Integrität pro Teil. Das Erste, worauf ein Reader schaut.
profile.jsonwenn gesetztDer gesamte me-Datensatz des Nutzers: Name, Kontakt, Headshot-Referenz und Flags, plus Ordner, Papierkorb, Projekt-Vorlagen, Nutzer-Vorlagen und selbst erstellte Tools, Favoriten, ausgeblendete Tools, Sprach- und Emoji-Wahl. Gelesen über host.profile.
sessions.jsonjaJede gespeicherte Sitzung: Slot, Tool-ID/-Version, Label, Thumbnail (Data-URL) und vollständige Eingabedaten. Gelesen über host.state.
assets.jsonjaMetadaten für jedes hochgeladene Asset (Bilder, Schriften, Markentoken, Logos, gespeicherte Kopien von Downloads), jeweils mit Verweis auf seine Bytes unter assets/blobs/.
assets/blobs/<n>.<ext>pro AssetDie rohen Asset-Bytes (Bild- und Schriftdateien). Unkomprimiert gespeichert (bereits komprimierte Formate). Die Erweiterung ist kosmetisch. Der MIME-Typ in assets.json ist maßgeblich.
assets/blobs/<n>.c2pawenn vorhandenExtrahierte Content Credentials als exakte Binärbytes, referenziert über _credentialFile im Asset-Datensatz. Dies sind keine geräteseitigen Signierschlüssel.
design-systems.jsonwenn vorhandenDie auf dieser Installation erstellten oder hinzugefügten Designsysteme, als { active, records }. Beim Import per ID gemergt; die aktive Wahl des Bundles greift nur, wenn das Ziel noch kein eigenes Designsystem hat.
file-history.jsonoptionalVersionierte Asset-Snapshots, abgeschlossene Dateioperationsberichte und vollständige Batch-Manifeste. Der Verlaufsteil hat eine eigene Version; bereitgestellt vom internen fileHistory-Backup-Adapter der Shell.
revision-history.jsonoptional, manuelle BackupsStabile Kreations-IDs, aufbewahrte Checkpoints, Thumbnails und fortlaufende Wiederherstellungs-Entwürfe. Bereitgestellt über host.state.history.backup, wo unterstützt.
file-history/versions/pro SnapshotVorherige Asset-Bytes und extrahierte Credentials, unabhängig davon, ob das aktuelle Asset noch existiert.
file-history/results/pro abgeschlossener OperationExakte Ausgabe-Bytes. Keine für die Konvertierung ausgewählte Originaldatei wird aufbewahrt oder eingeschlossen.
prefs.jsonjaNutzereigene lokale Einstellungen: theme, sidebarWidth und der ct-metrics-Aktivitätszähler.
lolly.txtjaEine für Menschen lesbare Zusammenfassung des Bundles (Anzahlen, Profil, Dateiname) für alle, die das Zip ohne Lolly öffnen. Wird bei jedem Export neu erzeugt und beim Import erkannt, zählt daher nie als übersprungener Teil. Sie wird nach der Integritätskarte geschrieben und bleibt somit außerhalb davon.

Das Bundle ist absichtlich ein einfaches Zip: Es übersteht jeden Transportweg unversehrt, und jedes Unzip-Tool kann es einsehen.

profile.json ist der kleinste Teil und der, den ein Reader in der App zuerst sieht: die Angaben, die ein Ersteller einmal einträgt, plus die Opt-in-Einstellung, die Tools erlaubt, sie zu nutzen.

Das Profildetails-Formular, aus dem profile.json wird: Name, Kontaktdaten und Profilfoto signed by Lollyvector SVG15 paths~1.2k nodes30 groups1 image40 KBPrüfen Sie es selbstSignierte Datei holen

manifest.json

{
  "format": "lolly-backup",
  "formatVersion": 3,
  "minReader": 1,
  "app": "lolly",
  "exportedAt": "2026-06-22T09:30:00.000Z",
  "counts": { "profile": true, "sessions": 2, "userAssets": 4, "prefs": 3, "assetVersions": 1, "fileOperations": 1 },
  "integrity": {
    "profile.json": "sha256-…",
    "sessions.json": "sha256-…",
    "assets.json": "sha256-…",
    "assets/blobs/0.bin": "sha256-…",
    "file-history.json": "sha256-…",
    "file-history/versions/0.bin": "sha256-…",
    "file-history/results/0.bin": "sha256-…",
    "prefs.json": "sha256-…"
  }
}
FeldBedeutung
formatImmer lolly-backup. Eine Datei ohne dieses Feld wird als "kein Lolly-Backup" abgelehnt.
formatVersionDas Layout, mit dem dieses Bundle geschrieben wurde. Wird bei jeder Änderung an den Teilen oder ihrer Form erhöht. Reader prüfen dieses Feld nicht.
minReaderDie Mindest-Reader-Version, die zum sicheren Import dieses Bundles nötig ist. Auf dieses Feld prüfen Reader.
appID der erzeugenden App, für Diagnosezwecke.
exportedAtISO-Zeitstempel der Bundle-Erstellung.
countsWas der Writer eingefügt hat, zur Anzeige und Plausibilitätsprüfung.
integrityOptional. Ordnet jedem Teil außer manifest.json einen SRI-artigen sha256-<base64>-Digest seiner unkomprimierten Bytes zu.

Versionsrichtlinie (Abwärtskompatibilität)

Die Trennung von formatVersion und minReader ermöglicht es, das Format weiterzuentwickeln, ohne ältere Installationen auszuschließen:

Faustregel für Autoren: Wenn jeder bestehende Reader durch das Ignorieren Ihrer Ergänzung weiterhin korrekt funktionieren würde, ist sie additiv - formatVersion erhöhen, minReader unverändert lassen. Andernfalls minReader erhöhen.

Integrität

Ist manifest.integrity vorhanden, prüft ein Reader den SHA-256-Wert jedes gelisteten Teils bevor irgendetwas geschrieben wird. Eine Abweichung ("hat die Integritätsprüfung nicht bestanden") oder ein fehlender Teil ("unvollständig") bricht den gesamten Import ab - es gibt keine Teilwiederherstellung. Damit werden Beschädigungen erfasst, die ein Dateitransport verursachen kann (ein abgebrochenes AirDrop, ein E-Mail-Gateway, das den Anhang neu kodiert hat, ein defekter USB-Sektor).

Integrität ist bewusst als Best-Effort ausgelegt: Sie wird nur geschrieben, wo Web Crypto verfügbar ist (jeder sichere Browser-Kontext und modernes Node), und nur geprüft, wenn sowohl die Karte als auch Web Crypto vorhanden sind. Ein Bundle ohne Karte - zum Beispiel eines von vor Einführung der Integritätsprüfung - wird unverändert importiert. "Nicht prüfbar" wird niemals als "beschädigt" behandelt.

Das Manifest listet weder sich selbst noch die neu erzeugte lolly.txt-README. Die Digests decken die Teile ab, für die das Manifest bürgt.

Importsemantik

Der Import ist ein Merge, niemals ein Replace-all:

Gespeicherte Sitzungen verknüpfen sich automatisch neu mit ihren Bildern: Asset-Referenzen werden per ID gehalten, und die Bridge löst sie neu auf, nachdem die hochgeladenen Bilder wiederhergestellt wurden (das muss sie ohnehin, da blob:-URLs einen Reload nicht überstehen).

Die Importzusammenfassung meldet { profile, sessions, userAssets, prefs, skipped, failedAssets }. failedAssets zählt hochgeladene Assets, die nicht wiederhergestellt werden konnten (etwa weil der Gerätespeicher voll ist). Das unterscheidet sich von skipped, was Teile eines abwärtskompatiblen, neueren Writers zählt, die dieser Build nicht erkannt hat. Die Oberfläche zeigt skipped an ("… · N neuere Elemente übersprungen"), damit die Wiederherstellung ehrlich darüber Auskunft gibt, was sie zurückgelassen hat.

Ist ein Dateiverlauf vorhanden, trägt die Zusammenfassung außerdem assetVersions, fileOperations und failedHistory. Erschöpfter Speicherplatz oder Konflikte bei unveränderlichen IDs können eine teilweise Wiederherstellung verursachen; die Oberfläche weist den Nutzer an, die Quell-Sicherung zu behalten. Die Cloud-Synchronisierung rückt ihre angewendete Revision nach einer teilweisen oder nicht unterstützten Wiederherstellung nicht vor, sodass der Snapshot für einen erneuten Versuch verfügbar bleibt. Die Wiederherstellung ist keine einzelne Transaktion über alle Profil-/Sitzungs-/Asset-/Verlaufsspeicher hinweg.

Erstellungsverlauf (v3)

Manuelle Sicherungen von einem verlaufsfähigen Web-Host enthalten revision-history.json mit seinem eigenen Schema { version: 1, documents, revisions, recoveries }. Es trägt die aufbewahrten IDs, kanonische Eingabe-Snapshots, Versionsstempel, Raster-Vorschauen und separate Schreiber-Entwürfe. Der Verlaufs-Adapter erfasst aktuelle Sitzungen und ihre Köpfe in einer einzigen Lese-Transaktion; sessions.json verwendet für ältere Reader dieselben aktuellen Snapshots.

Die Wiederherstellung prüft SHA-256 und Byte-Anzahlen der Nutzlast, eindeutige Identitäten, Dokument-/Kopf-Beziehungen, Abstammung, Zeitstempel, Vorschautypen und Limits, bevor sie das Archiv in einer Transaktion übernimmt. Komprimierte Eltern-Referenzen können fehlen. Vorhandene aktuelle Arbeit wird nie stillschweigend ersetzt: Ist eine Kreation auf beiden Seiten vorhanden, wird die nicht als aktuell behaltene Seite zu einem geschützten Entwurf. Das 384-MiB-Übertragungslimit des Archivs wird ausdrücklich geprüft, und Speicherlimits werden durchgesetzt, ohne aufbewahrte Checkpoints abzuschneiden. Die Gesamt-Sicherung verwendet weiterhin eine In-Memory-ZIP-Implementierung und ist kein Streaming-Archiv.

Die Zusammenfassung ergänzt revisions und recoveryDrafts, die nur zählen, was dieser Import hinzugefügt hat, sowie added, kept, replaced, copies und hidden dafür, wie jede Kreation zusammengeführt wurde. Eine Shell ohne diese Fähigkeit stellt gewöhnliche Sitzungen wieder her und meldet den Verlaufsteil als übersprungen. Der native Dateisystem-Verlauf bleibt nicht unterstützt, bis sein Adapter dauerhafte Verlaufs-Transaktionen liefert. Der P2P-Gastzustand hat weder dauerhaften Verlauf noch ein Wiederherstellungsarchiv.

Die persönliche Snapshot-Synchronisierung schließt den Erstellungsverlauf ausdrücklich aus. Das Anwenden eines Snapshots auf ein lokales Dokument mit Verlauf bewahrt dessen vorherigen Arbeitszustand als separaten Wiederherstellungs-Entwurf und macht das Schreib-Token jedes offenen Editors ungültig. Seine unveränderlichen Checkpoints bleiben auf dem Gerät. Dies schützt den lokalen Verlauf während des Snapshot-Austauschs; es führt keine gleichzeitigen Geräteverläufe zusammen.

Historische Asset-Referenzen bleiben erhalten, während das Rendering Assets weiterhin über die vorhandene Bibliothek des Ziels auflöst. Dieses Archiv garantiert noch nicht die exakten alten Asset-Bytes oder alte Tool-Renderings. Asset-Versions- und Dateiergebnis-Bytes reisen weiterhin über ihren bestehenden separaten Backup-Teil.

Gespeicherte Versionen und Dateiergebnisse (v2)

Der optionale Verlaufsteil enthält { version: 2, assetVersions: [...], operations: [...], batches: [...] }; Reader akzeptieren auch die frühere History-v1-Form ohne Batches. Jeder Snapshot benennt die stabile Asset-ID und die exakte Version, seinen Speicherzeitpunkt, die Byte-Länge und den hexadezimalen SHA-256, plus einen Asset-Datensatz, dessen _file und optionales _credentialFile auf Binärteile verweisen. Operationen tragen die ursprünglichen Datei-Fakten, die Anfrage, den Bericht, Zeitstempel und ein optionales Ergebnis-_file; Namen des Speicher-Backends, OPFS-Handles und Ausführungs-Leases reisen nicht mit. Ältere, nur History-v1-fähige Reader lehnen die neue Verlaufsversion vor dem Import ab, statt die Batch-Zugehörigkeit stillschweigend zu verwerfen.

Batch-Manifeste erfassen jede ausgewählte Quelle vor der Verarbeitung, einschließlich nie gelesener Dateien, abgebrochener Mitglieder, gescheiterter Reservierungen von Ergebnisplatz und unterbrochener Arbeit. Jedes Mitglied hat eine stabile Operations-ID, eine Quellreferenz/-Fakten, den angeforderten Ausgabenamen und einen abschließenden Bericht. Eine ungelesene Quelle hat deklarierte Fakten, keinen erfundenen Digest. Der Import prüft die Mitglieds-Identität und die Konsistenz mit einem mitgeführten Operationsbericht. Batch-Berichte bleiben verfügbar, wenn einzelne Ergebnisse ausdrücklich entfernt wurden, aber ein Beleg bedeutet nicht, dass seine Ausgabe-Bytes noch gespeichert sind.

Ältere Reader akzeptieren weiterhin den v2-Umschlag (minReader: 1) und stellen vertraute Teile wieder her, wobei nicht unterstützte Verlaufsteile als übersprungen gezählt werden. Eine vollständige Verlaufs-Wiederherstellung erfordert eine Shell mit dem fileHistory-Adapter; dies ist eine shell-interne Nahtstelle, keine neue toolseitige HostV1-Fähigkeit. Eine echte Zwei-Geräte-Wiederherstellung wird durch das lokale Chromium-Gate abgedeckt; die Abnahme der Wiederherstellung auf installierten Tauri-/iOS-/Android-Apps bleibt gesondert.

Was nicht mitreist

Der Speicherzähler gliedert dieselbe Aufteilung auf. Gespeicherte Sitzungen, Meine Bilder und Dateiergebnisse & Versionen reisen in einem Bundle mit. Der Asset-Cache, Tool-Vorschauen und Offline-Pins darunter sind alle neu ableitbar und bleiben daher zurück.

Der Speicherzähler, der die Daten dieses Geräts in benannte Kategorien unterteilt, wobei Gespeicherte Sitzungen und Meine Bilder getrennt vom Asset-Cache erfasst werden, hier auf einer frischen Installation, in der jede Kategorie noch leer ist signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBPrüfen Sie es selbstSignierte Datei holenDer Speicherzähler, der die Daten dieses Geräts in benannte Kategorien unterteilt, wobei Gespeicherte Sitzungen und Meine Bilder getrennt vom Asset-Cache erfasst werden, hier auf einer frischen Installation, in der jede Kategorie noch leer ist signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBPrüfen Sie es selbstSignierte Datei holen

Shell-übergreifende Garantie

data-transfer.ts liest und schreibt ausschließlich über die Capability-Bridge (host.profile, host.state, host.assets) und die gemeinsamen localStorage-Einstellungen. Dasselbe Modul liest und schreibt den gemeinsamen Umschlag auf Web und Tauri, über IndexedDB- oder Dateisystem-Speicher. Optionale Verlaufsteile erscheinen nur dort, wo der entsprechende Adapter verfügbar ist; ein nicht unterstützter Teil wird beim Import als übersprungen gemeldet. Die Headless-Suite testet die gemeinsamen Teile gegen eine In-Memory-Bridge, während Verlaufs-Transaktionen zusätzlich echte Browser-Tests haben.

Zwei Shells stehen aus unterschiedlichen Gründen außerhalb dieser Garantie:

Reservierte Erweiterungspunkte

Der Umschlag ist absichtlich ein Manifest plus eine Menge benannter Teile, damit neue Arten portabler Daten später ohne inkompatible Änderung darin Platz finden. Sie fügen sich als additive Teile ein (neue formatVersion, gleiche minReader), und der heutige Reader überspringt, was er nicht erkennt. Diese sind noch nicht gebaut. Die Namen sind hier reserviert, damit das Format kohärent bleibt, wenn sie eintreffen.

Alles außerhalb dieser reservierten Namen und der oben genannten Teile ist für einen Reader ein unbekannter Teil: wird unangetastet gelassen und in skipped mitgezählt.

Referenz