Lolly
Öppna appen

Dataöverföring - paketet lolly-backup

Allt en Lolly-användare samlar på sig finns på deras enhet - inget konto, inget moln. Dataöverföringspaketet är hur det värdet flyttas: exportera det från en installation, ta med filen på valfritt sätt (USB, AirDrop, e-post till dig själv, en nätverksdelning) och importera den på en annan. Filen är transporten. Målet kan vara offline eller online. Det spelar ingen roll, eftersom inget någonsin pratar med en server.

De två knapparna som flyttar en hel installation: Exportera mina data skriver en zip, Importera data läser in den igen signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBKontrollera självHämta den signerade filenDe två knapparna som flyttar en hel installation: Exportera mina data skriver en zip, Importera data läser in den igen signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBKontrollera självHämta den signerade filen

Den här sidan är formatspecifikationen. För slutanvändargenomgången, se Hitta och återfå ditt arbete → Flytta ditt arbete till en annan enhet. Implementationen är shells/web/src/data-transfer.ts, och tests/data-transfer.test.ts fastställer kontraktet för tur-och-retur.

Omfattning. Ett paket bär användardata, inte katalogverktyg. Katalogverktyg och katalogtillgångar synkas separat och antas redan finnas på målet (i värsta fall i en högre version); verktyg en användare själv har gjort följer med inuti profile.json. Import installerar eller uppgraderar aldrig ett katalogverktyg.

Mål

Kuvertet

Ett paket är en vanlig .zip. Nedladdningen namnges efter personen den tillhör - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (till exempel LollyTools-Ada-Lovelace-2026-06-26-1.zip) - så att en Downloads-mapp full av säkerhetskopior förblir läsbar. Förnamns- och efternamnsdelarna kommer från profilen och utelämnas om de inte är ifyllda. Ingen profil ger LollyTools-2026-06-26-1.zip, och enbart förnamn ger LollyTools-Ada-2026-06-26-1.zip. Varje del saneras till en filnamnssäker token (Unicode-bokstäver/siffror behålls, mellanslag/skiljetecken tas bort, begränsat till 32 tecken). <n> är en sekvens per dag och enhet, så upprepade exporter samma dag inte krockar och förblir i ordning. backupFilename() i shells/web/src/data-transfer.ts bygger namnet. Zip-innehållet är identiskt oavsett namn. Innehåll:

SökvägKrävsInnehåll
manifest.jsonjaFormat-id, versioner, antal och integritet per del. Det första en läsare tittar på.
profile.jsonnär ifylldAnvändarens hela me-post: namn, kontaktuppgifter, referens till profilbild och flaggor, plus mappar, Papperskorg, projektmallar, användarmallar och användargjorda verktyg, favoriter, dolda verktyg, språk- och emoji-val. Läses via host.profile.
sessions.jsonjaVarje sparad session: plats, verktygs-id/version, etikett, miniatyrbild (data-URL) och all indata. Läses via host.state.
assets.jsonjaMetadata för varje uppladdad tillgång (bilder, typsnitt, varumärkestoken, logotyper, sparade kopior av nedladdningar), var och en pekande på sina byte under assets/blobs/.
assets/blobs/<n>.<ext>per tillgångDe råa byten för tillgången (bild- och typsnittsfiler). Lagras okomprimerat (redan komprimerade format). Filändelsen är kosmetisk. MIME-typen i assets.json är auktoritativ.
assets/blobs/<n>.c2panär närvarandeExtraherade Content Credentials som exakta binära byte, refererade av _credentialFile i tillgångsposten. Dessa är inte enhetens signeringsnycklar.
design-systems.jsonnär närvarandeDesignsystemen som skapats eller lagts till på den här installationen, som { active, records }. Slås samman efter id vid import; paketets aktiva val gäller bara när målet inte har något eget designsystem.
file-history.jsonvalfriVersionerade tillgångsögonblicksbilder, terminalens filoperationsrapporter och kompletta batch-manifest. Historikdelen har sin egen version; tillhandahålls av skalets interna säkerhetskopieringsadapter fileHistory.
revision-history.jsonvalfri, manuella säkerhetskopiorStabila skapelse-ID:n, bevarade checkpoints, miniatyrer och löpande återställningsutkast. Tillhandahålls av host.state.history.backup där det stöds.
file-history/versions/per ögonblicksbildTidigare tillgångsbyte och extraherade credentials, oberoende av om den aktuella tillgången fortfarande finns.
file-history/results/per avslutad operationExakta utdatabyte. Ingen ursprunglig fil vald för konvertering behålls eller inkluderas.
prefs.jsonjaAnvändarägda lokala inställningar: theme, sidebarWidth och aktivitetsräknaren ct-metrics.
lolly.txtjaEn människoläsbar sammanfattning av paketet (antal, profil, filnamn) för den som öppnar zip:en utan Lolly. Genereras på nytt vid varje export och känns igen vid import, så den räknas aldrig som en överhoppad del. Den skrivs efter integritetskartan, så den ligger utanför den.

Paketet är avsiktligt en vanlig zip: det överlever alla transporter intakt, och vilket uppackningsverktyg som helst kan inspektera det.

