Data Transfer - ang lolly-backup bundle

Ang lahat ng naiipon ng isang user ng Lolly ay nasa kanilang device - walang account, walang cloud. Ang data-transfer bundle ang paraan para ilipat ang halagang iyon: i-export ito sa isang install, dalhin ang file sa anumang paraan (USB, AirDrop, email-to-self, isang network share) at i-import ito sa isa pa. Ang file mismo ang transport. Maaaring offline o online ang target. Walang pagkakaiba, dahil walang kailanman nakikipag-usap sa isang server.

Ang dalawang button na naglilipat ng buong install: isinusulat ng Export my data ang isang zip, binabasa ito pabalik ng Import datasigned by Lollyvector SVGI-check mo mismoGet the signed file12 paths~5.1k nodes12 groups60 KBAng dalawang button na naglilipat ng buong install: isinusulat ng Export my data ang isang zip, binabasa ito pabalik ng Import datasigned by Lollyvector SVGI-check mo mismoGet the signed file12 paths~5.1k nodes12 groups60 KB

Ang pahinang ito ang format spec. Para sa end-user na walkthrough, tingnan ang Using Lolly → Moving to another device. Ang implementation ay nasa shells/web/src/data-transfer.ts, at itinatakda ng tests/data-transfer.test.ts ang round-trip contract.

Saklaw. Ang isang bundle ay may dalang user data, hindi mga tool. Ang mga tool at catalog asset ay naka-sync nang hiwalay at ipinapalagay na naroroon na sa target (sa pinakamasamang kaso ay sa mas mataas na bersyon). Ang pag-import ay hindi kailanman nag-i-install o nag-a-upgrade ng isang tool.

Mga Layunin

Ang Envelope

Ang isang bundle ay isang plain na .zip. Ipinapangalan ang download ayon sa taong pagmamay-ari nito - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (halimbawa, LollyTools-Ada-Lovelace-2026-06-26-1.zip) - para manatiling nababasa ang isang Downloads folder ng mga backup. Ang unang pangalan at apelyido ay galing sa profile at inaalis kapag hindi nakatakda. Kung walang profile, LollyTools-2026-06-26-1.zip ang resulta, at kung unang pangalan lang, LollyTools-Ada-2026-06-26-1.zip. Bawat bahagi ay nili-linis tungo sa isang filename-safe na token (napapanatili ang mga Unicode letra/digit, tinatanggal ang mga espasyo/bantas, may hangganang 32 character). Ang <n> ay isang sequence kada araw, kada device, kaya hindi nagbabanggaan at nananatiling maayos ang pagkakasunod-sunod ng mga paulit-ulit na export sa parehong araw. Binubuo ng backupFilename() sa shells/web/src/data-transfer.ts ang pangalan. Magkapareho ang laman ng zip anuman ang pangalan. Sa loob:

PathKinakailanganLaman
manifest.jsonooFormat id, mga bersyon, mga bilang at per-part integrity. Ang unang tinitingnan ng isang reader.
profile.jsonkapag naka-setAng me record ng user (pangalan, contact, headshot ref, flags). Binabasa sa pamamagitan ng host.profile.
sessions.jsonooBawat naka-save na session: slot, tool id/version, label, thumbnail (data-URL) at buong input data. Binabasa sa pamamagitan ng host.state.
assets.jsonooMetadata para sa bawat na-upload na asset (mga imahe, font, brand token), bawat isa ay tumuturo sa mga byte nito sa ilalim ng assets/blobs/.
assets/blobs/<n>.<ext>per assetAng raw na byte ng asset (mga image at font file). Naka-store nang uncompressed (mga format na naka-compress na). Cosmetic lang ang extension. Ang MIME sa assets.json ang authoritative.
prefs.jsonooMga lokal na preference na pag-aari ng user: theme, sidebarWidth at ang activity tally na ct-metrics.
lolly.txtooIsang human-readable na buod ng bundle (mga bilang, profile, filename) para sa sinumang magbubukas ng zip nang wala ang Lolly. Nabubuo muli sa bawat export at kinikilala sa pag-import, kaya hindi ito kailanman nabibilang bilang isang skipped na bahagi. Isinusulat ito pagkatapos ng integrity map, kaya nananatili itong nasa labas nito.

Sadyang isang plain zip ang bundle: nakakaligtas itong buo sa anumang transport, at maaari itong tingnan ng anumang unzip tool.

Ang profile.json ang pinakamaliit na bahagi at ang unang nakikita ng isang reader sa app: ang mga detalyeng pinupunan ng isang producer nang isang beses, kasama ang opt-in na nagpapahintulot sa mga tool na gamitin ang mga ito.

Ang Profile details form na nagiging profile.json - pangalan, contact, headshot at ang opt-in sa tabi nilasigned by Lollyvector SVGI-check mo mismoGet the signed file18 paths~2.0k nodes41 groups30 KBAng Profile details form na nagiging profile.json - pangalan, contact, headshot at ang opt-in sa tabi nilasigned by Lollyvector SVGI-check mo mismoGet 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-…"
  }
}
FieldKahulugan
formatPalaging lolly-backup. Tinatanggihan ang isang file na wala nito bilang "not a Lolly backup".
formatVersionAng layout na ginamit sa pagsulat ng bundle na ito. Tumataas sa anumang pagbabago sa set o hugis ng mga bahagi. Hindi ito ginagawang batayan ng mga reader.
minReaderAng minimum na bersyon ng reader na kailangan para i-import nang ligtas ang bundle na ito. Ito ang field na ginagawang batayan ng mga reader.
appId ng app na gumawa nito, para sa diagnostics.
exportedAtISO timestamp kung kailan ginawa ang bundle.
countsAng inilagay ng writer, para sa display at sanity-checking.
integrityOpsyonal. Nagmamapa ng bawat bahagi maliban sa manifest.json sa isang SRI-style na sha256-<base64> digest ng mga uncompressed na byte nito.

