Lolly
Lancarkan Aplikasi

Pemindahan Data - bundel lolly-backup

Segala yang terkumpul oleh pengguna Lolly berada pada peranti mereka - tiada akaun, tiada awan. Bundel pemindahan data adalah cara nilai itu berpindah: eksportkannya pada satu pemasangan, bawa fail itu dengan apa cara sekalipun (USB, AirDrop, e-mel-kepada-diri-sendiri, perkongsian rangkaian) dan import pada yang lain. Fail itu ialah pengangkutan tersebut. Sasaran boleh berada dalam talian atau luar talian. Tiada bezanya, kerana tiada apa pun yang pernah berhubung dengan pelayan.

The two buttons that move a whole install: Export my data writes one zip, Import data reads it back signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBSemak sendiriDapatkan fail yang ditandatanganiThe two buttons that move a whole install: Export my data writes one zip, Import data reads it back signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBSemak sendiriDapatkan fail yang ditandatangani

Halaman ini adalah spesifikasi format. Untuk panduan pengguna akhir lihat Cari dan pulihkan hasil kerja anda → Pindahkan kerja anda ke peranti lain. Pelaksanaannya ialah shells/web/src/data-transfer.ts, dan tests/data-transfer.test.ts mengunci kontrak pergi-balik itu.

Skop. Bundel membawa data pengguna, bukan alat katalog. Alat katalog dan aset katalog disegerakkan secara berasingan dan diandaikan sudah wujud pada sasaran (paling teruk pada versi yang lebih tinggi); alat yang dibuat sendiri oleh pengguna berpindah di dalam profile.json. Import tidak sekali-kali memasang atau menaik taraf sesuatu alat katalog.

Matlamat

Sampul

Bundel adalah .zip biasa. Muat turun itu dinamakan sempena orang yang memilikinya - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (contohnya LollyTools-Ada-Lovelace-2026-06-26-1.zip) - supaya folder Downloads penuh sandaran kekal mudah difahami. Bahagian nama pertama dan akhir datang daripada profil dan ditinggalkan apabila tidak ditetapkan. Tiada profil menghasilkan LollyTools-2026-06-26-1.zip, dan hanya nama pertama menghasilkan LollyTools-Ada-2026-06-26-1.zip. Setiap bahagian disanitasi kepada token selamat-nama-fail (huruf/angka Unicode dikekalkan, ruang/tanda baca dibuang, dihadkan pada 32 aksara). <n> adalah jujukan per-hari, per-peranti, jadi eksport berulang pada hari yang sama tidak berlanggar dan kekal tersusun. backupFilename() dalam shells/web/src/data-transfer.ts membina nama itu. Kandungan zip itu sama tanpa mengira nama. Di dalamnya:

LaluanDiperlukanKandungan
manifest.jsonyaId format, versi, kiraan dan integriti per-bahagian. Perkara pertama yang dilihat oleh pembaca.
profile.jsonapabila ditetapkanRekod me pengguna yang lengkap: nama, hubungan, rujukan gambar kepala dan bendera, ditambah folder, Trash, pelan projek, templat pengguna dan alat buatan pengguna, kegemaran, alat tersembunyi, pilihan bahasa dan emoji. Dibaca melalui host.profile.
sessions.jsonyaSetiap sesi tersimpan: slot, id/versi alat, label, lakaran kecil (data-URL) dan data input penuh. Dibaca melalui host.state.
assets.jsonyaMetadata bagi setiap aset yang dimuat naik (imej, fon, token jenama, logo, salinan tersimpan muat turun), setiap satu menunjuk kepada baitnya di bawah assets/blobs/.
assets/blobs/<n>.<ext>setiap asetBait aset mentah (fail imej dan fon). Disimpan tanpa mampatan (format yang sudah dimampatkan). Sambungan itu bersifat kosmetik sahaja. MIME dalam assets.json yang muktamad.
assets/blobs/<n>.c2paapabila hadirContent Credentials yang diekstrak sebagai bait binari yang tepat, dirujuk oleh _credentialFile dalam rekod aset. Ini bukan kunci penandatanganan peranti.
design-systems.jsonapabila hadirSistem reka bentuk yang dibuat atau ditambah pada pemasangan ini, sebagai { active, records }. Digabung mengikut id semasa import; pilihan aktif bundel itu terpakai hanya apabila sasaran tiada sistem reka bentuk sendiri.
file-history.jsonpilihanSnapshot aset berversi, laporan operasi fail terminal dan manifes batch lengkap. Bahagian sejarah ini mempunyai versinya sendiri; dibekalkan oleh penyesuai sandaran fileHistory dalaman milik shell.
revision-history.jsonpilihan, sandaran manualID ciptaan yang stabil, checkpoint yang dikekalkan, lakaran kecil dan draf pemulihan berputar. Dibekalkan oleh host.state.history.backup jika disokong.
file-history/versions/setiap snapshotBait aset terdahulu dan credential yang diekstrak, tidak bergantung pada sama ada aset semasa masih wujud.
file-history/results/setiap operasi selesaiBait output yang tepat. Tiada fail asal yang dipilih-untuk-penukaran dikekalkan atau disertakan.
prefs.jsonyaKeutamaan tempatan milik pengguna: theme, sidebarWidth dan kiraan aktiviti ct-metrics.
lolly.txtyaRingkasan bundel yang boleh dibaca manusia (kiraan, profil, nama fail) untuk sesiapa yang membuka zip itu tanpa Lolly. Dijana semula pada setiap eksport dan dikenali semasa import, jadi ia tidak sekali-kali dikira sebagai bahagian yang dilangkau. Ia ditulis selepas peta integriti, jadi ia kekal di luar peta itu.

