27 điểm bởi xguru 2025-06-04 | 2 bình luận | Chia sẻ qua WhatsApp
  • Lớp dữ liệu quản lý trạng thái được thiết kế để có thể phát triển ứng dụng hiệu năng cao mà không phải gánh nặng về việc phát triển logic đồng bộ
  • Điểm nổi bật là sử dụng SQLite phản ứng (reactive) và công cụ đồng bộ tích hợp
  • Ưu tiên cục bộ (Local-first) nên vẫn cung cấp hiệu năng cao khi ngoại tuyến và hỗ trợ tự động đồng bộ khi mạng được khôi phục
    • Mọi thao tác quản lý trạng thái đều được thực hiện nhanh chóng trên cơ sở dữ liệu SQLite cục bộ
  • Luồng dữ liệu phản ứng: khi dữ liệu thay đổi, sự kiện sẽ được phát ngay tới các listener được kết nối với UI, cho phép phản ánh thay đổi trạng thái theo thời gian thực
  • Có thể áp dụng trong nhiều môi trường khác nhau như web, di động, desktop
  • So với các công cụ quản lý trạng thái hiện có, giải pháp này cho kết quả vượt trội về hiệu năng gốc và tính nhất quán dữ liệu

2 bình luận

 
laeyoung 2025-06-04

