1 điểm bởi GN⁺ 2024-11-19 | 1 bình luận | Chia sẻ qua WhatsApp
  • Chỉ với một tệp HTML duy nhất chạy trong trình duyệt, có thể gói việc khám phá dữ liệu, phân tích, trực quan hóa, dàn trang và triển khai vào trong một tài liệu, qua đó rút gọn luồng notebook truyền thống → công cụ xuất bản → PDF
  • Cốt lõi triển khai là kết hợp các ô echo hiển thị stylescript ngay trên màn hình, contenteditable và Observable Runtime để tạo các ô phản ứng có thể chỉnh sửa
  • cell(name, inputs, definition) tuân theo mô hình phụ thuộc của Observable để cấu thành các đơn vị thực thi liên kết với nhau, như counter, phần render FizzBuzz, ô ẩn và ô giá trị trung gian không có đầu ra
  • Trong cùng một tài liệu HTML, bản demo trình diễn Observable Plot, TeX, Markdown, Graphviz, SQLite dựa trên WASM, Python dựa trên Pyodide, R dựa trên WebR, Observable Inputs và cả trạng thái Mutable
  • Kết quả là một tài liệu khoa học/kỹ thuật chạy trong trình duyệt mà không cần nền tảng riêng; phần triển khai sau đó được công bố thành thư viện @celine/celine

Thu hẹp khoảng cách giữa notebook và xuất bản bằng một tệp HTML duy nhất

  • HTML được dùng rộng rãi cho dàn trang, nhưng tương đối ít được tận dụng như một nền tảng khám phá, phân tích và trực quan hóa dữ liệu
  • Quy trình làm việc thông thường đi qua nhiều công cụ
    • Thực hiện khám phá, phân tích và trực quan hóa trong các notebook tương tác như Jupyter, RStudio, Pluto.jl, Observable
    • Chuyển sang các nền tảng xuất bản như Typst, Overleaf, LaTeX hoặc trình soạn thảo WYSIWYG để dàn trang
    • Xuất ra .pdf để phân phối
  • Nếu một tệp HTML đảm nhận cả ba bước này, có thể giảm bớt thao tác thủ công, công cụ CLI, các bước CI và sự phụ thuộc vào nền tảng bên thứ ba
  • Phần triển khai chịu ảnh hưởng mạnh từ In-browser code playgrounds của Anton Zhiyanov, Self-modifying HTML notes của Cristóbal Sciutto, QuartoObservable Framework

Tạo các ô có thể chỉnh sửa

  • Bước đầu tiên là dùng lớp CSS echo để hiển thị nguyên trạng các phần tử stylescript trong tài liệu
  • Khi thêm một phông chữ có tô sáng cú pháp tích hợp và thuộc tính contenteditable, chúng có thể được dùng như một trình chỉnh sửa mã cơ bản
  • script có áp dụng contenteditable sẽ được đánh giá lại khi mất focus
    • Nhân bản script hiện có để tạo phần tử script mới rồi xóa bản gốc
    • Cách này là cần thiết vì eval không hoạt động với mã có câu lệnh import
  • Để thực thi dựa trên Observable, hai thư viện được nạp vào
  • Trên phạm vi toàn cục chỉ để lộ hai symbol là librarycell

Luồng dữ liệu phản ứng dựa trên Observable Runtime

  • Hàm cell(name, inputs, definition, observerVisibility) định nghĩa ô bằng module scope của Observable Runtime
  • Nếu đã có biến cùng tên thì lấy biến hiện có; nếu chưa có thì tạo biến mới và định nghĩa nó
    • Nhờ cấu trúc này, khi đánh giá lại một ô contenteditable, định nghĩa mới sẽ được truyền tới các ô liên kết
  • Observable Inspector được dùng để hiển thị đầu ra của ô phía trên khối script
  • Ô counter được cấu thành như một async generator phát ra số mỗi giây
    • Thuộc tính id của script giống với đối số name của cell
    • Sau khi thay đổi giá trị ban đầu i và bỏ focus, giá trị mới sẽ được phản ánh
  • Cũng có thể tạo ô phụ thuộc vào counter
    • Nạp Hypertext Literal để render giá trị counter theo dạng FizzBuzz
    • htl triển khai bộ phân tích HTML5, xử lý tự động escape và nội suy các giá trị không tuần tự hóa như event listener, đối tượng style và DOM node

