Transfer Data - bundel lolly-backup

Semua yang terkumpul dari pengguna Lolly berada di perangkatnya - tanpa akun, tanpa cloud. Bundel transfer data adalah cara nilai itu berpindah: ekspor di satu instalasi, bawa file dengan cara apa pun (USB, AirDrop, email ke diri sendiri, berbagi jaringan) dan impor di instalasi lain. File itu adalah transportnya. Target bisa offline atau online. Tidak ada bedanya, karena tidak ada yang pernah berbicara dengan server.

Dua tombol yang memindahkan seluruh instalasi: Export my data menulis satu zip, Import data membacanya kembalisigned by Lollyvector SVGPeriksa sendiriGet the signed file12 paths~5.1k nodes12 groups60 KBDua tombol yang memindahkan seluruh instalasi: Export my data menulis satu zip, Import data membacanya kembalisigned by Lollyvector SVGPeriksa sendiriGet the signed file12 paths~5.1k nodes12 groups60 KB

Halaman ini adalah spesifikasi formatnya. Untuk panduan langkah demi langkah bagi pengguna akhir lihat Using Lolly → Moving to another device. Implementasinya ada di shells/web/src/data-transfer.ts, dan tests/data-transfer.test.ts mengunci kontrak bolak-balik (round-trip).

Cakupan. Sebuah bundel membawa data pengguna, bukan tool. Tool dan aset katalog disinkronkan secara terpisah dan diasumsikan sudah ada di target (dalam kasus terburuk pada versi yang lebih tinggi). Mengimpor tidak pernah menginstal atau meningkatkan tool.

Tujuan

Amplop

Sebuah bundel adalah .zip biasa. Unduhan diberi nama sesuai orang yang memilikinya - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (misalnya LollyTools-Ada-Lovelace-2026-06-26-1.zip) - sehingga folder Downloads berisi cadangan tetap mudah dibaca. Bagian nama depan dan belakang berasal dari profil dan dihilangkan jika tidak diatur. Tanpa profil menghasilkan LollyTools-2026-06-26-1.zip, dan hanya nama depan menghasilkan LollyTools-Ada-2026-06-26-1.zip. Setiap bagian dibersihkan menjadi token yang aman untuk nama berkas (huruf/angka Unicode dipertahankan, spasi/tanda baca dihapus, dibatasi hingga 32 karakter). <n> adalah urutan per hari, per perangkat, sehingga ekspor berulang di hari yang sama tidak bertabrakan dan tetap berurutan. backupFilename() di shells/web/src/data-transfer.ts membuat nama tersebut. Isi zip identik terlepas dari namanya. Di dalamnya:

PathWajibIsi
manifest.jsonyaId format, versi, jumlah dan integritas per bagian. Hal pertama yang dilihat pembaca.
profile.jsonjika diaturRekaman me milik pengguna (nama, kontak, ref headshot, flag). Dibaca lewat host.profile.
sessions.jsonyaSetiap sesi tersimpan: slot, id/versi tool, label, thumbnail (data-URL) dan data input lengkap. Dibaca lewat host.state.
assets.jsonyaMetadata untuk setiap aset yang diunggah (gambar, font, token brand), masing-masing menunjuk ke byte-nya di bawah assets/blobs/.
assets/blobs/<n>.<ext>per asetByte aset mentah (file gambar dan font). Disimpan tanpa kompresi (format yang sudah terkompresi). Ekstensinya bersifat kosmetik. MIME di assets.json adalah yang otoritatif.
prefs.jsonyaPreferensi lokal milik pengguna: theme, sidebarWidth dan tally aktivitas ct-metrics.
lolly.txtyaRingkasan bundel yang dapat dibaca manusia (jumlah, profil, nama file) bagi siapa pun yang membuka zip tanpa Lolly. Dibuat ulang setiap ekspor dan dikenali saat impor, jadi tidak pernah dihitung sebagai bagian yang dilewati. Ditulis setelah peta integritas, jadi tetap berada di luar peta itu.

Bundel sengaja berupa zip biasa: ia bertahan utuh di transport mana pun, dan alat unzip apa pun bisa memeriksanya.

profile.json adalah bagian terkecil dan yang pertama kali dilihat pembaca di aplikasi: detail yang diisi sekali oleh pembuat, plus opsi ikut serta yang memungkinkan tool memakainya.

Formulir detail Profile yang menjadi profile.json - nama, kontak, headshot dan opsi ikut serta di sampingnyasigned by Lollyvector SVGPeriksa sendiriGet the signed file18 paths~2.0k nodes41 groups30 KBFormulir detail Profile yang menjadi profile.json - nama, kontak, headshot dan opsi ikut serta di sampingnyasigned by Lollyvector SVGPeriksa sendiriGet 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-…"
  }
}
BidangMakna
formatSelalu lolly-backup. File tanpa ini ditolak sebagai "bukan backup Lolly".
formatVersionTata letak tempat bundel ini ditulis. Dinaikkan pada perubahan apa pun terhadap kumpulan atau bentuk bagian. Pembaca tidak menjadikan ini gerbang.
minReaderVersi pembaca minimum yang diperlukan untuk mengimpor bundel ini dengan aman. Ini adalah bidang yang dijadikan gerbang oleh pembaca.
appId aplikasi pembuat, untuk diagnostik.
exportedAtTimestamp ISO saat bundel dibuat.
countsApa yang dimasukkan penulis, untuk tampilan dan pemeriksaan kewarasan.
integrityOpsional. Memetakan setiap bagian kecuali manifest.json ke digest bergaya SRI sha256-<base64> dari byte tanpa kompresinya.

