← بلاگ

الٹا آرکیٹیکچر

⁦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 spans⁩ پر مشتمل ہوتا ہے۔

فارمیٹ اسٹرنگ 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 فرنٹ اینڈ میں ناپی گئی تھیں۔