Lolly
Buksan ang App

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 data signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBI-check mo mismoKunin ang signed na fileAng dalawang button na naglilipat ng buong install: isinusulat ng Export my data ang isang zip, binabasa ito pabalik ng Import data signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBI-check mo mismoKunin ang signed na file

Ang pahinang ito ang format spec. Para sa end-user na walkthrough, tingnan ang Hanapin at bawiin ang gawa mo → Ilipat ang gawa mo sa ibang 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 catalogue tool. Ang mga catalogue 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 mga tool na ginawa mismo ng isang user ay naglalakbay sa loob ng profile.json. Ang pag-import ay hindi kailanman nag-i-install o nag-a-upgrade ng isang catalogue 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 buong me record ng user: pangalan, contact, headshot ref at flags, kasama ang mga folder, Trash, project blueprint, user template at mga tool na ginawa ng user, favourites, nakatagong tool, wika at pinili sa emoji. 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, logo, na-save na kopya ng mga download), 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.
assets/blobs/<n>.c2pakapag naroroonNakuhang Content Credentials bilang eksaktong binary bytes, tinutukoy ng _credentialFile sa asset record. Hindi ito mga signing key ng device.
design-systems.jsonkapag naroroonAng mga design system na ginawa o idinagdag sa install na ito, bilang { active, records }. Pinagsasama ayon sa id sa pag-import; ang aktibong pili ng bundle ay nalalapat lang kapag walang sariling design system ang target.
file-history.jsonopsyonalMga versioned na asset snapshot, mga terminal file-operation report at kumpletong batch manifest. May sariling bersyon ang history part; ibinibigay ng internal na fileHistory backup adapter ng shell.
revision-history.jsonopsyonal, manual na backupMatatag na creation ID, mga retained checkpoint, thumbnail at umiikot na recovery draft. Ibinibigay ng host.state.history.backup kung suportado.
file-history/versions/per snapshotMga nakaraang asset byte at nakuhang credentials, hindi nakadepende kung umiiral pa ang kasalukuyang asset.
file-history/results/per completed operationEksaktong output bytes. Walang orihinal na file na napili-para-i-convert ang iniingatan o kasama.
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 form ng mga detalye ng Profile na nagiging profile.json: pangalan, contact detail at larawan sa profile signed by Lollyvector SVG15 paths~1.2k nodes30 groups1 image40 KBI-check mo mismoKunin ang signed na file

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-…"
  }
}
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 import ay isang merge, 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.

Kapag naroroon ang file history, dala rin ng summary ang assetVersions, fileOperations at failedHistory. Puwedeng magdulot ng partial restore ang pagkaubos ng storage o mga hidwaan sa immutable ID; sinasabihan ng UI ang user na itago ang orihinal na backup. Hindi isinusulong ng cloud sync ang applied revision nito pagkatapos ng isang partial o hindi suportadong restore, kaya nananatiling available ang snapshot para sa muling pagsubok. Hindi iisang transaction sa lahat ng profile/session/asset/history store ang restore.

Kasaysayan ng creation (v3)

Kasama sa mga manual na backup mula sa isang history-capable na web host ang revision-history.json na may sariling { version: 1, documents, revisions, recoveries } na schema. Dala nito ang mga retained ID, canonical na input snapshot, version stamp, raster preview at hiwalay na writer draft. Kinukuha ng history adapter ang mga kasalukuyang session at ang mga head nito sa iisang read transaction; ginagamit ng sessions.json ang parehong kasalukuyang snapshot na iyon para sa mga mas lumang reader.

Sinusuri ng restore ang SHA-256 at bilang ng byte ng payload, natatanging identity, relasyon ng document/head, ancestry, timestamp, uri ng preview at mga limitasyon bago i-commit ang archive sa iisang transaction. Puwedeng wala ang mga na-compact na parent reference. Hindi kailanman tahimik na pinapalitan ang umiiral na kasalukuyang gawa: kapag nasa magkabilang panig ang isang creation, ang panig na hindi pinanatiling kasalukuyan ay nagiging protected draft. Sinusuri nang tahasan ang 384 MiB na transfer limit ng archive, at ipinapatupad ang mga storage limit nang hindi pinuputol ang mga retained checkpoint. Gumagamit pa rin ang kabuuang backup ng isang in-memory na ZIP implementation at hindi ito isang streaming archive.