Kebijakan versi (kompatibilitas maju)

Pemisahan antara formatVersion dan minReader adalah yang memungkinkan format ini berkembang tanpa meninggalkan instalasi yang lebih lama:

Aturan praktis untuk penulis: jika setiap pembaca yang ada akan tetap berperilaku benar dengan mengabaikan penambahan Anda, itu aditif - naikkan formatVersion, biarkan minReader. Jika tidak, naikkan minReader.

Integritas

Ketika manifest.integrity ada, pembaca memverifikasi SHA-256 setiap bagian yang tercantum sebelum menulis apa pun. Ketidakcocokan ("gagal pemeriksaan integritasnya") atau bagian yang hilang ("tidak lengkap") membatalkan seluruh impor - tidak ada pemulihan sebagian. Ini menangkap korupsi yang bisa ditimbulkan oleh transport file (AirDrop yang terpotong, gateway email yang meng-encode ulang lampiran, sektor USB yang buruk).

Integritas sengaja dirancang sebagai upaya terbaik: hanya ditulis ketika Web Crypto tersedia (setiap konteks peramban aman dan Node modern), dan hanya diverifikasi ketika baik peta maupun Web Crypto tersedia. Bundel tanpa peta - misalnya dari sebelum integritas ada - diimpor tanpa perubahan. "Tidak bisa diverifikasi" tidak pernah diperlakukan sebagai "rusak".

Manifes tidak mencantumkan dirinya sendiri maupun README lolly.txt yang dibuat ulang. Digest mencakup bagian-bagian yang dijamin oleh manifes.

Semantik impor

Impor bersifat gabung-timpa (merge-overwrite), tidak pernah ganti-semua:

Sesi tersimpan menautkan ulang ke gambarnya secara otomatis: referensi aset dipertahankan berdasarkan id, dan bridge menyelesaikannya ulang setelah gambar yang diunggah dipulihkan (memang harus begitu, karena URL blob: tidak bertahan setelah reload).

Ringkasan impor melaporkan { profile, sessions, userAssets, prefs, skipped, failedAssets }. failedAssets menghitung aset yang diunggah yang gagal dipulihkan (misalnya penyimpanan perangkat penuh). Ini berbeda dari skipped, yang menghitung bagian dari penulis yang lebih baru dan kompatibel-maju yang tidak dikenali oleh build ini. UI menampilkan skipped ("… · N item lebih baru dilewati"), sehingga pemulihan jujur soal apa yang ditinggalkannya.

Apa yang tidak ikut berpindah

Meteran penyimpanan merinci pemisahan yang sama. Sesi tersimpan dan My images ikut dalam bundel. Cache aset, pratinjau tool dan pin offline di bawahnya semuanya dapat diturunkan ulang, jadi tetap tinggal.

Meteran penyimpanan memecah data perangkat ini ke dalam kategori bernama, dengan Saved sessions dan My images dilacak terpisah dari Asset cache, di sini pada instalasi baru di mana setiap kategori masih kosongsigned by Lollyvector SVGPeriksa sendiriGet the signed file25 paths~4.8k nodes46 groups59 KBMeteran penyimpanan memecah data perangkat ini ke dalam kategori bernama, dengan Saved sessions dan My images dilacak terpisah dari Asset cache, di sini pada instalasi baru di mana setiap kategori masih kosongsigned by Lollyvector SVGPeriksa sendiriGet the signed file25 paths~4.8k nodes46 groups59 KB

Jaminan lintas shell

data-transfer.ts membaca dan menulis secara eksklusif melalui capability bridge (host.profile, host.state, host.assets) dan preferensi localStorage bersama. Karena bridge adalah satu-satunya titik sambung, modul yang sama menghasilkan bundel yang identik byte-per-byte di setiap shell meskipun penyimpanan di baliknya berbeda - IndexedDB di web, sistem berkas di Tauri. Shell Tauri menggunakan kembali modul ini tanpa perubahan. Hanya implementasi host.state mereka yang berbeda. Uji headless menjalankan round-trip penuh terhadap bridge in-memory, itulah sebabnya uji ini mewakili semuanya.

Dua shell berada di luar jaminan itu, karena alasan yang berbeda:

Titik ekstensi yang dicadangkan

Amplop ini sengaja dirancang sebagai manifes plus sekumpulan bagian bernama, sehingga jenis data portabel baru bisa menumpang di kemudian hari tanpa perubahan yang merusak. Bagian-bagian ini masuk sebagai bagian aditif (formatVersion baru, minReader yang sama), dan pembaca saat ini melewati apa pun yang tidak dikenalinya. Ini ada di roadmap, belum diimplementasikan. Nama-namanya dicadangkan di sini agar format tetap koheren saat bagian tersebut hadir.

Apa pun di luar nama yang dicadangkan dan bagian-bagian di atas, bagi pembaca, adalah bagian yang tidak dikenal: dibiarkan tanpa diubah dan dihitung dalam skipped.

Referensi