Ô hiển thị, ô ẩn và ô không có đầu ra

  • Nếu không gắn lớp echo, có thể ẩn định nghĩa ô nhưng vẫn quan sát được đầu ra
    • Những ô như vậy có thể dùng làm primitive render
  • Cũng có thể tạo kiểu ô không hiển thị chính đầu ra
    • silent(name, inputs, definition) đặt observerVisibility thành ẩn, dùng để lưu giá trị trung gian hoặc cấu trúc dữ liệu
  • Ô có thể hoạt động bất kể thứ tự khai báo
    • Trong ví dụ, ô reallyNegative phụ thuộc vào ô negative được khai báo sau đó
  • Cùng một giá trị ô cũng được dùng cho đầu ra phức tạp hơn
    • Nạp Observable Plot để vẽ mảng số thành biểu đồ đường và hiển thị một đường quy tắc dọc tại vị trí counter % 40

Mở rộng đầu ra tài liệu và trực quan hóa

  • Ô có thể trả về bất kỳ phần tử DOM nào
  • Các bản demo TeX, Markdown và Graphviz lần lượt trả về các dạng phần tử khác nhau
    • Ô tex trả về phần tử span
    • Ô md trả về phần tử table
    • Ô dot trả về phần tử svg
  • Ô có thể trả về Promise hoặc ném Error
    • Observable Inspector áp dụng lớp observablehq--running cho div bên ngoài ô đang chạy
    • Áp dụng lớp observablehq--error cho ô lỗi
    • Tài liệu định kiểu theo các trạng thái này

SQLite, Python và R trong trình duyệt

Đầu vào và trạng thái biến đổi

  • Kiểu ô viewof được tạo để dùng cùng Observable Inputs
  • viewof khai báo hai ô phản ứng
    • NAME: giá trị của input
    • viewof NAME: chính phần tử DOM
  • Để hiển thị input phía trên ô, đặt id của ô thành viewof NAME
  • Trong ví dụ, tạo range input bằng Inputs.range([0, 100], { step: 1 }), và ô rangePlot được cập nhật theo giá trị đó
  • Cách hoạt động của Observable Inputs khá khó hiểu; bản demo Synchronized Inputs có thể hữu ích
  • Với những trường hợp chỉ dùng luồng dữ liệu thuần hàm là chưa đủ, một helper mutable cũng được tạo
    • mutable đăng ký một đối tượng Mutable phát ra giá trị mới khi giá trị thay đổi

Công bố thư viện và slide thuyết trình

  • Ban đầu phần triển khai này được cân nhắc đặt tên là incel, nhưng sau đó định gọi là celine
  • Thư viện được công bố dưới tên @celine/celine
  • Tài liệu này đã được demo tại SydJS
  • Cũng có mã để biến tài liệu thành slideshow
    • Shift+N: bắt đầu slideshow hoặc chuyển sang slide tiếp theo
    • Shift+B: quay lại slide trước
    • Shift+E: kết thúc slideshow
  • Mã nguồn triển khai được công bố tại source code