profile.json är den minsta delen och den en läsare ser först i appen: uppgifterna som en producent fyller i en gång, plus samtycket som låter verktyg använda dem.

Formuläret med profildetaljer som blir profile.json: namn, kontaktuppgifter och profilbild signed by Lollyvector SVG15 paths~1.2k nodes30 groups1 image40 KBKontrollera självHämta den signerade filen

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-…"
  }
}
FältBetydelse
formatAlltid lolly-backup. En fil utan det avvisas som "not a Lolly backup".
formatVersionLayouten det här paketet skrevs med. Höjs vid varje ändring av uppsättningen delar eller deras form. Läsare styr inte på den.
minReaderDen lägsta läsarversion som krävs för att importera det här paketet säkert. Det är det här fältet läsare styr på.
appId för den app som skapade paketet, för diagnostik.
exportedAtISO-tidsstämpel för när paketet skapades.
countsVad skribenten lade in, för visning och rimlighetskontroll.
integrityValfritt. Kopplar varje del utom manifest.json till ett SRI-liknande sha256-<base64>-hashvärde för dess okomprimerade byte.

Versionspolicy (framåtkompatibilitet)

Uppdelningen mellan formatVersion och minReader är det som låter formatet växa utan att göra äldre installationer föräldralösa:

Tumregel för upphovspersoner: om varje befintlig läsare fortfarande skulle göra rätt genom att ignorera ditt tillägg, är det additivt - höj formatVersion, lämna minReader. Annars höj minReader.

Integritet

När manifest.integrity finns verifierar en läsare SHA-256 för varje listad del innan något skrivs. En avvikelse ("failed its integrity check") eller en saknad del ("incomplete") avbryter hela importen - det finns ingen delvis återställning. Det här fångar den skada en filtransport kan orsaka (en trunkerad AirDrop, en e-postgateway som kodat om bilagan, en dålig USB-sektor).

Integritet är avsiktligt best-effort: den skrivs bara där Web Crypto finns tillgängligt (varje säker webbläsarkontext och modern Node), och verifieras bara när både kartan och Web Crypto finns. Ett paket utan kartan - till exempel ett från innan integritet fanns - importeras oförändrat. "Cannot verify" behandlas aldrig som "corrupt".

Manifestet listar varken sig självt eller den återgenererade lolly.txt-README:n. Hashvärdena täcker de delar manifestet intygar för.

Importsemantik

Import är en sammanslagning, aldrig ersätt-allt:

Sparade sessioner länkas automatiskt om till sina bilder: tillgångsreferenser bevaras via id, och bryggan löser upp dem på nytt efter att de uppladdade bilderna återställts (det måste den ändå göra, eftersom blob:-URL:er inte överlever en omladdning).

Importsammanfattningen rapporterar { profile, sessions, userAssets, prefs, skipped, failedAssets }. failedAssets räknar uppladdade tillgångar som inte kunde återställas (till exempel fullt enhetslagringsutrymme). Det skiljer sig från skipped, som räknar delar från en framåtkompatibel nyare skribent som den här versionen inte kände igen. Gränssnittet visar skipped ("… · N newer items skipped"), så återställningen är ärlig om vad den lämnade kvar.

När filhistorik finns med bär sammanfattningen också assetVersions, fileOperations och failedHistory. Uttömd lagring eller oföränderliga ID-konflikter kan orsaka en delvis återställning; gränssnittet ber användaren behålla källsäkerhetskopian. Molnsynk flyttar inte fram sin tillämpade revision efter en delvis eller ostödd återställning, så ögonblicksbilden förblir tillgänglig för ett nytt försök. Återställning är inte en enda transaktion över alla profil-/sessions-/tillgångs-/historiklager.

Skapelsehistorik (v3)

Manuella säkerhetskopior från en historikkapabel webbvärd inkluderar revision-history.json med sitt eget schema { version: 1, documents, revisions, recoveries }. Den bär de bevarade ID:na, kanoniska indataögonblicksbilder, versionsstämplar, rasterförhandsvisningar och separata skrivarutkast. Historikadaptern fångar aktuella sessioner och deras huvuden i en enda läs-transaktion; sessions.json använder samma aktuella ögonblicksbilder för äldre läsare.

Återställning kontrollerar nyttolastens SHA-256 och bytantal, unika identiteter, dokument-/huvud-relationer, härkomst, tidsstämplar, förhandsvisningstyper och gränser innan arkivet checkas in i en enda transaktion. Komprimerade föräldrareferenser kan saknas. Befintligt aktuellt arbete ersätts aldrig i tysthet: när en skapelse finns på båda sidor blir sidan som inte hålls aktuell ett skyddat utkast. Arkivets överföringsgräns på 384 MiB kontrolleras explicit, och lagringsgränser upprätthålls utan att trunkera bevarade checkpoints. Hela säkerhetskopian använder fortfarande en in-memory ZIP-implementation och är inte ett strömmande arkiv.