Bundel itu sengaja dijadikan zip biasa: ia bertahan pada mana-mana pengangkutan tanpa rosak, dan mana-mana alat unzip boleh memeriksanya.

profile.json adalah bahagian terkecil dan yang pertama dilihat oleh pembaca dalam aplikasi: butiran yang diisi sekali oleh pengeluar, ditambah opt-in yang membenarkan alat menggunakannya.

Borang butiran Profil yang menjadi profile.json: nama, butiran hubungan dan foto profil signed by Lollyvector SVG15 paths~1.2k nodes30 groups1 image40 KBSemak sendiriDapatkan fail yang ditandatangani

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-…"
  }
}
MedanMaksud
formatSentiasa lolly-backup. Fail tanpanya ditolak sebagai "bukan sandaran Lolly".
formatVersionSusun atur yang ditulis dengan bundel ini. Dinaikkan pada apa-apa perubahan set atau bentuk bahagian. Pembaca tidak menjadikannya syarat pengesahan.
minReaderVersi pembaca minimum yang diperlukan untuk mengimport bundel ini dengan selamat. Inilah medan yang dijadikan syarat oleh pembaca.
appId aplikasi yang menghasilkan, untuk diagnostik.
exportedAtCap masa ISO bila bundel itu dicipta.
countsApa yang dimasukkan oleh penulis, untuk paparan dan semakan kewarasan.
integrityPilihan. Memetakan setiap bahagian kecuali manifest.json kepada digest gaya-SRI sha256-<base64> bagi baitnya yang tidak dimampatkan.

Dasar versi (keserasian ke hadapan)

Pemisahan antara formatVersion dan minReader itulah yang membenarkan format ini berkembang tanpa mengabaikan pemasangan yang lebih lama:

Petua umum untuk pengarang: jika setiap pembaca sedia ada masih akan bertindak dengan betul dengan mengabaikan tambahan anda, ia adalah tambahan - naikkan formatVersion, tinggalkan minReader. Jika tidak, naikkan minReader.

Integriti

Apabila manifest.integrity hadir, pembaca mengesahkan SHA-256 setiap bahagian yang disenaraikan sebelum menulis apa-apa. Ketidakpadanan ("failed its integrity check") atau bahagian yang hilang ("incomplete") membatalkan keseluruhan import - tiada pemulihan separa. Ini menangkap kerosakan yang boleh diakibatkan oleh pengangkutan fail (AirDrop yang terputus, get laluan e-mel yang mengekod semula lampiran, sektor USB yang rosak).

Integriti direka secara usaha-terbaik: ia hanya ditulis di mana Web Crypto tersedia (setiap konteks pelayar selamat dan Node moden), dan hanya disahkan apabila kedua-dua peta dan Web Crypto hadir. Bundel tanpa peta itu - contohnya dari sebelum integriti wujud - diimport tanpa perubahan. "Tidak dapat disahkan" tidak sekali-kali dianggap sebagai "rosak".

Manifes itu tidak menyenaraikan dirinya sendiri mahupun README lolly.txt yang dijana semula. Digest itu meliputi bahagian yang dijamin oleh manifes.

