ایک Lolly صارف جو کچھ بھی جمع کرتا ہے وہ اس کے اپنے ڈیوائس پر رہتا ہے - کوئی اکاؤنٹ نہیں، کوئی کلاؤڈ نہیں۔ ڈیٹا-ٹرانسفر بنڈل وہ طریقہ ہے جس سے یہ قدر منتقل ہوتی ہے: اسے ایک انسٹال پر ایکسپورٹ کریں، فائل کو کسی بھی ذریعے (USB، AirDrop، خود کو ای میل، نیٹ ورک شیئر) سے لے جائیں اور اسے دوسرے پر امپورٹ کریں۔ فائل ہی ٹرانسپورٹ ہے۔ ٹارگٹ آف لائن یا آن لائن ہو سکتا ہے۔ کوئی فرق نہیں پڑتا، کیونکہ کبھی کوئی سرور سے بات نہیں ہوتی۔
signed by Lollyvector SVGخود جانچیںGet the signed file12 paths~5.1k nodes12 groups60 KB
signed by Lollyvector SVGخود جانچیںGet the signed file12 paths~5.1k nodes12 groups60 KB
یہ صفحہ فارمیٹ اسپیک ہے۔ اینڈ-یوزر واک تھرو کے لیے دیکھیں Using Lolly → Moving to another device۔ عملدرآمد shells/web/src/data-transfer.ts میں ہے، اور tests/data-transfer.test.ts راؤنڈ-ٹرپ کنٹریکٹ کو پن کرتا ہے۔
دائرہ کار۔ ایک بنڈل صارف کا ڈیٹا لے کر جاتا ہے، ٹولز نہیں۔ ٹولز اور کیٹلاگ اثاثے علیحدہ طور پر سنک ہوتے ہیں اور فرض کیا جاتا ہے کہ وہ ٹارگٹ پر پہلے سے موجود ہیں (بدترین صورت میں زیادہ ورژن پر)۔ امپورٹ کبھی کسی ٹول کو انسٹال یا اپ گریڈ نہیں کرتا۔
اہداف
- ایک فارمیٹ، ہر شیل۔ وہی بائٹس ویب PWA، Tauri ڈیسک ٹاپ/موبائل ایپس اور کسی بھی مستقبل کے شیل کے ذریعے تیار اور استعمال کیے جاتے ہیں۔ بنڈل ہی کنٹریکٹ ہے۔ ہر شیل کا کیپیبلٹی برج اس کے پیچھے فی-پلیٹ فارم اڈاپٹر ہے۔
- سفر میں محفوظ رہتا ہے۔ ٹرانزٹ میں خراب یا ٹرنکیٹ ہونے والا بنڈل امپورٹ پر واضح طور پر ناکام ہوتا ہے، کبھی آدھا بحال نہیں ہوتا۔
- اس ورژن سے آگے تک چلتا ہے۔ ایک پرانی ایپ اب بھی نئے بنڈل کے پہچانے جانے والے حصے امپورٹ کر سکتی ہے۔ حقیقی معنوں میں breaking فارمیٹ کو صاف طور پر مسترد کر دیا جاتا ہے۔
- مرج کے لیے محفوظ۔ پہلے سے استعمال میں موجود انسٹال پر امپورٹ کرنا کبھی اس چیز کو نہیں مٹاتا جو بنڈل میں نہیں تھی۔
لفافہ
ایک بنڈل ایک سادہ .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 ملتا ہے۔ ہر حصے کو فائل نام کے لیے محفوظ ٹوکن میں صاف کیا جاتا ہے (یونیکوڈ حروف/ہندسے برقرار، اسپیس/رموزاوقاف ہٹا دیے جاتے ہیں، زیادہ سے زیادہ 32 حروف)۔ <n> ایک فی-دن، فی-ڈیوائس ترتیب ہے، لہٰذا اسی دن دہرائے گئے ایکسپورٹس آپس میں نہیں ٹکراتے اور ترتیب میں رہتے ہیں۔ shells/web/src/data-transfer.ts میں backupFilename() نام بناتا ہے۔ زپ کا مواد نام سے قطع نظر ایک جیسا رہتا ہے۔ اندر:
| Path | لازمی | مواد |
|---|---|---|
manifest.json | ہاں | فارمیٹ id، ورژنز، شمار اور فی-حصہ انٹیگریٹی۔ ریڈر سب سے پہلے یہی دیکھتا ہے۔ |
profile.json | جب سیٹ ہو | صارف کا me ریکارڈ (نام، رابطہ، ہیڈ شاٹ ریفرنس، فلیگز)۔ host.profile کے ذریعے پڑھا جاتا ہے۔ |
sessions.json | ہاں | ہر محفوظ شدہ سیشن: سلاٹ، ٹول id/ورژن، لیبل، تھمب نیل (data-URL) اور مکمل ان پٹ ڈیٹا۔ host.state کے ذریعے پڑھا جاتا ہے۔ |
assets.json | ہاں | ہر اپ لوڈ شدہ اثاثے (تصاویر، فونٹس، برانڈ ٹوکنز) کا میٹا ڈیٹا، ہر ایک assets/blobs/ کے تحت اپنے بائٹس کی طرف اشارہ کرتا ہے۔ |
assets/blobs/<n>.<ext> | فی اثاثہ | خام اثاثہ بائٹس (تصویر اور فونٹ فائلیں)۔ بغیر کمپریشن کے محفوظ (پہلے سے کمپریسڈ فارمیٹس)۔ ایکسٹینشن محض ظاہری ہے۔ assets.json میں MIME مستند ہے۔ |
prefs.json | ہاں | صارف کی اپنی مقامی ترجیحات: theme، sidebarWidth اور ct-metrics سرگرمی شمار۔ |
lolly.txt | ہاں | بنڈل کا انسانی-پڑھنے کے قابل خلاصہ (شمار، پروفائل، فائل نام) ہر اس شخص کے لیے جو Lolly کے بغیر زپ کھولے۔ ہر ایکسپورٹ پر دوبارہ تیار ہوتا ہے اور امپورٹ پر پہچانا جاتا ہے، لہٰذا یہ کبھی چھوڑے گئے حصے میں شمار نہیں ہوتا۔ یہ انٹیگریٹی میپ کے بعد لکھا جاتا ہے، لہٰذا یہ اس سے باہر رہتا ہے۔ |
بنڈل جان بوجھ کر ایک سادہ زپ ہے: یہ کسی بھی ٹرانسپورٹ میں مکمل حالت میں بچ جاتا ہے، اور کوئی بھی ان زپ ٹول اس کا معائنہ کر سکتا ہے۔
profile.json سب سے چھوٹا حصہ ہے اور وہ ہے جسے ریڈر ایپ میں سب سے پہلے دیکھتا ہے: وہ تفصیلات جو تخلیق کار ایک بار پُر کرتا ہے، ساتھ ہی وہ آپٹ-ان جو ٹولز کو انہیں استعمال کرنے دیتا ہے۔
signed by Lollyvector SVGخود جانچیںGet the signed file18 paths~2.0k nodes41 groups30 KB
signed by Lollyvector SVGخود جانچیںGet 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-…"
}
}
| فیلڈ | معنی |
|---|---|
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پر گیٹ کرنے پر واپس چلے جاتے ہیں (تبدیلی کو breaking سمجھتے ہوئے)۔
مصنفین کے لیے عمومی اصول: اگر ہر موجودہ ریڈر آپ کے اضافے کو نظر انداز کر کے بھی درست کام کرے، تو یہ additive ہے -
formatVersionبڑھائیں،minReaderچھوڑ دیں۔ ورنہminReaderبڑھائیں۔
انٹیگریٹی
جب manifest.integrity موجود ہو، ایک ریڈر ہر درج شدہ حصے کا SHA-256 کچھ بھی لکھنے سے پہلے تصدیق کرتا ہے۔ کوئی عدم مطابقت ("failed its integrity check") یا غائب حصہ ("incomplete") پوری امپورٹ کو روک دیتا ہے - کوئی جزوی بحالی نہیں ہوتی۔ یہ اس خرابی کو پکڑتا ہے جو فائل ٹرانسپورٹ لا سکتا ہے (ایک ٹرنکیٹڈ AirDrop، ایک ای میل گیٹ وے جس نے اٹیچمنٹ کو دوبارہ انکوڈ کیا، ایک خراب USB سیکٹر)۔
انٹیگریٹی جان بوجھ کر best-effort ہے: یہ صرف وہاں لکھی جاتی ہے جہاں Web Crypto دستیاب ہو (ہر محفوظ براؤزر کانٹیکسٹ اور جدید Node)، اور صرف اسی صورت میں تصدیق کی جاتی ہے جب میپ اور Web Crypto دونوں موجود ہوں۔ میپ کے بغیر بنڈل - مثال کے طور پر انٹیگریٹی کے وجود میں آنے سے پہلے کا کوئی بنڈل - بلا تبدیلی امپورٹ ہوتا ہے۔ "Cannot verify" کو کبھی "corrupt" نہیں سمجھا جاتا۔
مینی فیسٹ نہ خود اپنی فہرست بناتا ہے اور نہ دوبارہ تیار کردہ lolly.txt README کی۔ ڈائجسٹس صرف انہی حصوں کا احاطہ کرتے ہیں جن کا مینی فیسٹ ضامن ہے۔
امپورٹ کی سیمنٹکس
امپورٹ merge-overwrite ہے، کبھی replace-all نہیں:
- ٹارگٹ پر موجودہ ڈیٹا اپنی جگہ چھوڑ دیا جاتا ہے۔
- کوئی بھی کلید جو ٹکراتی ہو - پروفائل، سیشن سلاٹ، اپ لوڈ شدہ تصویر کا id - امپورٹ شدہ نقل سے تبدیل کر دی جاتی ہے۔
- جو چیز بنڈل میں نہیں تھی اسے چھوا تک نہیں جاتا۔ وہ سیشن جو ٹارگٹ کے پاس تھا مگر بنڈل کے پاس نہیں تھا، امپورٹ کے بعد بھی موجود رہتا ہے۔
محفوظ شدہ سیشنز خودکار طور پر اپنی تصاویر سے دوبارہ منسلک ہو جاتے ہیں: اثاثے کے حوالے id کے ذریعے رکھے جاتے ہیں، اور اپ لوڈ شدہ تصاویر بحال ہونے کے بعد برج انہیں دوبارہ حل کرتا ہے (اسے بہرحال ایسا کرنا ہی ہے، کیونکہ blob: URLs ری لوڈ کے بعد باقی نہیں رہتے)۔
امپورٹ کا خلاصہ { profile, sessions, userAssets, prefs, skipped, failedAssets } رپورٹ کرتا ہے۔ failedAssets ان اپ لوڈ شدہ اثاثوں کو شمار کرتا ہے جنہیں بحال نہیں کیا جا سکا (مثلاً ڈیوائس اسٹوریج بھرا ہونا)۔ یہ skipped سے مختلف ہے، جو ایک فارورڈ-کمپیٹیبل نئے رائٹر کے ان حصوں کو شمار کرتا ہے جنہیں یہ بلڈ نہیں پہچان سکا۔ UI skipped ظاہر کرتا ہے ("… · N newer items skipped")، تاکہ بحالی اس بارے میں دیانتدار رہے کہ اس نے کیا پیچھے چھوڑا۔
کیا سفر نہیں کرتا
- کیٹلاگ کیشز (ڈاؤن لوڈ شدہ اثاثہ میٹا ڈیٹا اور بلابز، ٹول انڈیکس) - ٹارگٹ پر مفت میں دوبارہ سنک ہو جاتے ہیں۔
- ٹولز اور برانڈ اثاثے - دائرہ کار سے باہر، اور فرض کیا جاتا ہے کہ یہ ٹارگٹ پر پہلے سے موجود ہیں۔
blob:/ آبجیکٹ URLs - لوڈ کے وقت برج کے ذریعے دوبارہ تیار کیے جاتے ہیں۔- ایکسپورٹ سیکوئنس کاؤنٹر - فی-دن ڈاؤن لوڈ-نامنگ کاؤنٹر (
localStorageکلیدlolly-export-seq) ایک مقامی نامنگ سہولت ہے۔ اسےPREF_KEYSسے باہر رکھا جاتا ہے، لہٰذا یہ کبھی بنڈل میں شامل نہیں ہوتا۔
اسٹوریج میٹر اسی تقسیم کو تفصیل سے دکھاتا ہے۔ Saved sessions اور My images بنڈل میں شامل ہوتے ہیں۔ ان کے نیچے موجود اثاثہ کیش، ٹول پیش نظارے اور آف لائن پنز سب دوبارہ اخذ کیے جا سکتے ہیں، لہٰذا وہ پیچھے رہ جاتے ہیں۔
signed by Lollyvector SVGخود جانچیںGet the signed file25 paths~4.8k nodes46 groups59 KB
signed by Lollyvector SVGخود جانچیںGet the signed file25 paths~4.8k nodes46 groups59 KB
کراس-شیل ضمانت
data-transfer.ts صرف capability bridge (host.profile, host.state, host.assets) اور مشترکہ localStorage prefs کے ذریعے پڑھتا اور لکھتا ہے۔ چونکہ bridge ہی واحد seam ہے، اس لیے وہی ماڈیول ہر shell پر byte-identical bundle پیدا کرتا ہے، حالانکہ نیچے کا اسٹوریج مختلف ہوتا ہے - web پر IndexedDB، Tauri پر filesystem۔ Tauri shells اس ماڈیول کو بلا تبدیلی استعمال کرتے ہیں۔ صرف ان کا host.state نفاذ مختلف ہے۔ Headless ٹیسٹ ایک in-memory bridge کے خلاف مکمل round-trip چلاتا ہے، اسی لیے یہ ان سب کی نمائندگی کرتا ہے۔
دو shells اس ضمانت سے باہر ہیں، مختلف وجوہات کی بنا پر:
- one-shot CLI کے پاس لے جانے کو کچھ نہیں ہے - اس کی state ہر invocation کے لیے in-memory اور عارضی ہوتی ہے۔
- TUI state کو محفوظ ضرور کرتا ہے (
~/.lolly: sessions، folders، profile) اور اس کا Profile view اس کا بیک اپ لے سکتا ہے، لیکن یہ اپنا ایک سادہ archive لکھتا ہے: ہر session کے لیےsessions/<slot>.jsonنیزprofile.jsonاورfolders.json، بغیر کسی manifest کے، بغیرformatVersion/minReaderاور بغیر integrity map کے۔ یہ اس فارمیٹ کے ذریعے قابلِ import نہیں - reader اسے "not a Lolly backup" کہہ کر رد کر دیتا ہے - اور الجھن کی بات یہ ہے کہ یہ ملتا جلتا نام استعمال کرتا ہے (lolly-backup-<stamp>.zip)۔ دونوں کو یکجا کرنا ایک معلوم خلا ہے۔
محفوظ توسیعی پوائنٹس
envelope بذاتِ خود ایک manifest اور نامزد parts کا مجموعہ ہے، تاکہ نئی طرح کی portable data بعد میں بغیر کسی breaking change کے اس پر سوار ہو سکے۔ یہ additive parts کے طور پر شامل ہوں گے (نیا formatVersion، وہی minReader)، اور آج کا reader جو نہیں پہچانتا اسے چھوڑ دیتا ہے۔ یہ ابھی roadmap پر ہیں، نافذ نہیں ہوئے۔ نام یہاں محفوظ کیے گئے ہیں تاکہ جب یہ آئیں تو فارمیٹ مربوط رہے۔
tokens.json- design tokens۔ ایک W3C DTCG design-tokens دستاویز (وہ فارمیٹ جسے Penpot import اور export کرتا ہے -$value/$type/$descriptionوالے tokens، جو groups، sets اور themes میں منظم ہوں)۔ bundle میں موجود token set صارف کو اپنے brand primitives کو اپنی sessions کے ساتھ ایک انسٹال سے دوسرے میں منتقل کرنے دیتا ہے۔ طویل مدت میں، ایک ingest شدہ token set ایک first-class ماخذ بن جائے گا جس کے خلاف tools اور palette assets resolve ہوں گے۔penpot/- ingest شدہ Penpot فائلیں۔ ایک محفوظ directory ایک Penpot فائل (یا اس کے نکالے گئے، Lolly سے متعلقہ حصے) کے لیے جو ایک tool کے طور پر import اور ظاہر کی گئی ہو۔ bundle ingest شدہ definition کو لے کر چلے گا، تاکہ یہ صارف کے باقی ڈیٹا کے ساتھ سفر کرے۔
ان محفوظ ناموں اور اوپر دیے گئے parts کے علاوہ کچھ بھی reader کے نزدیک ایک نامعلوم part ہے: چھیڑا نہیں جاتا اور skipped میں شمار ہوتا ہے۔
حوالہ
- ماڈیول:
shells/web/src/data-transfer.ts(exportBackup،importBackup،BACKUP_FORMAT،BACKUP_FORMAT_VERSION،BACKUP_READER_VERSION-backupFilename()نام دینے والا اندرونی ہے)۔ - Contract ٹیسٹ:
tests/data-transfer.test.ts- round-trip، merge، integrity، forward-compat اور reader-gate کیسز۔ - استعمال شدہ Bridge سطح:
host.profile،host.state،host.assets- دیکھیے Host API۔