रिएक्टिव HTML नोटबुक
(maxbo.me)- केवल एक HTML फ़ाइल जिसे ब्राउज़र चलाता है, उसके ज़रिए डेटा exploration, analysis, visualization, typesetting और distribution को एक ही दस्तावेज़ में बाँधा जा सकता है, जिससे पारंपरिक notebook → publishing tool → PDF फ़्लो छोटा हो जाता है
- मुख्य implementation में स्क्रीन पर
styleऔरscriptको दिखाने वाले echo cells,contenteditable, और Observable Runtime को मिलाकर editable reactive cells बनाए जाते हैं cell(name, inputs, definition)Observable के dependency model का अनुसरण करते हुएcounter, FizzBuzz rendering, hidden cells, और output-रहित intermediate value cells जैसे आपस में जुड़े execution units बनाता है- उसी HTML दस्तावेज़ के भीतर Observable Plot, TeX, Markdown, Graphviz, WASM-आधारित SQLite, Pyodide-आधारित Python, WebR-आधारित R, Observable Inputs, और Mutable state तक का डेमो दिया गया है
- परिणाम एक ऐसा scientific और technical document है जो बिना किसी अलग platform के ब्राउज़र में चलता है, और implementation बाद में
@celine/celineलाइब्रेरी के रूप में जारी की गई
एक HTML फ़ाइल से notebook-publishing अलगाव कम करना
- HTML typesetting के लिए व्यापक रूप से इस्तेमाल होता है, लेकिन data exploration, analysis, और visualization platform के रूप में इसका उपयोग तुलनात्मक रूप से कम हुआ है
- सामान्य workflow कई tools से होकर गुजरता है
- अगर एक HTML फ़ाइल ये तीनों चरण संभाल ले, तो manual steps, CLI tools, CI stages, और third-party platform dependency कम की जा सकती है
- implementation पर Anton Zhiyanov के In-browser code playgrounds, Cristóbal Sciutto के Self-modifying HTML notes, Quarto, और Observable Framework का गहरा प्रभाव है
editable cells बनाना
- पहला चरण
echoCSS class के ज़रिएstyleऔरscriptelements को दस्तावेज़ के भीतर जैसा है वैसा दिखाना है - built-in syntax highlighting वाला font और
contenteditableattribute जोड़ने पर इसे एक बुनियादी code editor की तरह इस्तेमाल किया जा सकता है contenteditableलागू किए गएscriptको focus खोने पर फिर से evaluate किया जाता है- मौजूदा
scriptको copy करके नयाscriptelement बनाया जाता है और मूल element हटा दिया जाता है evalमेंimportstatements वाला code काम नहीं करता, इसलिए यह तरीका ज़रूरी है
- मौजूदा
- Observable-आधारित execution के लिए दो libraries लोड की जाती हैं
- global scope में केवल
libraryऔरcellये दो symbols expose किए जाते हैं
Observable Runtime-आधारित reactive data flow
cell(name, inputs, definition, observerVisibility)फ़ंक्शन Observable Runtime के module scope का उपयोग करके cells define करता है- अगर उसी नाम का variable पहले से हो, तो मौजूदा variable लिया जाता है; नहीं हो तो नया variable बनाकर define किया जाता है
- इस संरचना की वजह से
contenteditablecell को दोबारा evaluate करने पर नई definition connected cells तक propagate हो जाती है
- इस संरचना की वजह से
- Observable
Inspectorका उपयोग cell output कोscriptblock के ऊपर दिखाने के लिए किया जाता है countercell को एक asynchronous generator के रूप में बनाया गया है जो हर 1 सेकंड में एक संख्या emit करता हैscriptकाidattribute औरcellकाnameargument समान हैं- शुरुआती मान
iबदलकर focus हटाने पर नया मान लागू हो जाता है
counterपर निर्भर cells भी बनाए जा सकते हैं- Hypertext Literal लोड करके
countervalue को FizzBuzz रूप में render किया जाता है htlHTML5 parser implement करता है और automatic escaping, event listeners, style objects, और DOM nodes जैसे non-serializable values की interpolation संभालता है
- Hypertext Literal लोड करके
visible cells, hidden cells, और output-रहित cells
echoclass न जोड़ने पर cell definition छिपी रहती है, लेकिन output observe किया जा सकता है- ऐसे cells को rendering primitive की तरह इस्तेमाल किया जा सकता है
- ऐसा cell type भी बनाया जा सकता है जो output को दिखाए ही नहीं
silent(name, inputs, definition)मेंobserverVisibilityको hidden पर सेट किया जाता है, जिससे इसे intermediate values या data structures store करने के लिए उपयोग किया जा सके
- cells declaration order से स्वतंत्र होकर काम कर सकते हैं
- उदाहरण में
reallyNegativecell बाद में declare किए गएnegativecell पर निर्भर है
- उदाहरण में
- वही cell values अधिक जटिल outputs में भी उपयोग की जा सकती हैं
- Observable Plot लोड करके संख्याओं की array का line graph बनाया जाता है, और
counter % 40स्थिति पर vertical rule line दिखाई जाती है
- Observable Plot लोड करके संख्याओं की array का line graph बनाया जाता है, और
document और visualization output का विस्तार
- cells किसी भी DOM element को return कर सकते हैं
- TeX, Markdown, और Graphviz demos अलग-अलग प्रकार के elements return करते हैं
texcellspanelement return करता हैmdcelltableelement return करता हैdotcellsvgelement return करता है
- cells
Promisereturn कर सकते हैं याErrorthrow कर सकते हैं- Observable
Inspectorrunning cell के बाहरीdivपरobservablehq--runningclass लगाता है - error cell पर
observablehq--errorclass लागू होती है - दस्तावेज़ इन states के अनुरूप styling देता है
- Observable
ब्राउज़र के अंदर SQLite, Python, और R
- SQLite demo में Chinook sample database को
https://maxbo.me/chinook.dbपर होस्ट किया गया है और WASM-आधारित SQLite client से query किया जाता है- SQL query में
WHERE Milliseconds < 1000000जोड़कर देखा जा सकता है
- SQL query में
- Python demo में Pyodide CPython WASM distribution का उपयोग होता है
- Pyodide में NumPy, Pandas, Matplotlib, scikit-learn, Scipy शामिल हैं
- पहले बनाया गया plot, Matplotlib और Python
sqlite3module से फिर बनाया जाता है
- R demo में WebR का उपयोग होता है
inputs और mutable state
viewofcell type को Observable Inputs के साथ उपयोग के लिए बनाया गया हैviewofदो reactive cells declare करता हैNAME: input की valueviewof NAME: DOM element स्वयं
- input को cell के ऊपर दिखाने के लिए cell
idकोviewof NAMEपर सेट करना होता है - उदाहरण में
Inputs.range([0, 100], { step: 1 })से range input बनाया गया है, औरrangePlotcell उसी value के अनुसार update होता है - Observable Inputs की कार्यप्रणाली कुछ जटिल है, और Synchronized Inputs demo मददगार हो सकता है
- जहाँ शुद्ध functional data flow पर्याप्त नहीं होता, वहाँ
mutablehelper भी बनाया गया हैmutableऐसाMutableobject register करता है जो value बदलने पर नई value emit करता है
लाइब्रेरी रिलीज़ और presentation slides
- इस implementation के लिए शुरू में
incelनाम सोचा गया था, लेकिन बाद में इसेcelineकहा गया - लाइब्रेरी @celine/celine के रूप में जारी की गई
- इस दस्तावेज़ का डेमो SydJS में दिया गया
- दस्तावेज़ को slideshow में बदलने वाला code भी शामिल है
Shift+N: slideshow शुरू करें या अगली slide पर जाएँShift+B: पिछली slideShift+E: slideshow समाप्त करें
- implementation source source code के रूप में उपलब्ध है
1 टिप्पणियां
Hacker News की राय
लेख की बुनियादी धारणा से मैं दृढ़ता से सहमत हूँ। HTML computational notebooks के लिए एक बेहतरीन आधार बन सकता है।
हालांकि यहाँ implementation choices मुझे पसंद नहीं आईं। dynamic और reactive HTML को इससे कहीं ज़्यादा declarative बनाया जा सकता है, और Observable शानदार है, लेकिन यह standard JavaScript से कुछ हद तक अलग चला जाता है।
मैंने Heximal नाम का एक reactive HTML system बनाना शुरू किया है, जिसमें आगे चलकर notebook support भी जोड़ने की योजना है। यह HTML templates और custom elements पर आधारित declarative system है, जिसके ऊपर TC39 Signals proposal पर आधारित expression/reactivity system रखा गया है।
https://github.com/elematic/heximal
यह HTMX, Tangle, Curvenote और Polymer के मिश्रण जैसा है, और अगर HTML शुरू से ही reactive होता तो शायद कुछ ऐसा ही दिखता। मुझे लगता है कि यह graphics editing और notebook use cases के लिए काफी अच्छी तरह फिट होगा।
इसलिए Observablehq में सामान्य JavaScript debugging expressions ठीक से काम करते हैं।
https://github.com/observablehq/parser
मुझे Observable runtime पसंद है, इसलिए मैंने एक decompiler भी बनाया है जो frontend source और compiled pure JS representation के बीच दोनों दिशाओं में conversion कर सकता है।
https://observablehq.com/@tomlarkworthy/observablejs-toolcha...
वाकई शानदार। खासकर Python और SQLite demo अच्छा लगा। वेब के जरिए edit loop (TTW) से शुरू करके उसे quine कहना दिलचस्प है, और बात सही भी है, लेकिन इसकी मुख्य कमजोरी persistence है।
TiddlyWiki भी असल में यही काम करता है, लेकिन काम save करना सिरदर्द है। क्योंकि कुछ भी persist करना हो तो आखिरकार अलग headless server process चाहिए होता है।
जब मैं कुछ ऐसा ही बनाना चाहता था[0], तो व्यक्तिगत रूप से मैंने persistence से शुरुआत की, और उसका मतलब स्वाभाविक रूप से files था। ऐसी plain text files जिन्हें programmers के editor में edit किया जा सके और file system के जरिए save/deploy किया जा सके। इससे browser के अंदर programmers वाला editor दोबारा implement करने की समस्या से बचा जा सकता है, जो आसान नहीं है।
इसके बजाय तेज़ server लिखने की समस्या आती है, लेकिन वह अपने-आप में काफी मजेदार समस्या भी है[1]। यहाँ default contenteditable sections का इस्तेमाल करके उस समस्या से बचा गया है, लेकिन persistence के बाद यही अगली बड़ी समस्या है।
embedded scripts के अंदर export न कर पाना भी उसी दीवार जैसा लगता है। global window object को गंदा किए बिना काम करना हो तो ऐसी सुविधा अच्छी होगी, और मेरे use case में code generation भी आसान हो जाएगा।
0 - Literate Markdown: https://simpatico.io/lit.md
1 - Reflector, markdown को transform, compress, cache करने और file watch invalidation करने वाला छोटा node server: https://simpatico.io/reflector
लगाए गए विचार और मेहनत का सम्मान है, लेकिन इस approach की usability बेहद खराब है। exploratory data analysis करते समय styling elements तक की चिंता क्यों करनी पड़े, समझ नहीं आता
Jupyter notebook जैसे tools के अच्छी तरह चलने की वजह यही है। फिर भी, जिज्ञासा के साथ वैकल्पिक ideas implement करने की बात की मैं काफी सराहना करता हूँ
exploratory data analysis platform के तौर पर यह अभी पर्याप्त नहीं है। इसमें Observable Notebooks जैसे पूर्ण web code editor की तुरंत responsiveness भी नहीं है, और न ही यह file-watching based hot reloading देने वाला Observable Framework है। Deno + VSCode के लिए नया Jupyter kernel भी काफी smooth experience देता है
इसलिए exploratory analysis के लिए usability… हाँ, खराब है, इससे सहमत हूँ, लेकिन deployment usability मुझे उतनी खराब नहीं लगती। सच कहूँ तो अच्छी है। क्योंकि यह बस एक single file है। किसी को graph और data processing के results भेजने के लिए बड़ा toolchain maintain करने या किसी third-party service को पैसे देने की जरूरत नहीं; बस एक HTML file Slack पर डाल दें या कहीं host कर दें
analysis results को style करने की flexibility की वजह से इसे blog या research paper जैसे उन environments में भी publish किया जा सकता है जहाँ style महत्वपूर्ण है
ivoryकोredमें बदलते ही syntax highlighting का real-time में बदलना यह दिखाता हैयहाँ तक पहुँचने की पृष्ठभूमि समझ आती है, लेकिन यह अफसोस की बात है कि JavaScript frameworks और libraries के साथ browser में आसानी से खेलना-प्रयोग करना संभव नहीं है। आखिर यह सिर्फ JS ही तो है, और किसी हल्के environment में तेजी से experiment कर पाना चाहिए। इस approach की यही strength है
यह HTML/JS की playful और experimental संभावनाओं को वापस लाने का तरीका है। TS, rollup, webpack जैसी चीजों से ज्यादा ऐसे प्रयास होते तो अच्छा होता
अतिरिक्त: थोड़ा और पढ़ने पर लगा कि इसे data analysis के लिए propose किया जा रहा है। उस use case के लिए यह ठीक fit नहीं बैठता, ऐसा लगता है
ऐसी Jupyter notebook alternative में बड़ी value है जो फेंक देने पर खत्म न हो जाए। अभी user experience वाकई बहुत खराब है, लेकिन उसे सुधारा जा सकता है। सवाल यह है कि क्या यह setup Jupyter notebook के JSON chaos से बेहतर है; निजी तौर पर मैं मानता हूँ कि हाँ
Lit के original author ने हाल ही में Google छोड़ा है, और मेरी जानकारी में वह इससे बहुत मिलती-जुलती चीज पर काम कर रहे हैं
https://github.com/elematic/heximal
इस लेख का format मुझे पसंद आया। यह बिल्कुल नीचे से शुरू करके कुछ दिलचस्प चीज तक build करता है। dependencies के ढेर या इधर-उधर frameworks जोड़ने वाली overhyped flow नहीं है
follow करने के लिए शायद दिए गए pieces copy-paste करके step by step समझना होगा कि वे कैसे काम करते हैं। अगर मैं ऐसा कुछ लिखता, तो शायद org-mode की literate programming में लिखकर HTML में export करता और blog post बनाता
हालांकि built-in syntax highlighting वाला font अभी भी मुझे संदिग्ध लगता है
reactive HTML कहा जा रहा है, लेकिन क्या यह लगभग पूरा JavaScript नहीं है, या मैं कुछ गलत समझ रहा हूँ?
browser को छोड़ दें तो यह third-party software पर निर्भर नहीं है, और HTML की तरह लंबे समय तक चलने वाली, portable और इस्तेमाल में आसान है
जल्द ही इस तरह की HTML notebook को Raku में, या Raku के लिए support करने की कोशिश करूँगा
अभी Raku का “notebook solution” Jupyter-based या Mathematica-based है
इस प्रक्रिया में web technologies इस्तेमाल करके इसे जटिल बनाने का तर्क मुझे समझ नहीं आता। जो अतिरिक्त जटिलता जोड़ी गई है, वह किस समस्या को हल करती है? उल्टा यह प्रक्रिया को धीमा बनाती है, और auto-complete, snippets, extensions जैसी जरूरी सुविधाओं को हटाने के करीब लगती है
ऊपर से, संभव है कि दूसरे लोग इस setup से परिचित न हों, इसलिए collaboration भी और मुश्किल हो जाता है
environment बस एक बार set कर दीजिए, और technology बदलने के साथ छोटे-छोटे सुधार जोड़ते हुए उसी का इस्तेमाल जारी रखिए
n/vim users के लिए इतना काफी हो सकता है। 1- Data exploration: https://github.com/untitled-ai/jupyter_ascending का इस्तेमाल करके text को Jupyter notebook से जोड़ें। यह jupytext इस्तेमाल करता है, इसलिए text editor में code को efficiently edit और run किया जा सकता है
2- Writing: LaTeX के लिए https://github.com/lervag/vimtex इस्तेमाल कर सकते हैं
इसके ऊपर tmux और tmuxp जोड़ दें तो project तुरंत खोला जा सकता है। Emacs में org mode[1][2] और/या Auctex से smooth process बनाई जा सकती है
[1] https://sqrtminusone.xyz/posts/2021-05-01-org-python/
[2] https://martibosch.github.io/jupyter-emacs-universe/
हालांकि मुझे Python खास पसंद नहीं है, इसलिए मैं Python-centric न होने वाले tools इस्तेमाल करना चाहता हूँ। इसी वजह से मैंने Raku और Mathematica की बात की थी
वैसे https://github.com/imbue-ai/jupyter_ascending बताने के लिए धन्यवाद
इस लेख की premise—यानी HTML का scientific writing के distribution medium के रूप में पर्याप्त उपयोग नहीं हो रहा है—से मैं काफी हद तक सहमत हूँ
इसी से जुड़ा Will Crichton का हालिया काम है
https://willcrichton.net/nota/
https://willcrichton.net/notes/portable-epubs/
आजकल notebooks काफी hot topic हैं। हमने भी TypeScript notebook का version release किया है[1], लेकिन trade-offs में हमने काफी अलग दिशा चुनी है
हम backend node code चलाना चाहते थे, इसलिए इस लेख के तरीके या Observable के उलट इसे browser environment में चलाने की कोशिश नहीं करते। फिर भी कई applications के लिए यह idea बेहतर solution हो सकता है
लेखक को सलाम
https://github.com/srcbookdev/srcbook