Dataoverføring - lolly-backup-pakken

Alt en Lolly-bruker samler seg opp, lever på enheten deres - ingen konto, ingen sky. Dataoverføringspakken er hvordan den verdien flytter seg: eksporter den på én installasjon, bær filen på hvilken som helst måte (USB, AirDrop, e-post til deg selv, en nettverksdeling) og importer den på en annen. Filen er transporten. Målet kan være offline eller online. Det spiller ingen rolle, fordi ingenting noensinne snakker med en server.

De to knappene som flytter en hel installasjon: Eksporter dataene mine skriver én zip, Importer data leser den tilbakesigned by Lollyvector SVGSjekk det selvGet the signed file12 paths~5.1k nodes12 groups60 KBDe to knappene som flytter en hel installasjon: Eksporter dataene mine skriver én zip, Importer data leser den tilbakesigned by Lollyvector SVGSjekk det selvGet the signed file12 paths~5.1k nodes12 groups60 KB

Denne siden er formatspesifikasjonen. For sluttbrukergjennomgangen, se Using Lolly → Moving to another device. Implementasjonen er shells/web/src/data-transfer.ts, og tests/data-transfer.test.ts fastlåser tur-retur-kontrakten.

Omfang. En pakke bærer brukerdata, ikke verktøy. Verktøy og katalogressurser synkroniseres separat og antas allerede å være til stede på målet (i verste fall i en høyere versjon). Import installerer eller oppgraderer aldri et verktøy.

Mål

Konvolutten

En pakke er en vanlig .zip. Nedlastingen navngis etter personen den tilhører - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (for eksempel LollyTools-Ada-Lovelace-2026-06-26-1.zip) - slik at en Nedlastinger-mappe full av sikkerhetskopier holder seg lesbar. Fornavn- og etternavndelene kommer fra profilen og utelates når de ikke er angitt. Uten profil blir det LollyTools-2026-06-26-1.zip, og et fornavn alene gir LollyTools-Ada-2026-06-26-1.zip. Hver del saneres til et filnavn-sikkert token (Unicode-bokstaver/-tall beholdes, mellomrom/tegnsetting fjernes, maks 32 tegn). <n> er et sekvensnummer per dag per enhet, slik at gjentatte eksporter samme dag ikke kolliderer og forblir i rekkefølge. backupFilename() i shells/web/src/data-transfer.ts bygger navnet. Zip-filens innhold er identisk uansett navn. Inni:

StiPåkrevdInnhold
manifest.jsonjaFormat-id, versjoner, antall og integritet per del. Det første en leser ser på.
profile.jsonnår sattBrukerens me-post (navn, kontakt, portrettbilde-referanse, flagg). Leses via host.profile.
sessions.jsonjaHver lagrede sesjon: plass, verktøy-id/versjon, etikett, miniatyrbilde (data-URL) og fullstendige inputdata. Leses via host.state.
assets.jsonjaMetadata for hver opplastet ressurs (bilder, fonter, merkevaretokener), hver med peker til bytene sine under assets/blobs/.
assets/blobs/<n>.<ext>per ressursDe rå ressursbytene (bilde- og fontfiler). Lagret ukomprimert (allerede komprimerte formater). Filendelsen er kosmetisk. MIME-typen i assets.json er autoritativ.
prefs.jsonjaBrukereide lokale innstillinger: theme, sidebarWidth og ct-metrics-aktivitetstellingen.
lolly.txtjaEt menneskelesbart sammendrag av pakken (antall, profil, filnavn) for alle som åpner zip-en uten Lolly. Regenereres ved hver eksport og gjenkjennes ved import, så den regnes aldri som en hoppet-over del. Den skrives etter integritetskartet, så den holdes utenfor det.

Pakken er en vanlig zip med hensikt: den overlever enhver transport intakt, og ethvert utpakkingsverktøy kan inspisere den.

profile.json er den minste delen og den en leser ser først i appen: detaljene en produsent fyller inn én gang, pluss opt-inen som lar verktøy bruke dem.

Profile details-skjemaet som blir profile.json - navn, kontakt, portrettbilde og opt-inen ved siden avsigned by Lollyvector SVGSjekk det selvGet the signed file18 paths~2.0k nodes41 groups30 KBProfile details-skjemaet som blir profile.json - navn, kontakt, portrettbilde og opt-inen ved siden avsigned by Lollyvector SVGSjekk det selvGet the signed file18 paths~2.0k nodes41 groups30 KB

manifest.json

