Lolly उपयोगकर्ता जो कुछ भी जमा करता है वह उसके डिवाइस पर रहता है - कोई अकाउंट नहीं, कोई क्लाउड नहीं। डेटा-ट्रांसफ़र बंडल इसी मूल्य को हिलाने का तरीका है: इसे एक इंस्टॉल पर एक्सपोर्ट करें, फ़ाइल को किसी भी माध्यम से ले जाएँ (USB, AirDrop, ईमेल-टू-सेल्फ़, एक नेटवर्क शेयर) और दूसरे पर इम्पोर्ट करें। फ़ाइल ही परिवहन है। लक्ष्य डिवाइस ऑफ़लाइन हो या ऑनलाइन। इससे कोई फ़र्क़ नहीं पड़ता, क्योंकि कभी किसी सर्वर से बात नहीं होती।
signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBखुद जाँचेंसाइन की हुई फ़ाइल पाएँ
signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBखुद जाँचेंसाइन की हुई फ़ाइल पाएँ
यह पृष्ठ फ़ॉर्मैट स्पेक है। अंतिम-उपयोगकर्ता वॉकथ्रू के लिए देखें अपना काम खोजें और वापस पाएँ → अपना काम किसी दूसरे डिवाइस पर ले जाएँ। कार्यान्वयन है shells/web/src/data-transfer.ts, और tests/data-transfer.test.ts राउंड-ट्रिप कॉन्ट्रैक्ट को पिन करता है।
दायरा। एक बंडल उपयोगकर्ता डेटा ले जाता है, कैटलॉग टूल नहीं। कैटलॉग टूल और कैटलॉग एसेट्स अलग से सिंक होते हैं और मान लिया जाता है कि वे लक्ष्य पर पहले से मौजूद हैं (सबसे बुरी स्थिति में एक ऊँचे वर्शन पर); उपयोगकर्ता के अपने बनाए टूल
profile.jsonके भीतर यात्रा करते हैं। इम्पोर्ट कभी कोई कैटलॉग टूल इंस्टॉल या अपग्रेड नहीं करता।
लक्ष्य
- एक फ़ॉर्मैट, हर शेल। वेब PWA, Tauri डेस्कटॉप/मोबाइल ऐप्स और भविष्य के शेल वही एनवेलप और समर्थित पार्ट स्कीमा साझा करते हैं। वैकल्पिक पार्ट हर शेल की क्षमताओं पर निर्भर करते हैं; असमर्थित पार्ट रिपोर्ट किए जाते हैं। हर कैपेबिलिटी ब्रिज अपना स्टोरेज अडैप्टर देता है।
- यात्रा में जीवित रहता है। पारगमन में बिगड़ा या कटा-छँटा बंडल इम्पोर्ट पर स्पष्ट रूप से विफल होता है, कभी आधा-अधूरा रीस्टोर नहीं करता।
- इस वर्शन से आगे टिकता है। एक पुराना ऐप भी एक नए बंडल के पहचाने गए हिस्सों को इम्पोर्ट कर सकता है। एक सचमुच ब्रेकिंग फ़ॉर्मैट स्पष्ट रूप से अस्वीकार कर दिया जाता है।
- मर्ज करना सुरक्षित है। पहले से उपयोग में मौजूद इंस्टॉल पर इम्पोर्ट करना कभी उस चीज़ को नहीं मिटाता जो बंडल में नहीं थी।
एनवेलप
एक बंडल एक सादा .zip है। डाउनलोड का नाम उस व्यक्ति के नाम पर रखा जाता है जिसका यह है - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (उदाहरण के लिए LollyTools-Ada-Lovelace-2026-06-26-1.zip) - ताकि बैकअप्स से भरा Downloads फ़ोल्डर पठनीय बना रहे। पहला और अंतिम भाग प्रोफ़ाइल से आते हैं और सेट न होने पर छोड़ दिए जाते हैं। कोई प्रोफ़ाइल न होने पर LollyTools-2026-06-26-1.zip मिलता है, और अकेला पहला नाम होने पर LollyTools-Ada-2026-06-26-1.zip मिलता है। हर भाग को एक फ़ाइलनाम-सुरक्षित टोकन में सैनिटाइज़ किया जाता है (Unicode अक्षर/अंक रखे जाते हैं, स्पेस/विराम चिह्न हटा दिए जाते हैं, अधिकतम 32 वर्ण)। <n> एक प्रति-दिन, प्रति-डिवाइस क्रम है, ताकि एक ही दिन के बार-बार एक्सपोर्ट टकराएँ नहीं और क्रम में रहें। shells/web/src/data-transfer.ts में backupFilename() यह नाम बनाता है। नाम चाहे जो भी हो, zip की सामग्री समान रहती है। अंदर:
| पथ | आवश्यक | सामग्री |
|---|---|---|
manifest.json | हाँ | फ़ॉर्मैट id, वर्शन, गिनतियाँ और प्रति-भाग इंटीग्रिटी। पहली चीज़ जो एक रीडर देखता है। |
profile.json | सेट होने पर | उपयोगकर्ता का पूरा me रिकॉर्ड: नाम, संपर्क, हेडशॉट संदर्भ और फ़्लैग, साथ ही फ़ोल्डर, Trash, प्रोजेक्ट ब्लूप्रिंट, यूज़र टेम्पलेट और यूज़र-निर्मित टूल, फ़ेवरिट, छुपाए गए टूल, भाषा और इमोजी चुनाव। host.profile के ज़रिए पढ़ा जाता है। |
sessions.json | हाँ | हर सेव किया गया सेशन: स्लॉट, टूल id/वर्शन, लेबल, थंबनेल (data-URL) और पूरा इनपुट डेटा। host.state के ज़रिए पढ़ा जाता है। |
assets.json | हाँ | हर अपलोड की गई एसेट (इमेज, फ़ॉन्ट, ब्रांड टोकन, लोगो, डाउनलोड की सेव की गई कॉपी) का मेटाडेटा, हर एक assets/blobs/ के तहत अपने बाइट्स की ओर इशारा करता है। |
assets/blobs/<n>.<ext> | प्रति एसेट | कच्चे एसेट बाइट्स (इमेज और फ़ॉन्ट फ़ाइलें)। असंपीड़ित संग्रहीत (पहले से संपीड़ित फ़ॉर्मैट्स)। एक्सटेंशन केवल दिखावटी है। assets.json में MIME ही प्रामाणिक है। |
assets/blobs/<n>.c2pa | मौजूद होने पर | एसेट रिकॉर्ड में _credentialFile द्वारा संदर्भित, असली बाइनरी बाइट्स के रूप में निकाले गए Content Credentials। ये डिवाइस साइनिंग कीज़ नहीं हैं। |
design-systems.json | मौजूद होने पर | इस इंस्टॉल पर बनाए या जोड़े गए डिज़ाइन सिस्टम, { active, records } के रूप में। इम्पोर्ट पर id से मर्ज किया जाता है; बंडल की सक्रिय पसंद तभी लागू होती है जब लक्ष्य के पास अपना कोई डिज़ाइन सिस्टम न हो। |
file-history.json | वैकल्पिक | वर्शन वाले एसेट स्नैपशॉट, टर्मिनल फ़ाइल-ऑपरेशन रिपोर्ट और पूरे बैच मैनिफ़ेस्ट। हिस्ट्री भाग का अपना वर्शन है; शेल के अंतर्गत fileHistory बैकअप अडैप्टर द्वारा प्रदान किया जाता है। |
revision-history.json | वैकल्पिक, मैनुअल बैकअप | स्थायी क्रिएशन ID, रखे गए चेकपॉइंट, थंबनेल और चलती हुई रिकवरी ड्राफ़्ट। जहाँ समर्थित हो वहाँ host.state.history.backup द्वारा प्रदान किया जाता है। |
file-history/versions/ | प्रति स्नैपशॉट | पुराने एसेट बाइट्स और निकाले गए क्रेडेंशियल, इससे बेपरवाह कि मौजूदा एसेट अभी भी मौजूद है या नहीं। |
file-history/results/ | प्रति पूर्ण ऑपरेशन | असली आउटपुट बाइट्स। कन्वर्ज़न के लिए चुनी गई कोई मूल फ़ाइल रखी या शामिल नहीं की जाती। |
prefs.json | हाँ | उपयोगकर्ता-स्वामित्व वाली स्थानीय प्राथमिकताएँ: theme, sidebarWidth और ct-metrics गतिविधि गणना। |
lolly.txt | हाँ | बंडल का एक मानव-पठनीय सारांश (गिनतियाँ, प्रोफ़ाइल, फ़ाइलनाम) उस किसी के लिए जो Lolly के बिना zip खोलता है। हर एक्सपोर्ट पर फिर से बनाया जाता है और इम्पोर्ट पर पहचाना जाता है, इसलिए यह कभी छूटे हुए भाग के रूप में नहीं गिना जाता। यह इंटीग्रिटी मैप के बाद लिखा जाता है, इसलिए यह उससे बाहर रहता है। |
बंडल जानबूझकर एक सादा zip है: यह किसी भी परिवहन में बरकरार बचता है, और कोई भी अनज़िप टूल इसका निरीक्षण कर सकता है।
profile.json सबसे छोटा भाग है और वह जिसे ऐप में एक रीडर सबसे पहले देखता है: वे विवरण जिन्हें एक निर्माता एक बार भरता है, साथ ही वह ऑप्ट-इन जो टूल को उनका उपयोग करने देता है।
signed by Lollyvector SVG15 paths~1.2k nodes30 groups1 image40 KBखुद जाँचेंसाइन की हुई फ़ाइल पाएँ
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-…"
}
}| फ़ील्ड | अर्थ |
|---|---|
format | हमेशा lolly-backup। इसके बिना फ़ाइल "not a Lolly backup" के रूप में अस्वीकार कर दी जाती है। |
formatVersion | वह लेआउट जिसके साथ यह बंडल लिखा गया था। भाग-समूह या आकारों में किसी भी बदलाव पर बढ़ाया जाता है। रीडर इस पर गेट नहीं करते। |
minReader | न्यूनतम रीडर वर्शन जो इस बंडल को सुरक्षित रूप से इम्पोर्ट करने के लिए आवश्यक है। यही वह फ़ील्ड है जिस पर रीडर गेट करते हैं। |
app | निर्माण करने वाला ऐप id, निदान के लिए। |
exportedAt | बंडल बनाए जाने का ISO टाइमस्टैम्प। |
counts | लेखक ने क्या डाला, प्रदर्शन और सैनिटी-चेकिंग के लिए। |
integrity | वैकल्पिक। manifest.json को छोड़कर हर भाग को उसके असंपीड़ित बाइट्स के SRI-शैली sha256-<base64> डाइजेस्ट से मैप करता है। |
वर्शन नीति (फ़ॉरवर्ड संगतता)
formatVersion और minReader के बीच का विभाजन ही वह चीज़ है जो फ़ॉर्मैट को पुराने इंस्टॉल्स को अनाथ किए बिना बढ़ने देती है:
- जब
manifest.minReader ≤अपने ही रीडर वर्शन से कम या बराबर हो, तभी एक रीडर बंडल इम्पोर्ट करता है। यह तभी मना करता है ("needs a newer version of the app" के साथ) जब बंडल स्पष्ट रूप से एक नए रीडर की माँग करता है। - एक additive बदलाव - एक नया वैकल्पिक भाग, या एक नया वैकल्पिक मैनिफ़ेस्ट फ़ील्ड -
formatVersionबढ़ाता है लेकिनminReaderको अपरिवर्तित छोड़ता है। पुराने ऐप्स फिर भी हर वह भाग इम्पोर्ट करते हैं जिसे वे पहचानते हैं। जिन भागों को वे नहीं पहचानते उन्हें छोड़ दिया जाता है (नीचे देखें), चुपचाप गिराया नहीं जाता। - एक breaking बदलाव - जहाँ किसी भाग का गलत इम्पोर्ट डेटा को भ्रष्ट कर देता है, या जहाँ पहले वैकल्पिक भाग अनिवार्य हो जाता है -
minReaderबढ़ाता है। पुराने ऐप्स फिर उस चीज़ को इम्पोर्ट करने के बजाय जिसे वे संभाल नहीं सकते, स्पष्ट रूप से मना कर देते हैं। - यदि भविष्य का कोई बंडल
formatVersionसेट करता है लेकिनminReaderछोड़ देता है, तो रीडर सावधानी सेformatVersionपर गेट करने में वापस आ जाते हैं (बदलाव को ब्रेकिंग मानते हुए)।
लेखकों के लिए अंगूठे का नियम: यदि हर मौजूदा रीडर आपके जोड़े को अनदेखा करके भी सही काम करता रहेगा, तो यह additive है -
formatVersionबढ़ाएँ,minReaderछोड़ दें। अन्यथाminReaderबढ़ाएँ।
इंटीग्रिटी
जब manifest.integrity मौजूद होता है, तो एक रीडर कुछ भी लिखने से पहले हर सूचीबद्ध भाग का SHA-256 सत्यापित करता है। कोई बेमेल ("failed its integrity check") या कोई गायब भाग ("incomplete") पूरे इम्पोर्ट को रद्द कर देता है - कोई आंशिक रीस्टोर नहीं होता। यह उस भ्रष्टाचार को पकड़ता है जो एक फ़ाइल परिवहन ला सकता है (एक कटा हुआ AirDrop, एक ईमेल गेटवे जिसने अटैचमेंट को फिर से एनकोड किया, एक खराब USB सेक्टर)।
इंटीग्रिटी डिज़ाइन से ही बेस्ट-एफ़र्ट है: यह केवल वहीं लिखी जाती है जहाँ Web Crypto उपलब्ध है (हर सुरक्षित ब्राउज़र संदर्भ और आधुनिक Node), और केवल तभी सत्यापित होती है जब मैप और Web Crypto दोनों मौजूद हों। बिना मैप वाला बंडल - उदाहरण के लिए इंटीग्रिटी अस्तित्व में आने से पहले का कोई बंडल - बिना बदलाव के इम्पोर्ट हो जाता है। "Cannot verify" को कभी "corrupt" के रूप में नहीं लिया जाता।
मैनिफ़ेस्ट न तो अपने आप को सूचीबद्ध करता है और न ही फिर से बनाए गए lolly.txt README को। डाइजेस्ट उन्हीं भागों को कवर करते हैं जिनकी मैनिफ़ेस्ट गारंटी देता है।
इम्पोर्ट सिमेंटिक्स
इम्पोर्ट एक मर्ज है, कभी सब कुछ बदलना नहीं:
- लक्ष्य पर मौजूदा डेटा जगह पर छोड़ दिया जाता है।
- जब कोई सेशन स्लॉट या अपलोड की गई इमेज id दोनों पर मौजूद हो, तो हाल ही में सेव की गई कॉपी रखी जाती है, ताकि कोई पुराना बैकअप लक्ष्य पर नए काम को कभी ओवरराइट न करे। बराबर या अज्ञात समय होने पर लक्ष्य की कॉपी रखी जाती है। क्रिएशन हिस्ट्री वाले वेब इंस्टॉल पर, यही नियम तय करता है कि किसी क्रिएशन की कौन सी कॉपी वर्तमान बनी रहती है, और दूसरी कॉपी एक protected draft के रूप में रखी जाती है (नीचे देखें)।
- प्रोफ़ाइल रिकॉर्ड मर्ज किया जाता है, बदला नहीं जाता। लक्ष्य पर मौजूद हर फ़ोल्डर अपनी सामग्री के साथ बना रहता है; बंडल का कोई फ़ोल्डर जो लक्ष्य के पास नहीं है वह जोड़ दिया जाता है, और जो फ़ोल्डर दोनों पर है वह लक्ष्य का नाम और parent बनाए रखता है और बंडल के वे सदस्य पा लेता है जो उसके पास नहीं थे। लक्ष्य पर किसी फ़ोल्डर में फ़ाइल किया गया सेशन वहीं फ़ाइल रहता है।
- फ़ेवरिट (टूल, कैटलॉग एसेट और Projects आइटम) मिला दिए जाते हैं। बंडल के टेम्पलेट, Projects टेम्पलेट और यूज़र टूल तभी जोड़े जाते हैं जब लक्ष्य के पास उस id वाला कोई रिकॉर्ड न हो। दोनों के Trash एंट्री रखे जाते हैं, ताकि कोई ऐसा आइटम जो किसी भी इंस्टॉल पर रीस्टोर किया जा सकता था, अब भी किया जा सके।
- प्रोफ़ाइल का हर दूसरा फ़ील्ड (नाम, संपर्क विवरण, भाषा, फ़ीचर फ़्लैग, छुपाए गए टूल और बाक़ी सेटिंग्स) लक्ष्य का मान बनाए रखता है। जो फ़ील्ड लक्ष्य पर खाली है वह बंडल का मान ले लेता है।
prefs.jsonके लिए भी यही होता है: कोई प्राथमिकता केवल वहीं लिखी जाती है जहाँ लक्ष्य के पास कोई नहीं है। - डिवाइस सिंक का सामान्य अप्लाई इसका अपवाद है: डिवाइसों को साथ बनाए रखते हुए, यह सिंक की गई कॉपी का प्रोफ़ाइल रिकॉर्ड, प्राथमिकताएँ, सेशन और इमेज ले लेता है। किसी पुरानी कॉपी को रीस्टोर करना भी यही करता है, क्योंकि यह जानबूझकर समय में पीछे जाता है। पहला जॉइन, इसे इस डिवाइस पर लाएं, एक इम्पोर्ट की तरह मर्ज करता है।
- पुराने एसेट वर्शन और ऑपरेशन ID अपरिवर्तनीय अपवाद हैं: दोबारा इम्पोर्ट करना आइडेम्पोटेंट है, और जो ID पहले से अलग बाइट्स/हिस्ट्री का नाम रखती है उसे ओवरराइट नहीं, अस्वीकार किया जाता है। किसी एक जैसी मौजूदा एसेट को फिर से इम्पोर्ट करने से उसका वर्शन बना रहता है। बदली हुई मौजूदा एसेट को अलग वर्शन रखना होगा।
- क्रिएशन हिस्ट्री भी मर्ज होती है। जो क्रिएशन दोनों तरफ़ हो, वह हाल ही में सेव की गई कॉपी को वर्तमान के रूप में और दूसरी कॉपी को एक protected draft के रूप में रखती है; जो क्रिएशन जिस स्लॉट का इस्तेमाल लक्ष्य किसी दूसरी क्रिएशन के लिए करता है, वह उसके बगल में जोड़ दी जाती है; लक्ष्य के Trash में मौजूद क्रिएशन वहीं रहती है। कोई checkpoint id जो लक्ष्य पर अलग कॉन्टेंट का नाम रखती है, वह लक्ष्य की कॉपी बनाए रखती है। जो आर्काइव अपनी ही जाँच में विफल हो जाता है, वह किसी भी प्रोफ़ाइल, सेशन, एसेट या प्राथमिकता बदलाव से पहले ही इम्पोर्ट रोक देता है। एक जैसा दोबारा इम्पोर्ट कोई स्टोरेज नहीं जोड़ता।
- जो बंडल में नहीं था उसे छुआ नहीं जाता। जो सेशन लक्ष्य के पास था लेकिन बंडल में नहीं था, वह इम्पोर्ट के बाद भी बचा रहता है।
सेव किए गए सेशन अपने-आप अपनी इमेज से फिर से जुड़ जाते हैं: एसेट संदर्भ id से रखे जाते हैं, और अपलोड की गई इमेज रीस्टोर होने के बाद ब्रिज उन्हें फिर से हल करता है (इसे वैसे भी करना ही होता है, क्योंकि blob: URLs रीलोड में नहीं बचते)।
इम्पोर्ट सारांश { profile, sessions, userAssets, prefs, skipped, failedAssets } रिपोर्ट करता है। failedAssets उन अपलोड की गई एसेट्स की गिनती करता है जिन्हें रीस्टोर नहीं किया जा सका (जैसे डिवाइस स्टोरेज भरा होना)। यह skipped से अलग है, जो एक फ़ॉरवर्ड-संगत नए लेखक के उन भागों की गिनती करता है जिन्हें इस बिल्ड ने नहीं पहचाना। UI skipped को सामने लाता है ("… · N newer items skipped"), ताकि रीस्टोर इस बारे में ईमानदार रहे कि उसने क्या पीछे छोड़ा।
जब फ़ाइल हिस्ट्री मौजूद हो, तो सारांश assetVersions, fileOperations और failedHistory भी ले जाता है। स्टोरेज खत्म होना या अपरिवर्तनीय-ID टकराव आंशिक रीस्टोर का कारण बन सकते हैं; UI उपयोगकर्ता को सोर्स बैकअप रखने के लिए कहता है। आंशिक या असमर्थित रीस्टोर के बाद Cloud sync अपना लागू किया गया रिविज़न आगे नहीं बढ़ाता, इसलिए स्नैपशॉट फिर से कोशिश करने के लिए उपलब्ध रहता है। रीस्टोर सभी प्रोफ़ाइल/सेशन/एसेट/हिस्ट्री स्टोर में एक इकलौता ट्रांज़ैक्शन नहीं है।
क्रिएशन हिस्ट्री (v3)
एक हिस्ट्री-सक्षम वेब होस्ट से मैनुअल बैकअप में अपना { version: 1, documents, revisions, recoveries } स्कीमा रखने वाला revision-history.json शामिल होता है। यह रखी गई ID, कैनॉनिकल इनपुट स्नैपशॉट, वर्शन स्टैम्प, रास्टर प्रीव्यू और अलग राइटर ड्राफ़्ट साथ ले जाता है। हिस्ट्री अडैप्टर मौजूदा सेशन और उनके हेड्स को एक ही रीड ट्रांज़ैक्शन में कैप्चर करता है; sessions.json पुराने रीडर के लिए वही मौजूदा स्नैपशॉट इस्तेमाल करता है।
रीस्टोर आर्काइव को एक ट्रांज़ैक्शन में कमिट करने से पहले पेलोड SHA-256 और बाइट काउंट, यूनीक पहचान, दस्तावेज़/हेड संबंध, वंशावली, टाइमस्टैंप, प्रीव्यू प्रकार और सीमाएँ जाँचता है। कॉम्पैक्ट किए गए पैरेंट संदर्भ अनुपस्थित हो सकते हैं। मौजूदा वर्तमान काम कभी चुपचाप नहीं बदला जाता: जब कोई क्रिएशन दोनों तरफ़ हो, तो जो पक्ष वर्तमान के रूप में नहीं रखा जाता वह एक protected draft बन जाता है। आर्काइव की 384 MiB ट्रांसफ़र सीमा स्पष्ट रूप से जाँची जाती है, और स्टोरेज सीमाओं को रखे गए चेकपॉइंट को काटे बिना लागू किया जाता है। पूरा बैकअप अब भी एक इन-मेमोरी ZIP कार्यान्वयन इस्तेमाल करता है और यह कोई स्ट्रीमिंग आर्काइव नहीं है।
सारांश में revisions और recoveryDrafts जुड़ जाते हैं, जो सिर्फ़ यह गिनते हैं कि इस इम्पोर्ट ने क्या जोड़ा, और added, kept, replaced, copies व hidden यह बताने के लिए कि हर क्रिएशन कैसे मर्ज हुई। इस क्षमता के बिना एक शेल सामान्य सेशन रीस्टोर करता है और हिस्ट्री भाग को छूटा हुआ रिपोर्ट करता है। नेटिव फ़ाइलसिस्टम हिस्ट्री तब तक असमर्थित रहती है जब तक इसका अडैप्टर टिकाऊ हिस्ट्री ट्रांज़ैक्शन नहीं देता। P2P गेस्ट स्टेट के पास कोई टिकाऊ हिस्ट्री या रिकवरी आर्काइव नहीं है।
व्यक्तिगत स्नैपशॉट सिंक क्रिएशन हिस्ट्री को स्पष्ट रूप से बाहर रखता है। किसी हिस्ट्री रखने वाले लोकल दस्तावेज़ पर स्नैपशॉट लागू करना उसकी पिछली कार्यकारी स्थिति को एक अलग रिकवरी ड्राफ़्ट के रूप में सुरक्षित रखता है और किसी भी खुले एडिटर का राइट टोकन अमान्य कर देता है। इसके अपरिवर्तनीय चेकपॉइंट डिवाइस पर बने रहते हैं। यह स्नैपशॉट बदलने के दौरान लोकल हिस्ट्री की रक्षा करता है; यह समवर्ती डिवाइस हिस्ट्री को मर्ज नहीं करता।
पुराने एसेट संदर्भ बनाए रखे जाते हैं, जबकि रेंडरिंग अब भी एसेट को लक्ष्य की मौजूदा लाइब्रेरी के ज़रिए हल करती है। यह आर्काइव अभी तक असली पुराने एसेट बाइट्स या पुराने टूल रेंडर की गारंटी नहीं देता। एसेट-वर्शन और फ़ाइल-रिज़ल्ट बाइट्स अपने मौजूदा अलग बैकअप भाग के ज़रिए यात्रा करना जारी रखते हैं।
सेव किए गए वर्शन और फ़ाइल परिणाम (v2)
वैकल्पिक हिस्ट्री भाग में { version: 2, assetVersions: [...], operations: [...], batches: [...] } होता है; रीडर बिना बैच वाले पुराने history-v1 आकार को भी स्वीकार करते हैं। हर स्नैपशॉट स्थायी एसेट ID और असली वर्शन, उसका सेव समय, बाइट लंबाई और हेक्स SHA-256, साथ ही एक एसेट रिकॉर्ड पहचानता है जिसका _file और वैकल्पिक _credentialFile बाइनरी भागों की ओर इशारा करता है। ऑपरेशन मूल फ़ाइल फ़ैक्ट्स, रिक्वेस्ट, रिपोर्ट, टाइमस्टैंप और वैकल्पिक रिज़ल्ट _file ले जाते हैं; स्टोरेज बैकएंड नाम, OPFS हैंडल और एग्ज़िक्यूशन लीज़ यात्रा नहीं करते। पुराने केवल-history-v1 रीडर इम्पोर्ट करने से पहले नए हिस्ट्री वर्शन को अस्वीकार करते हैं, चुपचाप बैच सदस्यता गिराने के बजाय।
बैच मैनिफ़ेस्ट प्रोसेसिंग से पहले हर चुने गए सोर्स को रिकॉर्ड करते हैं, जिनमें कभी न पढ़ी गई फ़ाइलें, रद्द किए गए सदस्य, रिज़ल्ट स्पेस रिज़र्व करने में विफलता और बाधित काम शामिल हैं। हर सदस्य के पास एक स्थायी ऑपरेशन ID, सोर्स संदर्भ/फ़ैक्ट्स, माँगा गया आउटपुट नाम और टर्मिनल रिपोर्ट होती है। एक न पढ़ी गई सोर्स के पास घोषित फ़ैक्ट्स होते हैं, कोई मनगढ़ंत डाइजेस्ट नहीं। इम्पोर्ट सदस्य की पहचान और किसी भी ले जाई गई ऑपरेशन रिपोर्ट के साथ स्थिरता जाँचता है। बैच रिपोर्ट तब भी उपलब्ध रहती हैं जब अलग-अलग रिज़ल्ट को स्पष्ट रूप से हटा दिया गया हो, लेकिन एक रसीद का मतलब यह नहीं कि उसके आउटपुट बाइट्स अब भी संग्रहीत हैं।
- प्रोफ़ाइल या एसेट इम्पोर्ट के किसी भी राइट से पहले हर ज्ञात हिस्ट्री रिकॉर्ड, रिपोर्ट और संदर्भित फ़ाइल जाँची जाती है। गायब बाइट्स और बेमेल SHA-256 विफल हो जाते हैं भले ही एनवेलप में कोई इंटीग्रिटी मैप न हो। निकाले गए क्रेडेंशियल बाइट ऐरे बने रहते हैं, उन पुराने राइटर से इम्पोर्ट सहित जिन्होंने उन्हें न्यूमेरिक-key ऑब्जेक्ट के रूप में JSON-सीरियलाइज़ किया था।
- चल रहे ऑपरेशन बैकअप में बाधित रिकॉर्ड बन जाते हैं, एक स्पष्ट विफलता रिपोर्ट के साथ और कोई रिज़ल्ट नहीं। रीस्टोर करना कभी बैकग्राउंड काम फिर से शुरू नहीं करता या कोई सक्रिय लीज़ इम्पोर्ट नहीं करता। दोबारा कोशिश करने के लिए मूल फ़ाइल चुननी होती है, उपलब्ध होने पर उसके रिकॉर्ड किए गए SHA-256 के विरुद्ध जाँची जाती है।
- रीस्टोर किए गए रिज़ल्ट अपने बाइट्स और मेटाडेटा को IndexedDB में एक साथ कमिट करते हैं। सामान्य नए रिज़ल्ट उपलब्ध होने पर OPFS इस्तेमाल करते हैं, IndexedDB फ़ॉलबैक के साथ। कोई मौजूदा लाइव ऑपरेशन कभी किसी इम्पोर्ट से बदला नहीं जाता।
- हिस्ट्री ZIP असेंबली अब भी मेमोरी में होती है: मौजूदा सीमा है 256 MiB हिस्ट्री पेलोड, 4 MiB हिस्ट्री मेटाडेटा, अधिकतम 100 ऑपरेशन, 100 बैच और 2,000 स्नैपशॉट। एक्सपोर्ट बहुत बड़ी या अधूरी हिस्ट्री को स्पष्ट रूप से अस्वीकार करता है; यह कभी चुपचाप इसे छोड़ता नहीं। पुरानी लोकल कॉपी हटाने से पहले महत्वपूर्ण वर्शन/रिज़ल्ट अलग-अलग डाउनलोड करें। ये सीमाएँ फ़ोन के लिए मापी गई पीक-मेमोरी गारंटी नहीं हैं।
- लोकल रिज़ल्ट हिस्ट्री का बजट 512 MiB और 100-रिकॉर्ड कैप है। एसेट स्नैपशॉट का अलग 512 MiB बजट है और प्रति एसेट अधिकतम 20 पुराने वर्शन; निकाले गए क्रेडेंशियल बाइट्स उस स्नैपशॉट बजट में गिनते हैं। रीस्टोर इन सीमाओं का पालन करता है और कभी मौजूदा यूज़र डेटा को चुपचाप नहीं हटाता।
- लोकल बैच मेटाडेटा का अलग 4 MiB बजट है, अधिकतम 100 मैनिफ़ेस्ट और प्रति बैच 20 सदस्य। पेंडिंग सदस्य मेटाडेटा क्षमता रिज़र्व करते हैं, प्रति-सदस्य 32 KiB रिपोर्ट सीमा के साथ। यह एक लॉजिकल बजट है, ब्राउज़र डिस्क-स्पेस गारंटी नहीं; एक असली कोटा विफलता सामने लाई जाती है और इन-मेमोरी रिपोर्ट डाउनलोड करने योग्य रहती है। किसी बैच सदस्य को दोबारा कोशिश करना पुरानी रिपोर्ट को ओवरराइट किए बिना एक नया बैच बनाता है। किसी बैच रिकॉर्ड को हटाने से अलग-अलग रिज़ल्ट बाइट्स या लाइब्रेरी एसेट नहीं हटते।
- कन्वर्ट किए गए रिज़ल्ट को नॉर्मलाइज़ेशन या फिर से एन्कोड किए बिना स्पष्ट रूप से लाइब्रेरी में जोड़ा जा सकता है। सोर्स/आउटपुट हैश और ऑपरेशन संबंध एसेट के साथ जाते हैं। दोबारा जोड़ना एक अपरिवर्तित कॉपी दोबारा इस्तेमाल करता है; एक एडिट की गई कॉपी कभी ओवरराइट नहीं होती। रास्टर इमेज एक नया Design दस्तावेज़ शुरू कर सकती हैं। वह दस्तावेज़ मौजूदा लाइब्रेरी एसेट ID इस्तेमाल करता है: Design के रनटाइम और URL पथ में सटीक वर्शन पिन लागू करना अभी अलग काम है। SVG/HTML/PDF/ZIP रिज़ल्ट इस हैंडऑफ़ द्वारा ओपेक फ़ाइल एसेट के रूप में रखे जाते हैं, भरोसेमंद इंटरैक्टिव/वेक्टर कंटेंट के रूप में प्रोमोट नहीं किए जाते।
- Convert → Recent file operations हिस्ट्री उपयोग, रिपोर्ट, डाउनलोड और वर्शन मैनेजर दिखाता है। मैनेजर डिलीट की गई लाइब्रेरी एसेट के पुराने वर्शन भी ढूँढ लेता है। किसी स्नैपशॉट को रीस्टोर करना एक नया मौजूदा वर्शन बनाता है जबकि चुना गया स्नैपशॉट बरकरार रहता है। सेटिंग्स → स्टोरेज रिज़ल्ट और वर्शन को डिस्पोज़ेबल कैश से अलग गिनता है।
- स्पष्ट टेम्परेरी-फ़ाइल क्लीनअप केवल ऑपरेशन-स्वामित्व वाले, असंदर्भित बाइट्स हटाता है। मौजूदा रिकॉर्ड अपनी फ़ाइलों की सुरक्षा करते हैं; हाल के OPFS फ़ाइलों के लिए एक घंटे की ग्रेस अवधि है। सेव किए गए रिज़ल्ट और एसेट स्नैपशॉट अपने आप साफ़ नहीं होते।
पुराने रीडर अब भी v2 एनवेलप (minReader: 1) स्वीकार करते हैं और परिचित भाग रीस्टोर करते हैं, असमर्थित हिस्ट्री भाग को छूटा हुआ गिनते हैं। पूरी हिस्ट्री रिकवरी के लिए fileHistory अडैप्टर वाला शेल चाहिए; यह एक शेल-आंतरिक सीम है, कोई नई टूल-फ़ेसिंग HostV1 क्षमता नहीं। असली टू-डिवाइस रीस्टोर लोकल Chromium गेट से कवर होता है; इंस्टॉल किए गए Tauri/iOS/Android रिकवरी की स्वीकृति अलग बनी रहती है।
क्या यात्रा नहीं करता
- कैटलॉग कैश (डाउनलोड की गई एसेट मेटाडेटा और ब्लॉब्स, टूल इंडेक्स) - लक्ष्य पर मुफ़्त में फिर से सिंक हो जाते हैं।
- कैटलॉग टूल और कैटलॉग एसेट्स - दायरे से बाहर, और माना जाता है कि लक्ष्य पर पहले से मौजूद हैं। उपयोगकर्ता के जोड़े गए ब्रांड टोकन, फ़ॉन्ट और लोगो यूज़र एसेट हैं, इसलिए वे यात्रा करते हैं।
blob:/ ऑब्जेक्ट URLs - लोड पर ब्रिज द्वारा फिर से बनाए जाते हैं।- कन्वर्ज़न ओरिजिनल, लाइव एग्ज़िक्यूशन लीज़ और मशीन-लोकल एक्सेस/साइनिंग सीक्रेट - पोर्टेबल हिस्ट्री पेलोड नहीं हैं। एक सेव किया गया रिज़ल्ट एक कॉपी है, यह वादा नहीं कि मूल सोर्स का बैकअप लिया गया था।
- एक्सपोर्ट सीक्वेंस काउंटर - प्रति-दिन डाउनलोड-नामकरण काउंटर (
localStorageकुंजीlolly-export-seq) एक स्थानीय नामकरण सुविधा है। इसेPREF_KEYSसे बाहर रखा जाता है, इसलिए यह कभी किसी बंडल में सवार नहीं होता।
स्टोरेज मीटर उसी विभाजन को वस्तुओं में बाँटता है। सेव किए गए सेशन, My images और फ़ाइल रिज़ल्ट व वर्शन एक बंडल में सवार होते हैं। एसेट कैश, टूल प्रीव्यू और नीचे के ऑफ़लाइन पिन सभी फिर से व्युत्पन्न किए जा सकते हैं, इसलिए वे पीछे रह जाते हैं।
signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBखुद जाँचेंसाइन की हुई फ़ाइल पाएँ
signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBखुद जाँचेंसाइन की हुई फ़ाइल पाएँ
क्रॉस-शेल गारंटी
data-transfer.ts केवल कैपेबिलिटी ब्रिज (host.profile, host.state, host.assets) और साझा localStorage प्रेफ़्स के माध्यम से पढ़ता और लिखता है। यही मॉड्यूल वेब और Tauri पर सामान्य एनवेलप को पढ़ता और लिखता है, IndexedDB या फ़ाइलसिस्टम स्टोरेज पर। वैकल्पिक हिस्ट्री भाग केवल वहीं दिखते हैं जहाँ संगत अडैप्टर उपलब्ध हो; इम्पोर्ट पर एक असमर्थित भाग को छूटा हुआ रिपोर्ट किया जाता है। हेडलेस सूट सामान्य भागों को एक इन-मेमोरी ब्रिज के विरुद्ध चलाता है, जबकि हिस्ट्री ट्रांज़ैक्शन के लिए असली-ब्राउज़र टेस्ट भी हैं।
दो शेल उस गारंटी से बाहर हैं, अलग-अलग वजहों से:
- वन-शॉट CLI के पास ले जाने के लिए कुछ नहीं होता - इसकी स्थिति हर बार इन्वोकेशन में इन-मेमोरी और अस्थायी होती है।
- TUI स्थिति को बनाए रखता है (
~/.lolly: सेशन, फ़ोल्डर, प्रोफ़ाइल) और इसका Profile व्यू इसका बैकअप ले सकता है, लेकिन यह अपना एक सरल आर्काइव लिखता है: हर सेशन के लिएsaved-state/<slot>.jsonके साथprofile.jsonऔरfolders.json, बिना किसी मेनिफ़ेस्ट, बिनाformatVersion/minReaderऔर बिना इंटीग्रिटी मैप के। यह इस फ़ॉर्मैट द्वारा इम्पोर्ट योग्य नहीं है - एक रीडर इसे "not a Lolly backup" कहकर अस्वीकार करता है - और भ्रामक रूप से यह मिलता-जुलता नाम इस्तेमाल करता है (lolly-backup-<stamp>.zip)। दोनों को एकीकृत करना एक ज्ञात कमी है।
सुरक्षित एक्सटेंशन पॉइंट
एनवेलप जानबूझकर एक मेनिफ़ेस्ट और नामित भागों का एक सेट है, ताकि नए तरह का पोर्टेबल डेटा बाद में बिना किसी ब्रेकिंग बदलाव के इस पर सवार हो सके। ये अतिरिक्त भागों के रूप में शामिल होते हैं (नया formatVersion, वही minReader), और आज का रीडर जो नहीं पहचानता उसे छोड़ देता है। ये अभी तक नहीं बनाए गए हैं। नाम यहाँ सुरक्षित रखे गए हैं ताकि जब ये आएँ तो फ़ॉर्मैट सुसंगत बना रहे।
tokens.json- डिज़ाइन टोकन। एक W3C DTCG डिज़ाइन-टोकन दस्तावेज़ (वह फ़ॉर्मैट जिसे Penpot इम्पोर्ट और एक्सपोर्ट करता है -$value/$type/$descriptionवाले टोकन, समूहों, सेट और थीम में व्यवस्थित)। बंडल में एक टोकन सेट उपयोगकर्ता को अपने ब्रैंड प्रिमिटिव्स को अपने सेशन के साथ इंस्टॉल के बीच ले जाने देता है। (उपयोगकर्ता के अपने ब्रांड टोकन आज भीassets.jsonमेंuser/tokens/brandएसेट के रूप में यात्रा करते हैं; यह भाग अपने सेट और थीम के साथ एक पूरा DTCG दस्तावेज़ ले जाएगा।) लंबी अवधि में, इंजेस्ट किया गया टोकन सेट एक फ़र्स्ट-क्लास स्रोत बन जाता है जिसके विरुद्ध टूल और पैलेट एसेट रिज़ॉल्व होते हैं।penpot/- इंजेस्ट किए गए Penpot फ़ाइलें। एक Penpot फ़ाइल (या उसके निकाले गए, Lolly-प्रासंगिक सबसेट) के लिए एक सुरक्षित डायरेक्टरी जो इम्पोर्ट होकर एक टूल के रूप में सामने आती है। बंडल इंजेस्ट की गई परिभाषा को साथ ले जाएगा, ताकि यह उपयोगकर्ता के बाक़ी डेटा के साथ यात्रा करे।
इन सुरक्षित नामों और ऊपर दिए गए भागों के अलावा कुछ भी रीडर के लिए एक अज्ञात भाग है: बिना छेड़े छोड़ दिया जाता है और skipped में गिना जाता है।
संदर्भ
- मॉड्यूल:
shells/web/src/data-transfer.ts(exportBackup,importBackup,BACKUP_FORMAT,BACKUP_FORMAT_VERSION,BACKUP_READER_VERSION-backupFilename()नामकर्ता आंतरिक है)। - कॉन्ट्रैक्ट टेस्ट:
tests/data-transfer.test.ts- राउंड-ट्रिप, मर्ज, इंटीग्रिटी, फ़ॉरवर्ड-कम्पैट और रीडर-गेट केस। - हिस्ट्री कॉन्ट्रैक्ट टेस्ट:
tests/file-history-backup.test.ts,tests/file-batch-history.test.tsऔरtests/file-result-library.test.ts। ब्राउज़र स्वीकृति:tests/file-history.browser.test.ts,tests/file-batch-history.browser.test.tsऔरtests/file-result-reuse.browser.test.ts। - इस्तेमाल की गई ब्रिज सतह:
host.profile,host.state,host.assets- देखें Host API।