1 điểm bởi GN⁺ 2025-01-18 | 1 bình luận | Chia sẻ qua WhatsApp
  • learn.yjs.dev hiện tạm ngừng triển khai, nên không thể xem nội dung học tập
  • Trên trang không nêu nguyên nhân tạm ngừng ngoài trạng thái This deployment is temporarily paused
  • Thời điểm hoặc lịch trình triển khai trở lại cũng chưa được công bố
  • Hiện không thể kiểm tra cấu trúc, tính năng hay ví dụ của nội dung học Yjs trên trang này
  • Phạm vi có thể đánh giá lúc này chỉ là learn.yjs.dev đang ở trạng thái tạm ngừng

1 bình luận

 
GN⁺ 2025-01-18
Các ý kiến trên Hacker News
  • Hey HN! Tôi là lập trình viên Jamsocket đã tạo ra thứ này. Nếu chưa quen với Yjs, có thể xem nó là một thư viện CRDT để xây dựng các ứng dụng cộng tác và local-first
    Nếu bạn chưa từng xử lý trạng thái phân tán thì đường cong học tập khá dốc, và ngay cả việc tăng bộ đếm kiểu “hello world” trong demo framework JavaScript cũng trở nên khó nhằn khi có nhiều client tham gia
    Nhiều tutorial theo kiểu “cài tích hợp thư viện này với trình soạn thảo văn bản là xong app”, nên không cung cấp được mô hình tư duy về chuyện gì thực sự đang diễn ra
    Vì vậy tôi đã tạo Learn Yjs, một tutorial Yjs tương tác, và đưa vào nhiều demo có thể khám phá cùng bài tập lập trình để ngay cả người mới tiếp cận phát triển local-first cũng có thể hiểu một cách trực quan

    • Tôi từng quan tâm đến CRDT và tính năng cộng tác, nhưng mỗi lần bắt đầu thì rào cản lớn nhất lại chính là các tutorial kiểu “cài thư viện là xong”
      WebSocket cũng có vẻ hơi khó tìm hosting miễn phí hơn, và các tutorial CRDT hiện có cũng đã giúp ích rất nhiều
    • Tôi tò mò liệu có ví dụ nào về việc tạo ứng dụng local-first không
      Tôi đang làm bằng HTML/JS thuần và Alpine, và cũng muốn biết liệu có thể dùng Yjs trong những app như vậy không
    • Tôi tò mò liệu cái này có hoạt động với Yrs [0] không, hay là một dự án riêng
      Ngoài ra, tôi cũng muốn biết Y-Sweet có hoạt động với các thư viện CRDT khác như Automerge hay Loro không, hay chỉ dành riêng cho Yjs
      Cấu trúc của chúng trông đều khá giống nhau, đều trao đổi các file nhị phân, nên tôi đã thắc mắc Y-Sweet tương thích đến mức nào với các triển khai CRDT tương tự
      [0] https://github.com/y-crdt/y-crdt
    • Làm rất tốt. Tôi tò mò liệu nhờ cái này cuối cùng mình có hiểu được CRDT không, và dự định cuối tuần sẽ xem hết
  • Yjs tốt, và khá dễ đạt được kết quả P2P
    Tuy nhiên backend cho Yjs, tính bền vững dữ liệu, xử lý xung đột cuối cùng (trường hợp một người biên tập offline quá lâu), tua lại lịch sử có vẻ là những bài toán kỹ thuật khó giải
    Tôi luôn muốn có trải nghiệm tốt trong các trình biên tập dạng khối như Platejs https://platejs.org/
    Những giải pháp như Liveblocks https://liveblocks.io/text-editor cố gắng đơn giản hóa trải nghiệm phát triển là điều tốt, nhưng phần lớn đòi hỏi phải từ bỏ một phần quyền kiểm soát dữ liệu
    Khi tìm từ khóa CRDT trên HN thì luôn thấy kết quả tốt và sự quan tâm, nhưng phía backend mã nguồn mở thì không thấy nhiều lựa chọn tốt. Trước đây tôi đã kiểm tra nhiều lần; nếu tôi bỏ sót gì thì mong được chỉ giúp
    https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=tru...
    Phần lớn mọi người kỳ vọng nó ít nhất hoạt động như Google Docs hay Notion, còn từ góc nhìn lập trình viên thì mong dữ liệu được lưu riêng tư theo định dạng tương tự Postgres JSONB mà không phải đào quá sâu vào chi tiết triển khai

    • Về lý thuyết chỉ cần phân phối các patch đã tuần tự hóa, nhưng trong backend thực tế có thể cũng cần biết trạng thái tài liệu hiện tại, danh tính người dùng, và cả một mức độ kiểm soát truy cập nào đó
      Tôi đã nhiều lần muốn dùng Y.js trong backend Go, nhưng khó tìm được một triển khai tham khảo đơn giản nên lần nào cũng phải bỏ cuộc vì hạn chế thời gian
      Sau nhiều năm quay lại kiểm tra, ngoài Node.js ra thì vẫn có vẻ khó
  • Trước đây tôi đã dùng Yjs trong một dự án phụ nhỏ. Phía client khá dễ học và dễ dùng
    Ở phía server, tôi muốn triển khai dưới dạng một binary duy nhất, nhưng ví dụ bằng ngôn ngữ không phải Node, chẳng hạn ví dụ về Yrs, bản port Rust, thì gần như không có
    Cuối cùng tôi đã sửa nhẹ https://github.com/yjs/y-websocket và gắn thêm tính bền vững dựa trên LevelDB, nhưng theo tiêu chuẩn của tôi thì đó không phải phương án tối ưu
    Tôi tò mò liệu có tài liệu tốt nào về việc triển khai phía server kèm tính bền vững bằng một ngôn ngữ như Rust không
    Theo tôi nhớ, các tài liệu client hiện có thiên nhiều về tích hợp trình soạn thảo văn bản, nên tutorial này thật sự hữu ích. Vì tôi không dùng tích hợp trình soạn thảo văn bản nên đã phải tự mò mẫm

    • Có thể Y-Sweet[1] là thứ phù hợp. Đó là server Rust mã nguồn mở chạy banner của Learn Yjs
      Nó dùng S3 hoặc hệ thống file cục bộ làm kho lưu trữ, và biên dịch thành một binary vài MB được liên kết với musl
      https://github.com/jamsocket/y-sweet
  • Có nói rằng “kỹ thuật fractional indexing, đặt chỉ mục là phân số thay vì số nguyên”; tôi tò mò có thể dùng bao nhiêu lần trước khi nó dừng lại

    • Tôi tự thử thì được 1075 lần, không phải con số quá lớn nên có vẻ có thể trở thành vấn đề chính của thư viện này
      Mã kiểm thử như sau:
      let left = 0, right = 1
      let rightPrevious = 2
      let counter = 0;
      while (right > left && right < rightPrevious) {
      rightPrevious = right;
      right /= 2;
      counter++
      }
      console.log(counter)
      Tôi chỉ xem lướt repository trong thời gian rất ngắn nhưng không tìm thấy chỗ xử lý vấn đề này, và cũng không có thời gian đào sâu. Nếu đây là issue thật thì tôi có thể giúp giải quyết
  • Hiện tôi đang dùng Yjs khi xây dựng một app cần hoạt động offline
    Thực tế nó không phải app cộng tác thời gian thực, nhưng nếu coi server là một cộng tác viên và app là cộng tác viên khác thì có thể dễ dàng hình dung use case

  • Điểm mà tôi rốt cuộc vẫn không vượt qua được với Yjs là: nếu khái quát hóa ví dụ di chuyển mục trong ứng dụng việc cần làm của hướng dẫn này, mọi thứ trở nên phức tạp quá nhanh
    Khi có nhiều đối tượng có quan hệ với nhau, bạn sẽ muốn đặt chúng trong cùng một Document, và việc giữ cho các quan hệ đó luôn ở trạng thái đồng bộ có rất nhiều cạm bẫy như fractional indexing trong hướng dẫn
    Rồi khi tích lũy đến quy mô cơ sở dữ liệu, mô hình đồ chơi nhét mọi thứ vào một tài liệu duy nhất đồng nghĩa với việc bất kỳ bên nào muốn đọc bất kỳ mục nào cũng phải được gửi toàn bộ DB cùng lịch sử của nó
    Cuối cùng bạn phải tách các mục thành các đối tượng riêng và tự mình lưu bền vững, nhưng tài liệu thì ngoài hướng dẫn này [0] ra không có gì; nói trước luôn, đó là một trang trống đã ghi “Work in Progress - come back later” suốt nhiều năm
    Vì vậy dù muốn tạo và quản lý một Provider, tình hình tài liệu vẫn y như vậy [1]
    Khi phát hiện Subdocuments, bạn sẽ vui mừng nghĩ rằng có lẽ đã có lời giải cho vấn đề phổ biến này [2], nhưng một số Provider không xử lý được quan hệ giữa các tài liệu con, còn một số Provider thì không hỗ trợ tài liệu con. Rốt cuộc lại phải tự viết Provider, rồi quay về vấn đề là không có tài liệu
    Nếu thử đọc mã, cuối cùng bạn sẽ nhận ra cốt lõi của Yjs là giao thức. Nhưng ngay cả giao thức đó, tức bản chất của Yjs, cũng không được tài liệu hóa đầy đủ, mà nằm rải rác ở nhiều chỗ trong những đoạn mã khá đặc thù. Trừ khi bạn tính cả bài báo nói về cách tiền thân của Yjs hoạt động 10 năm trước là tài liệu
    Tôi không định viết thành lời phàn nàn, nhưng trong vài năm qua tôi đã tốn quá nhiều thời gian để cố làm cho nó chạy, và khoảng cách giữa các demo đồ chơi kiểu “nó hoạt động như phép màu!” với một thứ thực tế là quá lớn. Phần tài liệu đó suốt 10 năm qua vẫn trống trơn ngoài dòng “Work in Progress”
    Hy vọng các công ty đang cố kiếm tiền từ Yjs, như tác giả bài viết này, sẽ lấp được khoảng trống đó
    [0] https://docs.yjs.dev/tutorials/persisting-the-document-to-a-...
    [1] https://docs.yjs.dev/tutorials/creating-a-custom-provider
    [2] https://docs.yjs.dev/api/subdocuments
    [3] Khi viết điều này, tôi đã hy vọng tình hình đã thay đổi, nhưng mọi tài liệu dường như vẫn đang làm dở như 5 năm trước, và hỗ trợ tài liệu con cũng vậy

  • Trong demo tương tác, thanh trượt độ trễ hoạt động như một bộ đệm debounce chứ không phải độ trễ mạng, nên khá bối rối. Tôi không hiểu vì sao lại làm như vậy

    • Chúng tôi chọn mô hình độ trễ đơn giản nhất đủ để minh họa vấn đề phát sinh khi trạng thái thay đổi ở nhiều nơi
      Ưu điểm của cách này là có thể triển khai mà không che giấu bất kỳ trạng thái nào với người đọc. Biểu đồ tròn hiển thị nguyên trạng thái nội bộ duy nhất đang tồn tại
      Mục tiêu không phải là mô phỏng mạng chính xác, mà là xây dựng trực giác
  • Demo tương tác rất đẹp. Tò mò không biết đã dùng thư viện nào để làm

    • Toàn bộ trang được làm bằng Astro, còn các demo là “đảo tương tác” viết bằng React
      Demo thực sự chạy Yjs bên trong. Mỗi “client” có tài liệu riêng; khi người dùng nhấp, nó mô phỏng độ trễ bằng setTimeout rồi hợp nhất thủ công các tài liệu với nhau. Cũng có một tài liệu thứ ba cho timeline ở giữa
      Ngoài ra, demo việc cần làm dùng dnd kit [1] cho kéo-thả, Motion [2] cho animation, và CodeMirror [3] cho trình soạn thảo văn bản
      [1] https://dndkit.com
      [2] https://motion.dev
      [3] https://codemirror.net
  • Trò chơi ở ảnh banner ngớ ngẩn nhưng vui

  • Cuối cùng tôi cũng làm được cỏ bốn lá, nhưng khoảng 2 phút sau có ai đó phá mất
    Sửa: khoan đã, mọi người đi đâu hết rồi? Có vẻ chúng tôi đã làm hỏng nó hoặc tôi bị chặn. Dù sao cũng vỗ tay cho người làm ra nó. Một thứ rất hay

    • Chắc chắn không phải bạn bị chặn. Có vẻ chỉ là một lúc mọi người ít đi, còn bây giờ lại thấy khá nhiều con trỏ
      Nhân tiện, còn có thêm hai emoji bí mật nữa