{
  "format": "lolly-backup",
  "formatVersion": 1,
  "minReader": 1,
  "app": "lolly",
  "exportedAt": "2026-06-22T09:30:00.000Z",
  "counts": { "profile": true, "sessions": 2, "userAssets": 4, "prefs": 3 },
  "integrity": {
    "profile.json": "sha256-…",
    "sessions.json": "sha256-…",
    "assets.json": "sha256-…",
    "assets/blobs/0.webp": "sha256-…",
    "prefs.json": "sha256-…"
  }
}
FeltBetydning
formatAlltid lolly-backup. En fil uten det avvises som «not a Lolly backup».
formatVersionLayouten denne pakken ble skrevet med. Heves ved enhver endring av delsettet eller formene. Lesere sjekker ikke mot denne.
minReaderMinste leserversjon som kreves for å importere denne pakken trygt. Dette er feltet lesere sjekker mot.
appProduserende app-id, for diagnostikk.
exportedAtISO-tidsstempel for når pakken ble laget.
countsHva skriveren la inn, for visning og fornuftssjekk.
integrityValgfritt. Kobler hver del unntatt manifest.json til en SRI-lignende sha256-<base64>-digest av dens ukomprimerte bytes.

Versjonspolicy (fremoverkompatibilitet)

Delingen mellom formatVersion og minReader er det som lar formatet vokse uten å etterlate eldre installasjoner:

Tommelfingerregel for forfattere: hvis enhver eksisterende leser fortsatt ville gjort det riktige ved å ignorere tilføyelsen din, er den additiv - hev formatVersion, la minReader være. Ellers hev minReader.

Integritet

Når manifest.integrity er til stede, verifiserer en leser hver oppførte dels SHA-256 før noe skrives. Et avvik («failed its integrity check») eller en manglende del («incomplete») avbryter hele importen - det finnes ingen delvis gjenoppretting. Dette fanger opp korrupsjonen en filtransport kan innføre (en avkuttet AirDrop, en e-postgateway som har omkodet vedlegget, en dårlig USB-sektor).

Integritet er beste innsats med hensikt: den skrives kun der Web Crypto er tilgjengelig (enhver sikker nettleserkontekst og moderne Node), og verifiseres kun når både kartet og Web Crypto er til stede. En pakke uten kartet - for eksempel en fra før integritet fantes - importeres uendret. «Cannot verify» behandles aldri som «corrupt».

Manifestet lister verken seg selv eller den regenererte lolly.txt-README-en. Digestene dekker delene manifestet går god for.

Importsemantikk

Import er sammenslåing-med-overskriving, aldri erstatt-alt:

Lagrede sesjoner kobles automatisk sammen med bildene sine igjen: ressursreferanser holdes med id, og broen løser dem opp på nytt etter at de opplastede bildene er gjenopprettet (den må uansett det, fordi blob:-URL-er ikke overlever en omlasting).

Importsammendraget rapporterer { profile, sessions, userAssets, prefs, skipped, failedAssets }. failedAssets teller opplastede ressurser som ikke kunne gjenopprettes (enhetslagring full, for eksempel). Det er atskilt fra skipped, som teller deler fra en fremoverkompatibel nyere skriver som denne buildjen ikke gjenkjente. UI-en viser skipped («… · N newer items skipped»), så gjenopprettingen er ærlig om hva den lot ligge.

Hva som ikke følger med

Lagringsmåleren viser den samme oppdelingen kategori for kategori. Lagrede sesjoner og Mine bilder følger med i en pakke. Ressursbufferen, verktøyforhåndsvisningene og offline-pinnene under dem er alle avledbare på nytt, så de blir igjen.

Lagringsmåleren som deler denne enhetens data inn i navngitte kategorier, med Saved sessions og My images sporet separat fra Asset cache, her på en fersk installasjon der hver kategori fortsatt er tomsigned by Lollyvector SVGSjekk det selvGet the signed file25 paths~4.8k nodes46 groups59 KBLagringsmåleren som deler denne enhetens data inn i navngitte kategorier, med Saved sessions og My images sporet separat fra Asset cache, her på en fersk installasjon der hver kategori fortsatt er tomsigned by Lollyvector SVGSjekk det selvGet the signed file25 paths~4.8k nodes46 groups59 KB

Kryssgaranti mellom shells

data-transfer.ts leser og skriver utelukkende gjennom kapabilitetsbroen (host.profile, host.state, host.assets) og de delte localStorage-innstillingene. Fordi broen er den eneste skjøten, produserer den samme modulen et byte-identisk bundt på hvert shell selv om lagringen under er forskjellig - IndexedDB på web, filsystemet på Tauri. Tauri-shellene gjenbruker denne modulen uendret. Bare deres host.state-implementasjon er forskjellig. Den skjulte testen kjører hele rundturen mot en in-memory-bro, og det er derfor den representerer dem alle.

To shell befinner seg utenfor den garantien, av ulike grunner:

Reserverte utvidelsespunkter

Konvolutten er et manifest pluss et sett navngitte deler med hensikt, slik at nye typer portabel data kan følge med senere uten en brytende endring. De kobles inn som additive deler (ny formatVersion, samme minReader), og dagens leser hopper over det den ikke kjenner igjen. Disse er på veikartet, ikke implementert ennå. Navnene er reservert her slik at formatet forblir sammenhengende når de kommer.

Alt utenfor disse reserverte navnene og delene ovenfor er, for en leser, en ukjent del: uberørt og talt med i skipped.

Referanse