Patakaran sa Bersyon (forward compatibility)

Ang paghahati sa pagitan ng formatVersion at minReader ang nagpapahintulot sa format na lumago nang hindi iniiwan ang mga mas lumang install:

Simpleng patnubay para sa mga may-akda: kung gagawin pa rin ng bawat umiiral na reader ang tamang bagay sa pamamagitan ng pagbalewala sa dinagdag mo, additive ito - itaas ang formatVersion, iwanan ang minReader. Kung hindi, itaas ang minReader.

Integridad

Kapag naroroon ang manifest.integrity, vine-verify ng isang reader ang SHA-256 ng bawat nakalistang bahagi bago magsulat ng anuman. Ang isang mismatch ("failed its integrity check") o isang nawawalang bahagi ("incomplete") ay nag-a-abort sa buong import - walang partial restore. Nahuhuli nito ang katiwalian na maaaring idulot ng isang file transport (isang na-truncate na AirDrop, isang email gateway na nag-re-encode ng attachment, isang masamang USB sector).

Sadyang best-effort ang integrity: isinusulat lang ito kung saan available ang Web Crypto (bawat secure browser context at modernong Node), at vine-verify lang kapag naroroon ang parehong map at Web Crypto. Ang isang bundle na walang map - halimbawa, isa mula sa panahon bago pa magkaroon ng integrity - ay nag-i-import nang hindi nagbabago. Ang "cannot verify" ay hindi kailanman itinuturing na "corrupt".

Hindi nakalista sa manifest ang sarili nito o ang nabuong muli na lolly.txt README. Sinasaklaw ng mga digest ang mga bahaging binabatikos ng manifest.

Semantika ng Pag-import

Ang pag-import ay merge-overwrite, hindi kailanman replace-all:

Awtomatikong nagre-relink ang mga naka-save na session sa kanilang mga imahe: pinapanatili ang mga asset reference ayon sa id, at nire-resolve muli ang mga ito ng bridge matapos maibalik ang mga na-upload na imahe (kailangan itong gawin sa anumang paraan, dahil hindi nakakaligtas ang mga blob: URL sa isang reload).

Ang import summary ay nagre-report ng { profile, sessions, userAssets, prefs, skipped, failedAssets }. Binibilang ng failedAssets ang mga na-upload na asset na hindi naibalik (halimbawa, puno ang device storage). Iba ito sa skipped, na bumibilang ng mga bahagi mula sa isang forward-compatible na mas bagong writer na hindi kinilala ng build na ito. Ipinapakita ng UI ang skipped ("… · N newer items skipped"), kaya matapat ang restore tungkol sa naiwan nito.

Ang Hindi Naglalakbay

Inilalarawan ng storage meter ang parehong paghahati. Sumasama sa bundle ang Saved sessions at My images. Ang asset cache, tool preview at offline pin sa ibaba ng mga ito ay lahat re-derivable, kaya naiiwan sila.

Hinahati ng storage meter ang datos ng device na ito sa mga pinangalanang kategorya, kasama ang Saved sessions at My images na sinusubaybayan nang hiwalay sa Asset cache, dito sa isang fresh install kung saan walang laman pa ang bawat kategoryasigned by Lollyvector SVGI-check mo mismoGet the signed file25 paths~4.8k nodes46 groups59 KBHinahati ng storage meter ang datos ng device na ito sa mga pinangalanang kategorya, kasama ang Saved sessions at My images na sinusubaybayan nang hiwalay sa Asset cache, dito sa isang fresh install kung saan walang laman pa ang bawat kategoryasigned by Lollyvector SVGI-check mo mismoGet the signed file25 paths~4.8k nodes46 groups59 KB

Garantiya sa Cross-shell

Ang data-transfer.ts ay nagbabasa at nagsusulat eksklusibo sa pamamagitan ng capability bridge (host.profile, host.state, host.assets) at ng shared na localStorage prefs. Dahil ang bridge lang ang tanging seam, ang parehong module ay gumagawa ng byte-identical bundle sa bawat shell kahit magkaiba ang storage sa ilalim nito - IndexedDB sa web, ang filesystem sa Tauri. Ginagamit ulit ng mga Tauri shell ang module na ito nang walang pagbabago. Ang implementation lang ng host.state nila ang naiiba. Sinusubok ng headless test ang buong round-trip laban sa isang in-memory bridge, kaya ito ang katayuan para sa lahat ng iba pa.

May dalawang shell na wala sa guarantee na iyon, sa magkaibang dahilan:

Nakalaang extension points

Ang envelope ay isang manifest kasama ang isang set ng named parts sa disenyo, kaya ang mga bagong uri ng portable data ay maaaring sumakay dito sa hinaharap nang walang breaking change. Sumasakay sila bilang additive parts (bagong formatVersion, parehong minReader), at ang reader ngayon ay lumalampas sa hindi nito nakikilala. Ang mga ito ay nasa roadmap, hindi pa ipinapatupad. Nakalaan dito ang mga pangalan para manatiling coherent ang format kapag dumating na sila.

Anumang wala sa mga nakalaang pangalang ito at sa mga parts sa itaas ay, sa paningin ng reader, isang unknown part: hindi nagagalaw at binibilang sa skipped.

Reference