แนวคิดที่น่าสนใจใน Observable Framework
(simonwillison.net)- Observable Framework เป็นเครื่องมือโอเพนซอร์สที่ก้าวข้ามโมเดลโน้ตบุ๊กซึ่งถนัดการสำรวจข้อมูลแบบชั่วคราว ไปสู่การดีพลอยแอปข้อมูล แดชบอร์ด และรายงานที่โหลดเร็วในรูปแบบเว็บไซต์แบบสแตติก
- บล็อกโค้ด
jsและ inline expression ภายใน Markdown จะถูกรันในเบราว์เซอร์ และเมื่อ ค่าแบบ reactive อย่างnowเปลี่ยน การแสดงผลที่เกี่ยวข้องก็จะอัปเดตอัตโนมัติ - Framework ยังคงความเป็น reactive ของ Observable Notebooks เอาไว้ พร้อมกับมอบ ไฟล์ Markdown เดียว, JavaScript มาตรฐาน และ workflow ที่เป็นมิตรกับ Git
- ไลบรารีอย่าง
Inputs,d3,Plotจะถูกโหลดแบบ lazy ระหว่างพัฒนา และตอน build/deploy จะโหลดเฉพาะโค้ดที่อ้างอิงโดยอัตโนมัติจาก jsdelivr CDN - หากใช้ Data loader ก็สามารถเตรียมข้อมูลตอน build ด้วยภาษาใดก็ได้ แล้ว bundle เป็นไฟล์สแตติกอย่าง JSON หรือ CSV ทำให้ดีพลอยแดชบอร์ดได้โดยพึ่งพาแบ็กเอนด์น้อยลง
เครื่องมือสร้างเว็บไซต์แบบสแตติกสำหรับแอปข้อมูล
- Observable Framework เป็น static site generator ที่คอมไพล์ Markdown, JavaScript และถ้าจำเป็นก็รวมภาษาอื่นด้วยให้กลายเป็น หน้าแบบ interactive
- มี hot reloading server แบบครบฟังก์ชันมาให้ เมื่อแก้และบันทึกไฟล์ในเอดิเตอร์ การเปลี่ยนแปลงจะสะท้อนในเบราว์เซอร์ทันที
- เมื่อทำงานเสร็จแล้ว สามารถใช้คำสั่ง build เพื่อสร้างชุดไฟล์สแตติกได้
- ไฟล์ชุดนี้สามารถนำไปดีพลอยบนเซิร์ฟเวอร์ได้
- หรือจะดีพลอยตรงไปยังแพลตฟอร์มแชร์ที่ยืนยันตัวตนของ Observable ด้วย
npm run deployก็ได้
JavaScript ที่รันอยู่ใน Markdown
- แกนหลักของการออกแบบ Framework คือการใส่ JavaScript ลงในเอกสาร Markdown เพื่อสร้าง เอกสารแบบ interactive
- บล็อกโค้ด Markdown ที่แท็กเป็น
jsจะถูกรันเป็น JavaScript ในเบราว์เซอร์ของผู้ใช้ - ยังสามารถใช้ inline expression ได้ เช่น
${new Date(now)}เพื่อแสดงเวลาปัจจุบันเป็นสตริง nowเป็นตัวแปรพิเศษที่ให้เวลาปัจจุบันเป็นมิลลิวินาทีตั้งแต่ epoch และอัปเดตต่อเนื่อง- เมื่อ
nowเปลี่ยน เซลล์และ inline expression ที่อ้างอิงถึงมันก็จะอัปเดตตามไปด้วย
- เมื่อ
- ใน Observable Notebooks โค้ดกับ Markdown จะถูกเขียนแยกเป็นคนละเซลล์ แต่ใน Framework ทั้งสองอย่างอยู่ใน เอกสารข้อความเดียว
- inline expression กับบล็อก
jsอาจมีรูปแบบการแสดงผลต่างกัน- inline expression ใช้การแสดงผลสตริงพื้นฐานของอ็อบเจ็กต์ JavaScript
- บล็อก
jsใช้ฟังก์ชันdisplay()ของ Observable และกฎการแสดงผลอยู่ใน inspect/src/inspect.js
คงโมเดลการรันแบบ reactive เอาไว้
- ความสามารถหลักของ Observable Notebooks อย่าง reactivity ยังคงมีอยู่ในเอกสาร JavaScript Markdown ของ Framework
- เมื่อเซลล์ใดเปลี่ยน เซลล์อื่นที่พึ่งพาเซลล์นั้นจะถูกประเมินใหม่โดยอัตโนมัติ
- นี่คือความต่างใหญ่เมื่อเทียบกับ Jupyter notebooks และยังเป็นฟีเจอร์เด่นของ marimo ซึ่งเป็นเครื่องมือ Python notebook ด้วย
- แนวทางนี้ยิ่งมีประโยชน์เมื่อใช้ร่วมกับฟอร์มอินพุต
- หากเพิ่มอินพุตลงในหน้าและอ้างอิงค่าของมันจากส่วนอื่นของเอกสาร ก็สามารถสร้างการโต้ตอบแบบเรียลไทม์ได้ง่าย
ตัวอย่างแดชบอร์ดดาวน์โหลด PyPI
- แดชบอร์ดตัวอย่างแสดงสถิติการดาวน์โหลด PyPI ของแต่ละแพ็กเกจ Python โดยเวอร์ชัน Observable Framework ถูกสร้างจากเอกสาร Markdown ความยาว 57 บรรทัด
- ผู้ใช้เลือกแพ็กเกจจากอาร์เรย์
packagesด้วยInputs.select()Inputs.select()เป็นเมธอดที่รวมมาใน Framework และดูได้ในเอกสาร Observable Inputs- ฟังก์ชัน
view()เป็นความสามารถใหม่ที่เพิ่มใน Framework เพื่อให้การเปลี่ยนตัวเลือกอินพุตสะท้อนไปยังบล็อกโค้ดอื่นในเอกสาร
packageNameถูกประกาศด้วยconstและสามารถนำไปใช้ในบล็อกjsอื่นของหน้าได้- ข้อมูลถูกดึงมาด้วย
d3.json()- ใน Framework สามารถใช้ D3 ได้ทั้งชุด
- URL จะรวมชื่อแพ็กเกจที่เลือกไว้ด้วย
- แหล่งข้อมูลคือ JSON API ของ Datasette
- ตาราง SQLite อยู่ที่ datasette.io/content/stats และอัปเดตวันละครั้งด้วยสถิติแพ็กเกจ PyPI ล่าสุด
- GitHub Actions workflow ที่เกี่ยวข้องเคยถูกกล่าวถึงในบทความก่อนหน้าเรื่อง baked data
- เมื่อเติม
.jsonต่อท้าย URL ก็จะได้ผลลัพธ์เป็น JSON- คำขอนี้ดึงเฉพาะแถวของแพ็กเกจที่ต้องการ
- เรียงตามวันที่จากมากไปน้อย
- รับได้สูงสุด 1,000 แถวในรูปแบบอาร์เรย์ของอ็อบเจ็กต์
- วันที่แบบสตริงของ SQLite จะถูกแปลงเป็นอ็อบเจ็กต์ JavaScript
Dateด้วยd3.timeParse("%Y-%m-%d") - กราฟถูกเรนเดอร์ด้วย Observable Plot ที่แพ็กมาพร้อมกับ Framework
- รายชื่อแพ็กเกจถูกดึงมาด้วยการรัน SQL query โดยตรงกับฐานข้อมูล
/contentของ Datasette- คำสั่ง query คือ
select package from stats group by package order by max(downloads) desc _shape=arrayfirstเป็นรูปแบบย่อสำหรับรับคอลัมน์แรกของแต่ละแถวเป็น JSON array
- คำสั่ง query คือ
รวมเฉพาะโค้ดที่ใช้งาน
- แดชบอร์ดตัวอย่างใช้ไลบรารีเสริมอย่าง
Inputs,d3,Plot - ในโหมดพัฒนา จะใช้การโหลดแบบ lazy loading
- โค้ดจะถูกโหลดก็ต่อเมื่อมีการใช้งานครั้งแรกในเซลล์
- เมื่อ build และ deploy แอปแล้ว Framework จะโหลดเฉพาะโค้ดไลบรารีที่มีการอ้างอิงโดยอัตโนมัติจาก jsdelivr CDN
แคชข้อมูลตอน build
- Data loader ของ Framework เป็นความสามารถสำหรับเตรียมข้อมูลแดชบอร์ดใน ช่วง build
- แดชบอร์ดของ Framework สามารถดึงข้อมูลจากที่ใดก็ได้ตอนรันไทม์ด้วย
fetch()หรือ wrapper ของมัน- Observable Notebooks ก็ทำงานในลักษณะเดียวกัน
- แนวทางนี้ทำให้ประสิทธิภาพของแดชบอร์ดขึ้นอยู่กับแบ็กเอนด์ที่เชื่อมต่ออยู่
- Framework แนะนำแพตเทิร์นที่สร้างข้อมูลสำหรับแดชบอร์ดในช่วงดีพลอย แล้ว bundle เฉพาะ subset ของข้อมูลที่จำเป็นเป็นไฟล์สแตติก
- ไฟล์ข้อมูลสแตติกสามารถให้บริการได้อย่างรวดเร็วจาก static hosting เดียวกับโค้ดของแดชบอร์ด
- Data loader เป็นสคริปต์ที่เขียนด้วยภาษาโปรแกรมใดก็ได้
- ตอน build นั้น Framework จะรันสคริปต์ดังกล่าว
- และบันทึกผลลัพธ์จาก standard output ของสคริปต์เป็นไฟล์
- ตัวอย่างใช้ไฟล์
quakes.json.shที่มีcurl https://earthquake.usgs.gov/earthquakes/feed/…- ตอน build ชื่อไฟล์นี้จะบอก Framework ว่าไฟล์ปลายทางคือ
quakes.jsonและตัวโหลดที่จะใช้คือ.sh
- ตอน build ชื่อไฟล์นี้จะบอก Framework ว่าไฟล์ปลายทางคือ
- หากสามารถพิมพ์ JSON, CSV หรือฟอร์แมตที่เป็นประโยชน์ออกทาง standard output ได้ ก็สามารถดึงข้อมูลด้วยเทคโนโลยีใดก็ได้
ความแตกต่างจาก Observable Notebooks
- Observable Framework นำแนวคิดและโค้ดจำนวนมากจาก Observable Notebooks มาใช้ซ้ำ แต่แตกต่างกันมากในด้านรูปแบบไฟล์และสภาพแวดล้อมการรัน
- Observable Notebooks แบบเดิมมีลักษณะต่อไปนี้เมื่อเทียบกับ Jupyter Notebooks
- ใช้ JavaScript แทน Python
- ตัวแก้ไขโน้ตบุ๊กเองไม่ใช่โอเพนซอร์ส และเป็นผลิตภัณฑ์โฮสต์ที่ให้บริการบน observablehq.com
- แม้จะ export โน้ตบุ๊กเป็นไฟล์สแตติกเพื่อนำไปรันที่ไหนก็ได้ แต่ตัวแก้ไขยังเป็นผลิตภัณฑ์แบบปิด
- เซลล์มีความเป็น reactive และเมื่อเซลล์ใดเปลี่ยน เซลล์อื่นที่พึ่งพาเซลล์นั้นจะถูกประเมินใหม่อัตโนมัติคล้าย Excel
- เพื่อรองรับโมเดล reactivity จึงมีการสร้างคีย์เวิร์ดเฉพาะอย่าง
viewofทำให้ไวยากรณ์ JavaScript ไม่เป็นมาตรฐานทั้งหมด - โน้ตบุ๊กที่แก้ไขได้ใช้รูปแบบไฟล์แบบปิดที่ซับซ้อน และเข้ากับเครื่องมืออย่าง Git ได้ไม่ดี Observable จึงต้องสร้างระบบเวอร์ชันและการทำงานร่วมกันของตัวเองขึ้นมา
- Observable Framework ย้ายโมเดลนี้ไปสู่รูปแบบไฟล์ที่เรียบง่ายกว่าและสภาพแวดล้อมการรันแบบโอเพนซอร์ส
- เอกสารคือ ไฟล์ Markdown เดียว ที่มีบล็อก JavaScript อยู่ภายใน
- ยังเป็น reactive เหมือนเดิม แต่แก้ไขได้ด้วย text editor ใดก็ได้และเก็บใน Git ได้
- ทั้งหมดเป็นโอเพนซอร์สภายใต้สัญญาอนุญาต ISC และสามารถรันสแตกการแก้ไขทั้งหมดบนเครื่องโลคัลได้
- ใช้เฉพาะ JavaScript มาตรฐาน โดยไม่มีไวยากรณ์พิเศษ
การเปลี่ยนทิศทางของ Observable
- Observable Framework ดูเหมือนเป็นสัญญาณว่า Observable กำลังขยับจากเครื่องมือทำงานร่วมกันที่มีศูนย์กลางเป็นตัวแก้ไข Observable Notebook แบบปิด ไปทาง เครื่องมือสำหรับนักพัฒนา มากขึ้น
- ข้อความแนะนำตัวบน Twitter ของ Observable คือ “The end-to-end solution for developers who want to build and host dashboards that don’t suck”
- ส่วนสำเนาที่เก็บไว้ใน Internet Archive เมื่อวันที่ 3 ตุลาคม 2023 ระบุว่า “Build data visualizations, dashboards, and data apps that impact your business — faster.”
- Observable Notebooks อาจถูกจำกัดการใช้งานบางส่วนจากความเป็นแพลตฟอร์มแบบปิดและข้อจำกัดของบัญชีฟรี โดยเฉพาะการไม่มีโน้ตบุ๊กส่วนตัวฟรี
- ไลบรารีโอเพนซอร์สอย่าง Observable Plot ถูกมองว่าเป็นเทคโนโลยีที่พร้อมใช้งานอย่างจริงจังอยู่แล้ว
- Observable Framework นำแนวคิดที่เคยทำให้ Observable Notebooks น่าสนใจกลับมาสร้างใหม่ในรูปแบบโอเพนซอร์ส, JavaScript มาตรฐาน, ไฟล์ข้อความเดี่ยว และโมเดลการดีพลอยแบบสแตติก
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ในบางแง่ Observable Framework เหมือน Avengers: Endgame ของจักรวาลภาพยนตร์ Mike Bostock
เอา d3, Observable, Observable Plot และ HTL มารวมกัน แล้วก็ใส่ไอเดียใหม่ ๆ ลงไปอีกพอสมควร
Observable มีการผสาน AI อยู่แล้ว และสิ่งนี้ดูเหมือนเป็น wrapper ที่ช่วยให้ AI นำไปประกอบใช้ได้ง่ายขึ้น ส่วนที่ประเมินกลยุทธ์โดยไม่มี AI ดูรู้สึกแปลก ๆ ไปหน่อย
วันนี้เริ่มดูวิธีโฮสต์ Jupyter Notebook แบบ static หรือเปิดแบบ interactive ด้วย WASM แล้วรู้สึกว่า สำหรับการใช้งานส่วนใหญ่ Observable Framework น่าจะเหมาะกว่า
ปัญหาของ Observable คือถึงแม้มันจะดูเหมือนคลังตัวอย่าง d3 แต่โค้ดถูกออกแบบมาให้รันภายในเฟรมเวิร์กนั้น จึงเอาไปคัดลอกแล้ววางใช้ตรง ๆ ไม่ได้
d3 เองก็ไม่ใช่ว่าจะใช้ง่ายถ้าไม่มีตัวอย่าง โดยเฉพาะเมื่อมีการเปลี่ยนแปลงระหว่างเวอร์ชันที่บางครั้งไม่เข้ากันได้ ถึงอย่างนั้นในเว็บก็มีกราฟิกที่น่าทึ่งอยู่มากมาย
[0] https://observablehq.com/@d3/gallery
มันใกล้กับภาษาหลักมากพอจนรู้สึกว่าน่าจะใช้ JavaScript ตรง ๆ ได้เลย เพียงแค่เพิ่ม API สำหรับแสดงกราฟิกเข้าไปเล็กน้อย
ส่วนใหญ่เป็นงานเขียนนิยามเซลล์ระดับบนสุดใหม่
[0]: https://observablehq.com/@bumbeishvili/convert-observable-co...
ความไม่พอใจแบบนี้หนักเป็นพิเศษกับโน้ตบุ๊ก ObservableHQ มันกลายเป็นทั้งตัวอย่างที่ยอดเยี่ยมและทรัพยากรที่เอาไปใช้ไม่ได้ในเวลาเดียวกัน แต่ Framework รอบนี้ดูเหมือนจะเปิดกว้างกว่านิดหน่อย และอย่างน้อยก็ self-host ได้ เลยกำลังจับตาดูอยู่
อีกอย่าง บทความนี้พูดว่า Observable Framework ใหม่ได้แก้ปัญหาบางส่วนของโน้ตบุ๊ก Observable แบบเก่าแล้ว ดังนั้นคอมเมนต์นี้จึงค่อนข้างหลุดจากบทความไปนิด ตอนนี้มันเป็นแนว “ทั้งหมดเป็น JavaScript มาตรฐาน และไม่มี syntax แบบกำหนดเอง” แล้ว
Framework นำไป deploy บน GitHub Pages ได้ง่ายมากเช่นกัน
ได้สรุปขั้นตอนและตัวอย่าง GitHub Action ไว้ที่: https://notes.billmill.org/programming/observable_framework/...
ผู้เขียนจับประเด็นเรื่อง Framework ได้ตรงมาก
ผมลองใช้ Observable Framework สร้าง plot แบบ interactive เล็ก ๆ (https://github.com/willmeyers/observable-ssta) แล้วขั้นตอนตั้งค่าและวาดข้อมูลนั้นง่ายจนน่าเหลือเชื่อ ข้อไม่พอใจอย่างเดียวคืออยากให้ตั้งค่า Python data loader ให้ใช้ virtualenv ได้
หลังสร้างโปรเจกต์ Python แล้ว ตอนเริ่ม dev server ให้รัน
poetry run yarn run devแทนyarn run devจากนั้น Python จะถูกรันภายใน virtualenv คอนฟิกนี้ช่วยให้กำหนดโค้ดที่ reusable และ unit-test ได้สำหรับ data loader เป็นแพ็กเกจ Python แบบกำหนดเอง แล้ว import จากไฟล์*.json.pyเพื่อให้ไฟล์เหล่านั้นเรียบง่ายมากเครื่องมืออย่าง node และ npm/yarn รวมถึง JavaScript จะถูกเก็บไว้ใน venv ด้วยกัน
.shแล้วชี้ไปยัง path เต็มของbin/pythonในไดเรกทอรี virtual environment ไม่ได้หรือ?เพิ่งทำโปรเจกต์ “ใช้งานจริง” ครั้งแรกด้วยโน้ตบุ๊ก Observable เสร็จเมื่อไม่นานมานี้
มีทั้งการเรียนรู้ Observable Plot, Arquero, ทบทวน JavaScript บางส่วน และผสานกับซิมูเลเตอร์ที่เขียนด้วย Rust ซึ่งเป็นกระบวนการสร้างข้อมูล พูดตรง ๆ ว่ามันยอดเยี่ยมจริง ๆ ต้องใช้พลังพอสมควรในการเรียนรู้เครื่องมือเหล่านี้ และฟีเจอร์สำหรับกำหนดพารามิเตอร์ให้ตัวสร้างข้อมูลยังไม่ค่อยน่าพอใจ แต่โน้ตบุ๊กสุดท้ายออกมาสวยและทำงานได้ดี
พอใช้ Markdown กับความเป็น reactive แล้ว รู้สึกว่าโน้ตบุ๊กแบบนี้ใช้งานได้จริง ฟอร์แมตแบบกำหนดเองของ Jupyter ทำให้การควบคุมเวอร์ชันยากขึ้นมาก และถ้าไม่มีความเป็น reactive โน้ตบุ๊กที่ออกแบบซ้ำไปซ้ำมาจะกลายเป็นกองยุ่งเหยิงแบบมีสถานะที่เขียนง่ายแต่อ่านยากได้ง่าย ๆ เคยลองทำด้วย Quarto และการผสาน Observable ของมันแล้ว แต่รู้สึกเหมือนเอาชิ้นส่วนเฉพาะหน้ามาปะติดปะต่อกัน
พูดจากใจ นี่เป็นครั้งแรกที่การเขียนโน้ตบุ๊กและแชร์กับคนอื่นเป็นเรื่องสนุกและน่าตื่นเต้น ต่อไปคงยังมีจุดขรุขระอีก แต่หลังจากโปรเจกต์นี้ มันกลายเป็นตัวเลือกแรกของผมในบรรดาเครื่องมือทำโน้ตบุ๊ก
[0]: https://living-papers.vercel.app/
หากอยากลองและเล่นกับ Framework ในเบราว์เซอร์อย่างรวดเร็ว ได้ทำ Codespace devcontainer ที่ตั้งค่า environment ของ Node และ Python ให้อัตโนมัติไว้แล้ว
[0]: https://github.com/dleeftink/observable-codespace
ควรย้ายจาก Jupyter Notebook ไปใช้ Observable ไหม? หรือการแบ่งสองอย่างนี้ออกจากกันแบบนั้นเป็นกรอบที่ผิดตั้งแต่แรก?
ถ้าพูดเนื้อหาในบทความอีกแบบ ทุกอย่างใน code block ที่มี content hint เป็น
jsจะรันในเบราว์เซอร์ของผู้ใช้ทันทีถ้าจะให้แสดงโค้ดต้องใช้ hint
js echoถ้าคิดถึง backward compatibility แล้ว แบบกลับกันจะไม่ดีกว่าหรือ? เช่นให้โค้ดที่รันในเบราว์เซอร์ผู้ใช้เป็น hint แบบ opt-in อย่างjs execแล้วปล่อย hintjsที่ใช้กันแพร่หลายไว้เหมือนเดิม ตอนนี้ด้วยโครงสร้างนี้ เวลานำ renderer นั้นไปรวมกับแอปที่มีอยู่ ต้องคอยจัดการแยกเองว่าจะอนุญาตให้รันตรงไหนทำได้ต่อหน้าใน front matter หรือใช้ project settings เพื่อใช้กับทั้งโปรเจกต์ก็ได้ แบบนั้นจะทำให้
js run=falseเป็นค่าเริ่มต้น แล้วเปิด live code ด้วยjs runเฉพาะตอนที่ต้องการได้ อย่างไรก็ตาม use case หลักของเราคือ live code เลยเลือกให้เป็นค่าเริ่มต้นตอนนี้เลยไม่สามารถแสดง Mermaid code block เฉย ๆ ได้แล้ว ถ้าไม่เอา language annotation ออก
ใช้เวลาอยู่กับ Observable Framework ทั้งคืนแล้วรู้สึกว่าดีมาก
แทบไม่รบกวน workflow และทำให้ผม visualize กับสำรวจประวัติ Google Maps ได้ละเอียด ส่วนที่เกี่ยวกับ environment ของ data loader ยังไม่ชัดเจนนัก แต่แก้ได้ด้วยการรัน Python ใน environment ของ poetry
ผมชอบ Kotlin เลยลองทำ data loader สำหรับ Kotlin script ด้วย แต่มีจุดที่ยังไม่เรียบอยู่ Kotlin คาดหวังให้ชื่อไฟล์ script เป็น
foo.main.ktsแต่ Observable คาดหวัง extensionfoo.exeสำหรับ shebang loader ที่รันได้ ผมเลยทำ proxy exe script ที่เรียก Kotlin script ขึ้นมา แต่แบบนั้นจะไม่ trigger การ reload data อัตโนมัติสิ่งที่รู้สึกไม่สะดวกเล็กน้อยเมื่อเทียบกับ marimo หรือ Jupyter คือการใช้ตัวแปรระหว่าง data loader กับ notebook เช่น ผมอยากใช้ view component สำหรับเลือกวันที่เพื่อเปลี่ยนช่วงข้อมูลที่ loader ดึงมา แต่ไม่ชัดเจนว่าต้องทำอย่างไร เลยทำให้ exploratory analysis ช้าลงนิดหน่อย ผมรู้ว่านี่ขัดกับ paradigm แต่ก็อยากชี้ไว้ ผลคือระหว่างสำรวจ อาจต้องย้ายงานแปลงข้อมูลจำนวนมากมาไว้ใน notebook ซึ่งในมุม performance แล้วไม่เหมาะนัก
สุดท้าย อยากให้สามารถ นิยาม data loader แบบ inline ได้ ผมชอบไฟล์เดียว ถ้าเพิ่ม Python code block แล้ว Framework ช่วย extract มันออกเป็นไฟล์ให้ได้ ก็น่าจะเป็นการปรับปรุงคุณภาพชีวิตเล็ก ๆ อย่างหนึ่ง แม้จะยังอยู่ช่วงต้น แต่ Framework ดูมีอนาคต อยากให้เอา Markdown notes ทั้งหมดมาไว้ที่นี่ แล้วสร้าง environment คล้าย org-mode ได้โดยไม่ต้องไปถึง Emacs เต็มรูปแบบ
.shหรือ.exeจะทำให้ระบุ interpreter ที่ผูกกับ file extension เฉพาะได้ เช่น
.ktsสำหรับ Kotlin https://github.com/observablehq/framework/pull/935วิธีขับ data loader ด้วย input นั้นออกจะคนละแนวกับ Framework นิดหน่อย เพราะ Framework ชอบ static data snapshot เป้าหมายคือให้ไซต์ที่ build แล้ว self-contained และมี performance ดี ถึงอย่างนั้น เทคนิคที่ใช้ได้ดีคือให้ data loader สร้าง superset ของข้อมูลที่จะ interact ด้วยเป็นไฟล์ Parquet แล้วให้ client ใช้ DuckDB/SQL เลือก subset ที่จะนำไป visualize โดยทั่วไป performance ดี แต่แน่นอนว่าขึ้นอยู่กับขนาดของ superset ที่ต้องจัดการ
Observable ผสานกับ ClickHouse ได้ดีมากผ่าน REST API
ตัวอย่างอยู่ที่นี่: https://observablehq.com/@stas-sl/github-issues-survival-ana...
ยังไม่ได้ลอง Observable Framework ใหม่ แต่ถ้าเห็นตัวอย่างคล้าย ๆ กันที่ query database แบบ realtime ก็น่าสนใจ หวังว่าโครงสร้างจะไม่ได้ทำได้แค่โหลดข้อมูลทั้งหมดล่วงหน้าและ cache ไว้เท่านั้น แอปแบบนี้ควร interactive ดังนั้น ideally ควรเปิดให้แก้ SQL แบบ live ได้
เดโมนี้โหลดข้อมูลด้วย
fetch()ตอน runtime: https://simonw.github.io/observable-framework-experiments/pa...