Semantik import

Import ialah satu gabungan, tidak sekali-kali ganti-semua:

Sesi tersimpan menyambung semula kepada imejnya secara automatik: rujukan aset dikekalkan mengikut id, dan jambatan itu menyelesaikannya semula selepas imej yang dimuat naik dipulihkan (ia memang mesti berbuat demikian, kerana URL blob: tidak bertahan selepas muat semula halaman).

Ringkasan import melaporkan { profile, sessions, userAssets, prefs, skipped, failedAssets }. failedAssets mengira aset yang dimuat naik yang tidak dapat dipulihkan (storan peranti penuh, contohnya). Ia berbeza daripada skipped, yang mengira bahagian daripada penulis lebih baharu serasi-hadapan yang tidak dikenali oleh binaan ini. UI memaparkan skipped ("… · N newer items skipped"), jadi pemulihan itu jujur tentang apa yang ditinggalkannya.

Apabila sejarah fail hadir, ringkasan itu turut membawa assetVersions, fileOperations dan failedHistory. Kehabisan storan atau konflik ID yang tidak boleh diubah boleh menyebabkan pemulihan separa; UI memberitahu pengguna untuk mengekalkan sandaran sumber. Segerak awan tidak memajukan revision yang telah dilaksanakannya selepas pemulihan separa atau yang tidak disokong, jadi snapshot itu kekal tersedia untuk dicuba semula. Pemulihan bukan satu transaksi tunggal merentasi semua storan profil/sesi/aset/sejarah.

Sejarah ciptaan (v3)

Sandaran manual daripada satu hos web yang menyokong sejarah menyertakan revision-history.json dengan skema { version: 1, documents, revisions, recoveries } miliknya sendiri. Ia membawa ID yang dikekalkan, snapshot input kanonik, cap versi, pratonton raster dan draf penulis berasingan. Penyesuai sejarah menangkap sesi semasa dan head-nya dalam satu transaksi baca; sessions.json menggunakan snapshot semasa yang sama itu untuk pembaca yang lebih lama.

Pemulihan menyemak SHA-256 muatan dan kiraan bait, identiti unik, perhubungan document/head, keturunan (ancestry), cap masa, jenis pratonton dan had sebelum melakukan commit arkib dalam satu transaksi. Rujukan induk yang dipadatkan mungkin tiada. Kerja semasa sedia ada tidak sekali-kali digantikan secara senyap: apabila satu ciptaan berada pada kedua-dua belah, pihak yang tidak dikekalkan sebagai semasa menjadi draf terlindung. Had pemindahan 384 MiB milik arkib disemak secara eksplisit, dan had storan dikuatkuasakan tanpa memotong checkpoint yang dikekalkan. Sandaran keseluruhan masih menggunakan pelaksanaan ZIP dalam-memori dan bukan arkib strim.

Ringkasan menambah revisions dan recoveryDrafts, mengira hanya apa yang ditambah oleh import ini, serta added, kept, replaced, copies dan hidden bagi cara setiap ciptaan digabungkan. Satu shell tanpa keupayaan ini memulihkan sesi biasa dan melaporkan bahagian sejarah sebagai dilangkau. Sejarah sistem fail native kekal tidak disokong sehingga penyesuainya membekalkan transaksi sejarah yang tahan lasak. Keadaan tetamu P2P tiada sejarah atau arkib pemulihan yang tahan lasak.

Segerak snapshot peribadi secara eksplisit mengecualikan sejarah ciptaan. Menggunakan satu snapshot pada dokumen tempatan yang membawa sejarah mengekalkan keadaan kerja sebelumnya sebagai satu draf pemulihan berasingan dan membatalkan token tulis mana-mana penyunting yang sedang terbuka. Checkpoint yang tidak boleh diubah kekal pada peranti. Ini melindungi sejarah tempatan semasa penggantian snapshot; ia tidak menggabungkan sejarah peranti serentak.

Rujukan aset sejarah dikekalkan, manakala rendering masih menyelesaikan aset melalui pustaka sedia ada destinasi. Arkib ini belum lagi menjamin bait aset lama atau render alat lama yang tepat. Bait versi-aset dan hasil-fail terus berpindah melalui bahagian sandaran berasingan yang sudah ada.

Versi tersimpan dan hasil fail (v2)