Sammanfattningen lägger till revisions och recoveryDrafts, som bara räknar det den här importen lade till, samt added, kept, replaced, copies och hidden för hur varje skapelse slogs samman. Ett skal utan den här förmågan återställer vanliga sessioner och rapporterar historikdelen som överhoppad. Historik för det inbyggda filsystemet förblir ostödd tills dess adapter tillhandahåller varaktiga historiktransaktioner. P2P-gästtillstånd har ingen varaktig historik eller något återställningsarkiv.

Personlig ögonblicksbildsynk utesluter uttryckligen skapelsehistorik. Att tillämpa en ögonblicksbild på ett lokalt dokument med historik bevarar dess tidigare arbetstillstånd som ett separat återställningsutkast och ogiltigförklarar en öppen redigerares skrivtoken. Dess oföränderliga checkpoints finns kvar på enheten. Det här skyddar lokal historik under utbyte av ögonblicksbild; det slår inte ihop samtidiga enheters historik.

Historiska tillgångsreferenser bevaras, medan rendering fortfarande löser upp tillgångar via målets befintliga bibliotek. Det här arkivet garanterar ännu inte exakta gamla tillgångsbyte eller gamla verktygsrenderingar. Byte för tillgångsversioner och filresultat fortsätter att följa med via sin befintliga separata säkerhetskopieringsdel.

Sparade versioner och filresultat (v2)

Den valfria historikdelen innehåller { version: 2, assetVersions: [...], operations: [...], batches: [...] }; läsare accepterar också den tidigare formen history-v1 utan batchar. Varje ögonblicksbild identifierar det stabila tillgångs-ID:t och den exakta versionen, dess sparandetid, bytlängd och hex-SHA-256, plus en tillgångspost vars _file och valfria _credentialFile pekar på binära delar. Operationer bär de ursprungliga filfakta, förfrågan, rapporten, tidsstämplar och en valfri resultat-_file; namn på lagringsbackend, OPFS-handtag och körningsleasar följer inte med. Äldre läsare som bara känner till history-v1 avvisar den nya historikversionen innan import, i stället för att tyst tappa batchmedlemskap.

Batch-manifest registrerar varje vald källa innan bearbetning, inklusive filer som aldrig lästs, avbrutna medlemmar, misslyckanden att reservera resultatutrymme och avbrutet arbete. Varje medlem har ett stabilt operations-ID, källreferens/-fakta, begärt utdatanamn och terminalrapport. En oläst källa har deklarerade fakta, inte en påhittad digest. Import validerar medlemsidentitet och konsistens mot en eventuell medföljande operationsrapport. Batch-rapporter förblir tillgängliga när enskilda resultat uttryckligen har tagits bort, men ett kvitto innebär inte att dess utdatabyte fortfarande är sparade.

Äldre läsare accepterar fortfarande v2-kuvertet (minReader: 1) och återställer bekanta delar, och räknar historikdelar som inte stöds som överhoppade. Fullständig historikåterställning kräver ett skal med adaptern fileHistory; det här är en skalintern skarv, inte en ny verktygsvänd HostV1-förmåga. Verklig återställning mellan två enheter täcks av den lokala Chromium-grinden; godkännande av återställning i installerade Tauri-/iOS-/Android-appar förblir separat.

Vad som inte följer med

Lagringsmätaren specificerar samma uppdelning. Saved sessions, My images och File results & versions följer med i ett paket. Tillgångscachen, verktygsförhandsvisningarna och offlinefästningarna under dem kan alla härledas på nytt, så de stannar kvar.

Lagringsmätaren som delar upp den här enhetens data i namngivna kategorier, med Saved sessions och My images spårade separat från Asset cache, här på en ny installation där varje kategori fortfarande är tom signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBKontrollera självHämta den signerade filenLagringsmätaren som delar upp den här enhetens data i namngivna kategorier, med Saved sessions och My images spårade separat från Asset cache, här på en ny installation där varje kategori fortfarande är tom signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBKontrollera självHämta den signerade filen

Garanti mellan skal

data-transfer.ts läser och skriver uteslutande via kapabilitetsbryggan (host.profile, host.state, host.assets) och de delade localStorage-inställningarna. Samma modul läser och skriver det gemensamma kuvertet på webben och Tauri, via IndexedDB eller filsystemlagring. Valfria historikdelar visas bara där motsvarande adapter finns tillgänglig; en del som inte stöds rapporteras som överhoppad vid import. Den huvudlösa testsviten kör de gemensamma delarna mot en in-memory-brygga, medan historiktransaktioner också har tester i en riktig webbläsare.

Två skal står utanför den garantin, av olika skäl:

Reserverade utökningspunkter

Kuvertet är ett manifest plus en uppsättning namngivna delar med avsikt, så att nya typer av portabel data kan ansluta senare utan en brytande ändring. De läggs till som additiva delar (ny formatVersion, samma minReader), och dagens läsare hoppar över det den inte känner igen. Dessa är inte byggda än. Namnen är reserverade här så att formatet förblir sammanhängande när de väl landar.

Allt utanför dessa reserverade namn och delarna ovan är, för en läsare, en okänd del: lämnas orörd och räknas i skipped.

Referens