Bản demo ngay trên trang chủ thật sự được làm rất tốt. Chỉ cần bấm thử một lúc là đủ khiến người ta muốn dùng thử.

 
GN⁺ 2025-06-04
Ý kiến trên Hacker News
  • Xin chào, mình là đồng sáng lập của LiveStore (trước đây từng làm Prisma).
    Trong 4 năm qua, khi xây dựng Overtone, một client nhạc hiệu năng cao ở mức native, mình đã phát triển LiveStore để tự dùng cho chính mình.
    LiveStore bổ sung một lớp tín hiệu phản ứng lên trên SQLite và kết hợp với đồng bộ dựa trên event sourcing (tương tự Git)

    • Mình đã đánh giá khá nhiều môi trường local-first, nhưng hầu như không có giải pháp nào xử lý gọn gàng như LiveStore
      Một công cụ trưởng thành tương tự là tinyBase, nhưng cấu trúc của nó khác (CRDTs so với event sourcing)
      Mình có điều thắc mắc là vì sao lại giới hạn dung lượng dữ liệu ở 1GB, và liệu có thể thêm tùy chọn để lưu dữ liệu lớn hơn trong SQLite và giữ lại trên đĩa hay không
      Có phải chỉ cần đổi chế độ persistence bằng cấu hình là được không?
      Multi-tenancy cũng có thể là một kịch bản thú vị; khi mỗi tổ chức cần một namespace riêng như JIRA, sẽ tốt hơn nếu mỗi người dùng cũng chỉ nhận dữ liệu của nhóm/bộ phận mình thay vì toàn bộ ticket
      Về cơ bản, đây sẽ là cấu trúc mà cơ sở dữ liệu cục bộ là một tập con của toàn bộ dữ liệu. Nếu có sẵn một sync server chạy trực tiếp trên Bun/Node (không cần Cloudflare) thì sẽ cực kỳ tuyệt
      Có vẻ nó cũng rất hợp với một ý tưởng dự án mình đang cân nhắc, nhất là vì multi-tenancy là yêu cầu bắt buộc

    • Tháng trước mình có định thử LiveStore cho một dự án cá nhân, nhưng vì đang là bản beta preview nên khó tiếp cận
      Hy vọng sớm có thể tìm hiểu sâu hơn. Mình rất ấn tượng với cách các bạn chủ động dẫn dắt các thảo luận về local-first
      Ai từng làm web app có đồng bộ offline đều sẽ nhận ra ngay sự hữu ích của sync engine

    • Hôm nay mình đã nghe phần trình bày ở Local-First Conf, rất hay
      Phần giải thích về cấu trúc triển khai event sourcing bằng SQLite rất rõ ràng và thuyết phục
      Cảm ơn vì đã tích cực quảng bá SQLite, đặc biệt là OPFS Wasm SQLite, trên web
      PowerSync cũng là bên ủng hộ mạnh mẽ SQLite, nên rất vui khi thấy một trường hợp thành công như LiveStore

    • Khi LiveStore mở rộng mô hình event sourcing ở phạm vi toàn cục, thông thường sẽ đồng bộ với mọi client thông qua một backend sync trung tâm; mình muốn hỏi liệu đây có phải là yêu cầu bắt buộc không
      Liệu có thể hỗ trợ các node liên hợp (federated nodes) hoặc một chế độ P2P hoàn chỉnh không? Mình cũng đang cân nhắc việc áp dụng cho các trường hợp mạng xã hội phân tán

    • Mình tò mò liệu khi kết hợp với React và WASM, LiveStore có thể thay thế framework Juce mà đa số ứng dụng âm nhạc đang dùng hay không
      Mình là beatmaker, và việc dùng Juce cùng C++ lúc nào cũng khó và đáng sợ. Mình muốn biết liệu LiveStore có thể là một lựa chọn thay thế tốt cho những ai muốn bước vào phát triển ứng dụng âm nhạc không

  • Mình đã xem bài nói ở Local-first Conf, dạo này đúng là có rất nhiều sync engine mới xuất hiện
    LiveStore đang đào sâu vào một mảng thú vị là kết hợp event sourcing với sync engine
    Mình ngạc nhiên vì hệ thống đã trở nên vững chắc đến vậy rồi
    Trong vài tuần gần đây mình đã trực tiếp dùng nó cho một dự án mới, và nó đang vận hành rất mượt

  • Chúc mừng ra mắt! Mình muốn hỏi liệu hệ thống này có phù hợp với chiến lược "1. Serialization" được mô tả ở đây không
    Như đã nhắc trong ProseMirror-collab, mình muốn hỏi liệu LiveStore có gặp vấn đề khi một client độ trễ thấp cập nhật thường xuyên có thể chặn cập nhật từ client độ trễ cao hơn hay không

  • Có vẻ LiveStore dùng wa-sqlite
    Mình muốn nghe chi tiết hơn về chiến lược persistence dữ liệu offline. Cụ thể là đang dùng OPFS (các biến thể như AccessHandlePoolVFS) hay IndexedDB, hoặc là cả hai?
    Ngoài ra, LiveStore xử lý thế nào với sự thiếu ổn định của OPFS giữa các trình duyệt và chính sách lưu trữ 7 ngày của Safari IndexedDB?
    Mình cũng muốn biết vì sao lại dùng wa-sqlite dù SQLite đã cung cấp bản build WASM chính thức

  • Gần đây bọn mình có nhắc ngắn về LiveStore trên podcast LocalFirst.fm (xem liên kết https://www.localfirst.fm/24)

    • Cảm ơn vì đã chia sẻ tập đó, bọn mình cũng đang chuẩn bị một tập riêng chỉ về LiveStore
  • Trông đây là một dự án rất đáng mong đợi, nhưng mình cũng hơi thận trọng vì sợ rơi vào bẫy cường điệu
    Mình cũng đang thử nghiệm hỗ trợ đa thiết bị khi tự xây một ứng dụng local-first tương tự
    Mình muốn hỏi liệu có thể thêm mã hóa E2E một cách tùy chọn hay không. Theo tài liệu thì có vẻ chỉ cần thêm mã hóa ở cấp payload của event là gần như làm được, ngoại trừ việc sẽ khó nén log phía server hơn

    • Mình đồng ý với ý kiến về "bẫy cường điệu"
      Mình đang tự xây LiveStore dựa trên nhu cầu nảy sinh khi làm Overtone
      Cả LiveStore lẫn Overtone đều đang được phát triển với mục tiêu bền vững dài hạn. Về E2E encryption thì cấu trúc hiện tại đã có thể hỗ trợ
      Dù mình chưa tự làm thử, nhưng nếu có vấn đề thì mình luôn sẵn sàng hỗ trợ
      Một hướng khác có thể là chỉ thử compaction ở phía client. Khi làm kỹ thuật, mình chắc chắn cũng sẽ ghi nhớ trường hợp sử dụng này
  • Mình hoài nghi về tuyên bố hỗ trợ đa nền tảng, vì điều đầu tiên mình thấy là web trên Android chưa được hỗ trợ

    • Nhận xét rất hợp lý. Bọn mình vẫn đang tiếp tục trao đổi với đội Android/Chrome về các vấn đề kỹ thuật. Bọn mình đã xác định được nguyên nhân từ khoảng 3 năm trước, nhưng đến nay vẫn chưa được giải quyết, nên có vẻ LiveStore sẽ phải tự đưa ra giải pháp vòng tránh riêng
      Bạn có thể theo dõi tiến triển trên GitHub chính thức (https://github.com/livestorejs/livestore/issues/321)
      Mong bạn thông cảm rằng để xây dựng một hệ thống đầy tham vọng như vậy, trong bối cảnh mức hỗ trợ web API khác nhau giữa các nền tảng, sẽ cần rất nhiều công sức và thời gian
  • Có một chi tiết thú vị trong video demo! Ở mốc 1 phút 7 giây, mình thấy hiện tượng âm thanh lệch sang trái. Chỉ là chi tiết nhỏ thôi nhưng nghĩ là nên báo để các bạn biết

  • Mình thấy ấn tượng khi các bạn còn cung cấp cả devtools, có vẻ đã thử nghiệm trong các dự án nội bộ một thời gian dài
    Điều mình tò mò là về dài hạn các bạn định xử lý compaction cho app/trang chạy lâu như thế nào, và dù event sourcing là một khái niệm hay, khi tầng ứng dụng phát triển thì việc quản lý code (client phiên bản cũ, schema migration, v.v.) có thể trở nên khó khăn
    Có vẻ Overtone hỗ trợ nhiều nguồn khác nhau; mình muốn hỏi liệu có hỗ trợ phát offline không, nhất là vì UI của Spotify quá bất tiện nên mình rất muốn có giải pháp thay thế

    • Câu hỏi rất hay! Bọn mình đã nhận được nhiều câu hỏi về compaction và sẽ sớm công bố giải pháp
      Ý tưởng cốt lõi là gán thêm thông tin ngữ nghĩa cho từng event để có thể định nghĩa sự chồng lấn giữa các event
      Ví dụ trong một ứng dụng todo, event "todoCompleted" của cùng một task ID có thể nén gọn các event "todoCompleted"/"todoUncompleted" khác của task đó
      Bạn có thể theo dõi tiến triển trên GitHub (https://github.com/livestorejs/livestore/issues/254)
      Event sourcing đúng là đòi hỏi kỷ luật và thiết kế rất nhiều. Với dữ liệu thì không có "bữa trưa miễn phí", nên cốt lõi vẫn là trade-off
      Với các trường hợp sử dụng chính của mình như Overtone, mình cảm thấy trade-off của event sourcing là phù hợp hơn
      Về hỗ trợ phiên bản cũ, v.v., có nhiều cách khá đơn giản để xử lý, nhưng cuối cùng vẫn phụ thuộc vào đặc tính của từng ứng dụng và trade-off tương ứng
      Cảm ơn bạn đã quan tâm đến Overtone. Mình cũng bắt đầu dự án này vì không hài lòng với Spotify. Với phát offline thì điều đó phụ thuộc vào nhà cung cấp nhạc
      Ví dụ, các album bạn sở hữu và lưu trên Dropbox có thể hỗ trợ, còn các dịch vụ streaming như Spotify thì có thể khác tùy theo chính sách
  • Mình thích kiến trúc này, đặc biệt là event sourcing
    Nhưng event sourcing cần được dùng cẩn thận: việc materialize theo view mong muốn có thể chậm, và sẽ càng chậm hơn khi dữ liệu lớn dần
    Giải pháp cho chuyện này là phải trực tiếp quản lý cập nhật materialize trong transaction bằng trigger hoặc các cơ chế tương tự
    Khi replicate hoặc sync cũng cần tính đến điều đó, và về giải quyết xung đột thì nhất định nên nắm vững các khái niệm CRDT
    Nếu có một cơ sở dữ liệu kiểu SQLite3 nhưng có các tính năng ngôn ngữ của Postgres thì sẽ rất tuyệt, vì local-first và remote-first khi đó có thể chỉ cần đổi cấu hình là dùng được

    • Về ý cuối, bạn có thể tham khảo pglite.dev (https://pglite.dev)
      Còn về điểm chính là chi phí materialize, bọn mình sẽ tiếp tục cải thiện compaction, và toàn bộ LiveStore là một framework được thiết kế rất cẩn thận với mục tiêu tối ưu hiệu năng