Bahagian sejarah pilihan mengandungi { version: 2, assetVersions: [...], operations: [...], batches: [...] }; pembaca turut menerima bentuk history-v1 terdahulu tanpa batches. Setiap snapshot mengenal pasti ID aset yang stabil dan versi tepatnya, masa simpannya, panjang bait dan SHA-256 hex, ditambah satu rekod aset yang _file dan _credentialFile pilihannya menunjuk kepada bahagian binari. Operasi membawa fakta fail asal, permintaan, laporan, cap masa dan _file hasil pilihan; nama backend storan, pemegang OPFS dan pajakan pelaksanaan tidak turut berpindah. Pembaca history-v1-sahaja yang lebih lama menolak versi sejarah baharu sebelum mengimport, dan bukannya secara senyap menggugurkan keahlian batch.

Manifes batch merekod setiap sumber yang dipilih sebelum diproses, termasuk fail yang tidak pernah dibaca, ahli yang dibatalkan, kegagalan menempah ruang hasil dan kerja yang terputus. Setiap ahli mempunyai ID operasi yang stabil, rujukan/fakta sumber, nama output yang diminta dan laporan terminal. Satu sumber yang tidak dibaca mempunyai fakta yang diisytiharkan, bukan digest rekaan. Import mengesahkan identiti ahli dan ketekalan dengan mana-mana laporan operasi yang dibawa. Laporan batch kekal tersedia apabila hasil individu telah dibuang secara eksplisit, tetapi satu resit tidak bermakna bait outputnya masih disimpan.

Pembaca lama masih menerima sampul v2 (minReader: 1) dan memulihkan bahagian yang dikenali, mengira bahagian sejarah yang tidak disokong sebagai dilangkau. Pemulihan sejarah penuh memerlukan satu shell dengan penyesuai fileHistory; ini ialah seam dalaman-shell, bukan keupayaan HostV1 baharu yang menghadap alat. Pemulihan dua-peranti sebenar dilindungi oleh get tempatan Chromium; penerimaan pemulihan Tauri/iOS/Android yang dipasang kekal berasingan.

Apa yang tidak berpindah

Meter storan memerincikan pemisahan yang sama. Sesi tersimpan, My images dan File results & versions dibawa dalam bundel. Cache aset, pratonton alat dan sematan luar talian di bawahnya semuanya boleh diterbitkan semula, jadi ia kekal ditinggalkan.

Meter storan memecahkan data peranti ini kepada kategori bernama, dengan Saved sessions dan My images dijejaki berasingan daripada Asset cache, di sini pada pemasangan baharu di mana setiap kategori masih kosong signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBSemak sendiriDapatkan fail yang ditandatanganiMeter storan memecahkan data peranti ini kepada kategori bernama, dengan Saved sessions dan My images dijejaki berasingan daripada Asset cache, di sini pada pemasangan baharu di mana setiap kategori masih kosong signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBSemak sendiriDapatkan fail yang ditandatangani

Jaminan merentas shell

data-transfer.ts membaca dan menulis secara eksklusif melalui jambatan keupayaan (host.profile, host.state, host.assets) dan keutamaan localStorage yang dikongsi. Modul yang sama membaca dan menulis sampul sepunya pada web dan Tauri, melalui storan IndexedDB atau sistem fail. Bahagian sejarah pilihan muncul hanya di tempat penyesuai berkaitannya tersedia; satu bahagian yang tidak disokong dilaporkan sebagai dilangkau semasa import. Suit headless menjalankan bahagian sepunya terhadap satu jambatan dalam-memori, manakala transaksi sejarah turut mempunyai ujian pelayar-sebenar.

Dua shell berada di luar jaminan itu, atas sebab yang berbeza:

Titik lanjutan terpelihara

Envelope itu direka sebagai manifes ditambah satu set bahagian bernama, supaya jenis data mudah alih yang baharu boleh menumpang kemudian tanpa perubahan yang memecahkan (breaking change). Ia disisipkan sebagai bahagian tambahan (formatVersion baharu, minReader yang sama), dan pembaca hari ini melangkau apa yang tidak dikenalinya. Ini belum dibina. Nama-namanya diperuntukkan di sini supaya format kekal koheren apabila ia tiba kelak.

Apa-apa di luar nama terpelihara ini dan bahagian di atas adalah, bagi pembaca, bahagian yang tidak diketahui: dibiarkan tanpa disentuh dan dikira dalam skipped.

Rujukan