1 bình luận

 
GN⁺ 2024-11-19
Ý kiến trên Hacker News
  • Tôi rất đồng ý với tiền đề của bài viết. HTML có thể là một nền tảng tuyệt vời cho notebook tính toán
    Tuy nhiên, tôi không thích các lựa chọn triển khai ở đây. HTML động, phản ứng có thể được làm theo cách khai báo hơn thế này rất nhiều, và Observable tuy rất hay nhưng có phần đi lệch khỏi JavaScript chuẩn
    Tôi đã bắt đầu xây dựng một hệ thống HTML phản ứng tên là Heximal, sau này cũng dự định bổ sung hỗ trợ notebook. Đây là một hệ thống khai báo dựa trên mẫu HTML và phần tử tùy chỉnh, bên trên là hệ thống biểu thức/phản ứng dựa trên đề xuất TC39 Signals
    https://github.com/elematic/heximal
    Nó gần giống như sự pha trộn giữa HTMX, Tangle, Curvenote và Polymer; nếu HTML vốn dĩ đã phản ứng từ đầu thì có lẽ nó sẽ trông như thế này. Tôi nghĩ nó khá phù hợp với các trường hợp sử dụng chỉnh sửa đồ họa và notebook

    • “Observable tuy hay nhưng đi lệch khỏi JS chuẩn” thì đúng với phần frontend, nhưng runtime bên dưới chỉ chạy JavaScript. Mã nguồn cũng gần giống JavaScript kèm một macro nhỏ, được chứa hoàn toàn trong parser acorn theo giấy phép MIT
      Vì vậy các biểu thức debug JavaScript thông thường hoạt động đúng trong Observablehq
      https://github.com/observablehq/parser
      Vì thích runtime của Observable, tôi còn làm cả một decompiler có thể chuyển đổi hai chiều giữa mã nguồn frontend và biểu diễn JS thuần đã biên dịch
      https://observablehq.com/@tomlarkworthy/observablejs-toolcha...
    • Tôi tự hỏi ở đây có cân nhắc đến Observable Framework không. Nó ra mắt vào tháng 3, và một trong những đặc điểm chính là dùng JavaScript chuẩn chứ không phải các cú hack cú pháp được tạo ra trong Observable Notebooks: https://observablehq.com/blog/observable-2-0#a-better-develo...
  • Thật sự rất tuyệt. Tôi đặc biệt thích demo Python và SQLite. Việc bắt đầu từ vòng lặp chỉnh sửa qua web (TTW) rồi gọi nó là quine khá thú vị; dù hợp lý, điểm yếu cốt lõi vẫn là tính bền vững dữ liệu
    TiddlyWiki thực ra cũng làm gần như điều tương tự, nhưng việc lưu công việc là một vấn đề đau đầu. Vì để duy trì thứ gì đó lâu dài thì rốt cuộc vẫn cần một tiến trình server headless riêng
    Khi muốn làm một thứ tương tự[0], cá nhân tôi bắt đầu từ tính bền vững, và điều đó dĩ nhiên có nghĩa là tệp. Đó là các tệp văn bản thuần có thể chỉnh sửa bằng editor dành cho lập trình viên và lưu/triển khai qua hệ thống tệp. Cách này tránh được vấn đề phải triển khai lại một editor cho lập trình viên ngay trong trình duyệt, vốn không hề dễ
    Đổi lại sẽ phát sinh vấn đề phải viết một server nhanh, nhưng đó cũng là một bài toán khá thú vị[1]. Ở đây họ tránh vấn đề đó bằng cách dùng các section contenteditable cơ bản, nhưng đây là vấn đề lớn tiếp theo sau tính bền vững dữ liệu
    Việc không thể export bên trong script nhúng cũng có vẻ là cùng một bức tường. Nếu không muốn làm lộn xộn đối tượng window toàn cục thì có tính năng như vậy sẽ tốt hơn, và trong trường hợp sử dụng của tôi, việc sinh mã cũng sẽ dễ hơn
    0 - Literate Markdown: https://simpatico.io/lit.md
    1 - Reflector, một server node nhỏ chuyển đổi, nén, cache markdown và vô hiệu hóa theo dõi tệp: https://simpatico.io/reflector

  • Tôi tôn trọng suy nghĩ và công sức đã bỏ ra, nhưng tính khả dụng của cách tiếp cận này thật tệ. Tôi không hiểu vì sao khi đang muốn làm phân tích dữ liệu khám phá lại còn phải bận tâm cả các yếu tố styling
    Đây chính là lý do những công cụ như Jupyter Notebook hoạt động hiệu quả. Dù vậy, tôi đánh giá cao việc tác giả tò mò và hiện thực hóa các ý tưởng thay thế

    • Tác giả: Tôi cũng tiếc, nhưng đồng ý rằng tính khả dụng của cách này thật tệ, và đó cũng là một phần lớn động lực khiến tôi tạo ra @celine/celine (https://maxbo.me/celine, tức là đóng gói bài viết thành thư viện)
      Nó vẫn chưa đủ tốt như một nền tảng phân tích dữ liệu khám phá. Nó không có tính phản ứng tức thì của một trình biên tập mã web hoàn chỉnh như Observable Notebooks, cũng không phải Observable Framework cung cấp hot reload dựa trên theo dõi tệp. Kernel Jupyter mới cho Deno + VSCode cũng mang lại trải nghiệm khá mượt
      Vì vậy, về tính khả dụng cho phân tích khám phá thì ừm… tôi đồng ý là tệ, nhưng tôi cho rằng tính khả dụng khi triển khai thì không tệ đến vậy. Thật ra là tốt. Vì nó chỉ là một tệp duy nhất. Khi muốn gửi biểu đồ và kết quả xử lý dữ liệu cho ai đó, bạn không cần duy trì một toolchain khổng lồ hay trả tiền cho dịch vụ bên thứ ba; chỉ cần thả một tệp HTML vào Slack hoặc host nó ở đâu đó
      Nhờ sự linh hoạt trong việc styling kết quả phân tích, bạn cũng có thể xuất bản trong những môi trường mà phong cách trình bày quan trọng, như blog hoặc bài báo nghiên cứu
    • Thoạt nhìn có vẻ như họ đang muốn định vị thứ này theo hướng “phân tích DOM khám phá”. Demo giới thiệu có cảm giác giống Scheme/Smalltalk ở chỗ vừa làm vừa xây dựng cấu trúc và các phần tử cơ bản; cảnh đổi ivory thành red khiến tô sáng cú pháp thay đổi theo thời gian thực cho thấy điều đó
      Tôi hiểu bối cảnh dẫn đến hướng này, nhưng thật tiếc là không thể dễ dàng nghịch thử các framework và thư viện JavaScript trong trình duyệt hơn nữa. Rốt cuộc nó cũng chỉ là JS, nên đáng ra phải có thể thử nghiệm nhanh trong một môi trường nhẹ. Cách tiếp cận này có thế mạnh ở điểm đó
      Đây là một cách đưa trở lại khả năng vui đùa và thử nghiệm của HTML/JS. Tôi mong có nhiều thử nghiệm kiểu này hơn, thay vì TS, rollup, webpack
      Bổ sung: đọc thêm một chút thì thấy họ đề xuất nó cho phân tích dữ liệu. Tôi nghĩ nó không hợp với mục đích đó
    • Nói là “chỉ đang muốn làm phân tích dữ liệu khám phá”, nhưng trọng tâm chẳng phải là có một nền tảng tích hợp để làm phân tích dữ liệu khám phá rồi dễ dàng xuất bản kết quả sao? Nó không dành cho những notebook Jupyter viết xong rồi bỏ
      Tôi nghĩ các lựa chọn thay thế Jupyter Notebook không bị bỏ đi sau khi dùng có giá trị rất lớn. Trải nghiệm người dùng hiện tại thật sự tệ thì có thể cải thiện được. Vấn đề là cấu hình này có tốt hơn mớ hỗn độn JSON của Jupyter Notebook không; cá nhân tôi nghiêng về câu trả lời là có
  • Tác giả gốc của Lit gần đây đã rời Google, và theo tôi biết thì đang làm một thứ rất giống với cái này
    https://github.com/elematic/heximal

    • Tôi không biết là anh ấy đã công khai thứ đang làm sau đó. Cảm ơn đã cho biết
  • Tôi thích hình thức của bài này. Nó bắt đầu từ tầng thấp nhất rồi xây dần lên thành một thứ thú vị. Không phải kiểu thổi phồng bằng cách gắn một đống dependency hay framework chỗ này chỗ kia
    Nếu muốn theo dõi, có lẽ chỉ cần copy-paste các mảnh được đưa ra và hiểu từng bước chúng hoạt động thế nào. Nếu tôi viết thứ như thế này, chắc tôi sẽ dùng literate programming của org-mode rồi xuất ra HTML để làm bài blog
    Tuy nhiên, tôi vẫn thấy khó hiểu về phông chữ có tô sáng cú pháp tích hợp

  • Gọi là HTML phản ứng nhưng gần như toàn bộ chẳng phải là JavaScript sao, hay tôi đang hiểu nhầm điều gì?

    • Phần tương tác/phản ứng là JavaScript, nhưng notebook được triển khai trong một tệp HTML tự chứa. Nó xử lý mọi thứ, từ cấu trúc tài liệu đến chỉnh sửa và hiển thị
      Ngoài trình duyệt ra thì không phụ thuộc vào phần mềm bên thứ ba, và giống như HTML, nó bền lâu, dễ mang đi và dễ dùng
    • Cảm giác như: “Tại sao mọi người lại dùng Colab hay Observable để chạy notebook trong trình duyệt nhỉ? Dù sao thì tôi sẽ đưa ra một lựa chọn thay thế dùng Observable cho những phần khó”
  • Sắp tới tôi muốn thử hỗ trợ loại HTML notebook này trong Raku, hoặc dành cho Raku
    Hiện tại “giải pháp notebook” của Raku dựa trên Jupyter hoặc Mathematica

  • Tôi không hiểu logic của việc dùng công nghệ web để làm phức tạp hóa quy trình này. Độ phức tạp được thêm vào giải quyết vấn đề gì? Ngược lại, nó có vẻ gần với việc làm quy trình chậm hơn và loại bỏ các tính năng cần thiết như tự động hoàn thành, snippet, extension
    Hơn nữa, rất có thể người khác không quen với thiết lập này, nên việc cộng tác cũng khó hơn
    Môi trường chỉ cần thiết lập một lần, rồi tiếp tục dùng, chỉ thêm các cải tiến nhỏ khi công nghệ thay đổi
    Nếu là người dùng n/vim thì những thứ sau là đủ. 1- Khám phá dữ liệu: dùng https://github.com/untitled-ai/jupyter_ascending để kết nối văn bản với Jupyter Notebook. Vì dùng jupytext, có thể chỉnh sửa và chạy mã hiệu quả trong trình soạn thảo văn bản
    2- Viết lách: có thể dùng https://github.com/lervag/vimtex cho LaTeX
    Thêm tmux và tmuxp vào đó là có thể mở dự án ngay lập tức. Trong Emacs, có thể tạo một quy trình mượt mà bằng org mode[1][2] và/hoặc Auctex
    [1] https://sqrtminusone.xyz/posts/2021-05-01-org-python/
    [2] https://martibosch.github.io/jupyter-emacs-universe/

    • Khi bật Jupyter Notebook trong trình duyệt thì đang dùng công nghệ gì? Khi mở website của OP thì đang dùng công nghệ gì?
    • Nhìn chung là nhận xét đúng
      Tuy nhiên tôi không thích Python lắm, nên muốn dùng công cụ không lấy Python làm trung tâm. Vì vậy tôi mới nói đến Raku và Mathematica
      Nhân tiện, cảm ơn vì đã giới thiệu https://github.com/imbue-ai/jupyter_ascending
    • Đồng ý. Những ai muốn notebook phản ứng nên nghiêm túc cân nhắc Emacs. Có nhiều người dùng Emacs chỉ cho một vài mục đích, và notebook phản ứng thường là một trong số đó
  • Tôi phần lớn đồng ý với tiền đề của bài viết này, tức là HTML chưa được tận dụng đủ như một phương tiện phân phối cho viết lách khoa học
    Có một số công việc gần đây của Will Crichton liên quan đến điều này
    https://willcrichton.net/nota/
    https://willcrichton.net/notes/portable-epubs/

  • Dạo này notebook quả là đang nóng. Chúng tôi cũng đã phát hành một phiên bản TypeScript notebook[1], nhưng đã chọn một hướng khá khác trong các đánh đổi
    Vì muốn chạy mã node ở backend, chúng tôi không cố chạy trong môi trường trình duyệt, khác với cách của bài viết này hay Observable. Dù vậy, với nhiều ứng dụng, ý tưởng này có thể là lời giải tốt hơn
    Xin dành lời khen cho tác giả
    https://github.com/srcbookdev/srcbook