Idinaragdag ng summary ang revisions at recoveryDrafts, na binibilang lang ang idinagdag ng import na ito, at ang added, kept, replaced, copies at hidden para sa kung paano pinagsama ang bawat creation. Ibinabalik ng isang shell na walang kakayahang ito ang mga ordinaryong session at iniuulat ang bahagi ng history bilang skipped. Nananatiling hindi suportado ang native filesystem history hangga't hindi nagbibigay ang adapter nito ng durable history transaction. Walang durable history o recovery archive ang P2P guest state.

Sadyang hindi kasama ang creation history sa personal snapshot sync. Ang pag-apply ng isang snapshot sa isang lokal na dokumentong may history ay nag-iingat ng nakaraang working state nito bilang hiwalay na recovery draft at nagpapawalang-bisa sa write token ng anumang bukas na editor. Nananatili sa device ang mga immutable checkpoint nito. Pinoprotektahan nito ang lokal na history habang pinapalitan ang snapshot; hindi nito pinagsasama ang magkasabay na history ng device.

Iniingatan ang mga historical na asset reference, habang ang pag-render ay nire-resolve pa rin ang mga asset sa pamamagitan ng umiiral na library ng destinasyon. Hindi pa ginagarantiya ng archive na ito ang eksaktong lumang asset bytes o lumang tool render. Nagpapatuloy ang paglalakbay ng asset-version at file-result bytes sa pamamagitan ng umiiral na hiwalay na backup part nito.

Mga na-save na bersyon at file result (v2)

May laman ang opsyonal na history part na { version: 2, assetVersions: [...], operations: [...], batches: [...] }; tinatanggap din ng mga reader ang mas naunang hugis ng history-v1 na walang batches. Kinikilala ng bawat snapshot ang matatag na asset ID at eksaktong bersyon, ang oras ng pag-save nito, haba ng byte at hex SHA-256, kasama ang isang asset record na ang _file at opsyonal na _credentialFile ay tumuturo sa mga binary part. Dala ng mga operation ang orihinal na file fact, request, report, timestamp at opsyonal na result _file; hindi naglalakbay ang mga pangalan ng storage backend, OPFS handle at execution lease. Tinatanggihan ng mga reader na history-v1-only lang ang bagong history version bago mag-import, sa halip na tahimik na iwan ang batch membership.

Itinatala ng mga batch manifest ang bawat napiling source bago iproseso, kasama ang mga file na hindi kailanman nabasa, mga cancelled na member, mga kabiguang mag-reserve ng result space at mga naantalang gawa. Bawat member ay may matatag na operation ID, source reference/fact, hiniling na output name at terminal report. Ang isang hindi nabasang source ay may nakadeklarang fact, hindi imbentadong digest. Vine-validate ng import ang member identity at pagkakapareho nito sa anumang dalang operation report. Nananatiling available ang mga batch report kahit tahasang tinanggal na ang mga indibidwal na resulta, pero hindi ibig sabihin ng isang resibo na naka-store pa rin ang output bytes nito.

Tinatanggap pa rin ng mga mas lumang reader ang v2 envelope (minReader: 1) at nire-restore ang mga pamilyar na bahagi, binibilang ang mga hindi suportadong history part bilang skipped. Nangangailangan ng buong history recovery ang isang shell na may fileHistory adapter; isang shell-internal na seam ito, hindi isang bagong HostV1 capability na nakaharap sa tool. Sinasaklaw ng lokal na Chromium gate ang tunay na two-device restore; hiwalay pa rin ang pagtanggap ng recovery sa naka-install na Tauri/iOS/Android.

Ang Hindi Naglalakbay

Inilalarawan ng storage meter ang parehong paghahati. Sumasama sa bundle ang Saved sessions, My images at File results & versions. 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 kategorya signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBI-check mo mismoKunin ang signed na fileHinahati 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 kategorya signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBI-check mo mismoKunin ang signed na file

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. Binabasa at isinusulat ng parehong module ang common envelope sa web at Tauri, sa ibabaw ng IndexedDB o filesystem storage. Lumalabas lang ang mga opsyonal na history part kung saan available ang katugmang adapter; ang isang hindi suportadong part ay iniuulat bilang skipped sa pag-import. Sinusubok ng headless suite ang mga common part laban sa isang in-memory bridge, habang may mga real-browser test din ang history transactions.

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. Hindi pa ito ginagawa. 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