← ब्लॉग

उल्टा आर्किटेक्चर

React कमिट DevTools में एक console.log कॉल कैसे बनता है।

Adam

DOM फ़्रेमवर्क में कंपोनेंट DOM नोड बनते हैं, जिनका ब्राउज़र पेज में लेआउट बनाता है और उन्हें पेंट करता है। Text.js में कंपोनेंट सेल बनते हैं, और सेल का हर बदला हुआ फ़्रेम DevTools में एक console.log कॉल बनता है। हम इसे इनवर्टेड आर्किटेक्चर कहते हैं।

पाइपलाइन

React ─▶ reconciler ─▶ Yoga ─▶ CellBuffer ─▶ row-hash gate ─▶ RLE ─▶ console.log

हर चरण इसलिए है क्योंकि कंसोल एक असामान्य डिस्प्ले है। यह मोनोस्पेस और पंक्ति-आधारित है, इसे %c से स्टाइल किया जाता है, और DevTools तय करता है कि इसे कब दोबारा पेंट करना है।

रिकंसाइलर

@textjs/react एक React 19 रिकंसाइलर ([email protected]) है जिसमें दो होस्ट एलिमेंट, tx-box और tx-text, और स्ट्रिंग चिल्ड्रेन के लिए टेक्स्ट इंस्टेंस हैं। <Box> से <Markdown> तक, आप जो भी इंपोर्ट करते हैं, वह इन्हीं पर बना है। कमिट requestAnimationFrame पर शेड्यूल होते हैं, और की दबाने या पेस्ट करने पर उसी टास्क में सिंक्रोनस रेंडर होता है।

लेआउट

WebAssembly में कंपाइल किया गया Yoga, pointScaleFactor = 1 के साथ ट्री का लेआउट बनाता है, ताकि हर बॉक्स पूरे सेल पर आए। टेक्स्ट को Intl.Segmenter और पूर्वी एशियाई चौड़ाई टेबल से मापा जाता है, इसलिए 你好 चार सेल लेता है और 🚀 दो। अगर कोई बदलाव टेक्स्ट नोड का आकार नहीं बदल सकता, तो Yoga से दोबारा नहीं पूछा जाता।

CellBuffer

फ़्रेम एक बार एलोकेट किए गए टाइप्ड ऐरे का ग्रिड है: कैरेक्टर Uint32Array में, फ़ोरग्राउंड और बैकग्राउंड पैक किए हुए 0xRRGGBBAA के रूप में, एट्रिब्यूट Uint16Array बिटमास्क के रूप में। पेंटिंग इन ऐरे में लिखती है और ट्रैक करती है कि उसने किन पंक्तियों को छुआ।

गेट

हर पंक्ति का कैश किया हुआ 32-बिट FNV-1a हैश होता है। सिर्फ़ पिछली फ़्रेम के बाद लिखी गई पंक्तियों का हैश दोबारा बनता है। अगर कोई पंक्ति नहीं बदली, तो ड्राइवर स्ट्रिंग बनाने से पहले लौट जाता है और कोई कंसोल कॉल नहीं करता। छिपे हुए टैब में स्पिनर की कोई लागत नहीं होती क्योंकि वह टिक नहीं कर रहा होता।

रन-लेंथ एन्कोडिंग

बदली हुई पंक्तियों को दोबारा स्कैन करके समान स्टाइल वाले रन बनाए जाते हैं, और हर रन एक %c span बनता है। रन लाइन ब्रेक के पार भी जारी रहते हैं। CSS स्ट्रिंग को इंटीजर स्टाइल आईडी के पीछे इंटर्न किया जाता है, इसलिए हॉट पाथ कभी एक ही स्ट्रिंग दो बार नहीं बनाता। 100×32 के डैशबोर्ड में 3,200 सेल और 149 span होते हैं।

फ़ॉर्मैट स्ट्रिंग DevTools के दो व्यवहारों से भी बचाती है। लिटरल % को %% लिखा जाता है। :// के बाद, www. के अंदर और path:line में एक word joiner रखा जाता है, ताकि DevTools आपके टेक्स्ट को लिंक में बदलकर अपने रंगों में दोबारा पेंट न करे।

एक कॉल

हर बदला हुआ फ़्रेम एक ही कॉल है:

console.log("%c\u200b%c\n%c▼ OpenCode Lite%c …", "margin-top:100vh;", "", "color:#fafafa;…", …);

फ़्रेम जोड़े जाते हैं, DevTools के 50 ms थ्रॉटलर के हिसाब से उनकी गति तय होती है और एक ही पेंट में उन्हें स्वैप किया जाता है। Turbolog: फ़्लैश हटाना में उस हिस्से की जानकारी है।

इनपुट

कंसोल कीस्ट्रोक नहीं ले सकता, इसलिए पेज लेता है। एक छिपा हुआ <textarea> की, पेस्ट और IME कंपोज़िशन इकट्ठा करता है, और wheel इवेंट ScrollBox कंपोनेंट को स्क्रॉल करते हैं। textjs.org पर Playground और OpenCode पेज एक बड़े फ़ोकस पैड का काम करते हैं। कंसोल खोलें, फिर टाइप करने के लिए पेज पर क्लिक करें।

पेज को दिखने वाली जानकारी

पेज कंसोल का आकार नहीं पढ़ सकता, सिर्फ़ अपनी विंडो का पढ़ सकता है, इसलिए Text.js इसका अनुमान लगाता है: डॉक किया हुआ पैनल innerWidth या innerHeight को घटाता है जबकि outer* वैसा ही रहता है, और डॉक की हर संभावित स्थिति का हिसाब Chrome के ज़ूम स्तरों के लिए लगाया जाता है। जो सबसे सटीक बैठता है, उसे चुना जाता है। कॉन्स्टेंट (56 px की हॉरिज़ॉन्टल पैडिंग, कंसोल क्रोम के 104 px, पंक्तियों के बीच 14 px का अंतर) असली DevTools फ़्रंटएंड में मापे गए थे।