2 คะแนน โดย GN⁺ 2024-06-27 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Triplit เป็นฐานข้อมูลโอเพนซอร์สที่ซิงก์ข้อมูลแบบเรียลไทม์ระหว่างเซิร์ฟเวอร์กับเบราว์เซอร์ และวางตำแหน่งตัวเองเป็น ฐานข้อมูลฟูลสแตก ที่ใช้งานได้โดยใส่เป็นแพ็กเกจ Typescript ในแอป
  • รองรับทั้งการจัดเก็บบนเซิร์ฟเวอร์และการซิงก์คิวรีของไคลเอนต์ พร้อมสนับสนุน incremental updates, การแก้ไขความขัดแย้งระดับพร็อพเพอร์ตี, local caching, โหมดออฟไลน์ และการเชื่อมต่อใหม่อัตโนมัติ
  • รองรับ สตอเรจแบบปลั๊กอิน เช่น SQLite, IndexedDB, LevelDB และ Memory พร้อมมี persistent storage ฝั่งเซิร์ฟเวอร์และแดชบอร์ดสำหรับจัดการ
  • ใช้งาน API สำหรับคิวรีและการเปลี่ยนแปลงได้ทั้งใน React และ vanilla Javascript และถูกจัดมาในรูปแบบ monorepo ที่ประกอบด้วย React·Svelte bindings, CLI, Console และ Server
  • มีทั้ง optimistic updates เพื่อให้ตอบสนองได้รวดเร็ว, การ rollback·retry สำหรับอัปเดตที่ล้มเหลว, สิทธิ์การอ่าน·เขียนที่บังคับใช้จากเซิร์ฟเวอร์ และความสามารถด้านการทำงานร่วมกันบนพื้นฐาน CRDT

สิ่งที่ Triplit มอบให้

  • Triplit เป็นฐานข้อมูลโอเพนซอร์สที่ ซิงก์ข้อมูลแบบเรียลไทม์ ระหว่างเซิร์ฟเวอร์กับเบราว์เซอร์
  • ให้ ที่เก็บข้อมูลแบบซิงก์ ที่สามารถเพิ่มเข้าไปในแอปได้ในรูปแบบแพ็กเกจ Typescript
  • จัดเก็บข้อมูลบนเซิร์ฟเวอร์ และซิงก์คิวรีของไคลเอนต์อย่างชาญฉลาด
  • Triplit เรียกรูปแบบนี้ว่า ฐานข้อมูลฟูลสแตก
    • มีวิดีโองานนำเสนอในชุมชน Local First ให้ดูด้วย: presentation

ฟีเจอร์หลัก

  • การซิงก์แบบเรียลไทม์

    • รองรับ incremental updates
    • มีการแก้ไขความขัดแย้งระดับพร็อพเพอร์ตี
  • ประสบการณ์ใช้งานแบบ local-first

    • มี local caching บนพื้นฐานฐานข้อมูลฝั่งไคลเอนต์เต็มรูปแบบ
    • ทำให้ทุกการโต้ตอบรู้สึกรวดเร็วด้วย optimistic updates
    • รองรับโหมดออฟไลน์, การเชื่อมต่อใหม่อัตโนมัติ และการรับประกันความสอดคล้องของข้อมูล
  • การจัดเก็บและการปฏิบัติการบนเซิร์ฟเวอร์

    • มี persistent storage ฝั่งเซิร์ฟเวอร์
    • รวมแดชบอร์ดสำหรับจัดการมาให้
    • รองรับ ผู้ให้บริการสตอเรจแบบปลั๊กอิน เช่น SQLite, IndexedDB, LevelDB และ Memory
  • โมเดลข้อมูลและ API

    • รองรับ relational queries สำหรับโมเดลข้อมูลที่ซับซ้อน
    • ให้ความปลอดภัยของข้อมูลและการเติมโค้ดอัตโนมัติของ Typescript ผ่าน schema
    • มี API แบบเรียบง่ายสำหรับคิวรีและการเปลี่ยนแปลง ทั้งใน vanilla Javascript และ React
  • การทำงานร่วมกันและความปลอดภัย

    • บังคับใช้สิทธิ์ทั้งการอ่านและการเขียนจากฝั่งเซิร์ฟเวอร์
    • มีฟีเจอร์การทำงานร่วมกัน·มัลติเพลเยอร์บนพื้นฐาน CRDTs
    • ใช้ delta patches เพื่อลดทราฟฟิกเครือข่ายและมุ่งสู่ latency ต่ำ
    • จัดการการ rollback และ retry สำหรับอัปเดตที่ล้มเหลว

องค์ประกอบของ monorepo

  • TriplitDB: DB ที่ออกแบบมาให้ทำงานในสภาพแวดล้อม JS เช่น เบราว์เซอร์, Node, Deno และ React Native โดยให้คิวรีที่รวดเร็วและอัปเดตแบบสด พร้อมรักษาความสอดคล้องในเครือข่ายที่มีผู้เขียนหลายราย
  • Client: ไลบรารีเบราว์เซอร์สำหรับโต้ตอบกับ TriplitDB ทั้งแบบโลคัลและระยะไกล
  • CLI: เครื่องมือบรรทัดคำสั่งสำหรับ scaffold โปรเจ็กต์, รันสภาพแวดล้อมพัฒนาแบบฟูลสแตก และทำ server migrations
  • React: React bindings สำหรับ @triplit/client
  • Svelte: Svelte bindings สำหรับ @triplit/client
  • Console: แอปสำหรับดูและแก้ไขข้อมูลโปรเจ็กต์ Triplit รวมถึงจัดการ schema
  • Server: เซิร์ฟเวอร์ Node ที่ซิงก์ข้อมูลระหว่างไคลเอนต์ Triplit
  • Server-core: ไลบรารีที่ไม่ผูกกับโปรโตคอล สำหรับสร้างเซิร์ฟเวอร์ Triplit
  • Docs: เอกสารของ Triplit ที่สร้างด้วย Nextra
  • Types: ชนิดข้อมูลที่โปรเจ็กต์ Triplit ใช้ร่วมกัน
  • UI: คอมโพเนนต์ UI ที่ใช้ร่วมกันบนพื้นฐาน shadcn

ขั้นตอนเริ่มต้นอย่างรวดเร็ว

  • โปรเจ็กต์ใหม่เริ่มได้ด้วย npm create triplit-app@latest my-app
  • สำหรับโปรเจ็กต์เดิม ให้ติดตั้ง @triplit/cli เป็น development dependency แล้วรัน npm run triplit init
  • กำหนด schema ใน my-app/triplit/schema.ts
    • ตัวอย่างกำหนดฟิลด์ id, text, completed ในคอลเลกชัน todos
    • completed ถูกตั้งเป็นฟิลด์ Boolean ที่มีค่าเริ่มต้นเป็น false
  • เริ่ม เซิร์ฟเวอร์ซิงก์ สำหรับพัฒนาด้วย npm run triplit dev
  • เซิร์ฟเวอร์พัฒนาจะแสดง environment variables ที่แอปต้องใช้ในการซิงก์กับเซิร์ฟเวอร์
    • ในตัวอย่าง Vite คือ VITE_TRIPLIT_SERVER_URL=http://localhost:6543
    • VITE_TRIPLIT_TOKEN=copied-in-from-triplit-dev

ตัวอย่างการใช้งาน React และการตรวจสอบการซิงก์

  • ตัวอย่าง React ใช้ TriplitClient และ useQuery
  • ไคลเอนต์ถูกสร้างจาก schema, server URL และ token
  • สมัครรับผลลัพธ์คิวรี todos ด้วย useQuery(client.query('todos'))
  • เมื่อเปลี่ยน checkbox จะสลับค่า completed ด้วย client.update
  • หลังเริ่มแอปแล้ว หากเปิดแท็บเบราว์เซอร์อีกแท็บ จะเห็นว่าข้อมูลถูก ซิงก์แบบเรียลไทม์

เอกสารและช่องทางติดต่อ

  • คู่มือเริ่มต้นทั้งหมด: getting started guide
  • ทัวร์เรียนรู้แบบละเอียดเพิ่มเติม: building a real-time todo app with Triplit, Vite, and React
  • สามารถถามคำถาม, ขอความช่วยเหลือในการเริ่มต้น, และดูตัวอย่างฟีเจอร์ใหม่ล่วงหน้าได้ที่ Discord
  • ติดตามประกาศล่าสุดได้ทาง Twitter/X

1 ความคิดเห็น

 
GN⁺ 2024-06-27
ความคิดเห็นบน Hacker News
  • ได้ลองใช้ Triplit ในโปรเจกต์ https://github.com/thanhnguyen2187/cryptaa แล้ว และมันทำงานได้ตามที่คาดไว้
    โมเดลข้อมูลเข้ากับแนวคิดที่ใกล้เคียงแบบกระจายศูนย์/P2P มากกว่าการมี DB ศูนย์กลางเพียงตัวเดียวเป็นแหล่งความจริง แต่ยังรู้สึกว่า การโฮสต์เอง และ ภาษา query ยังน่าเสียดายอยู่
    วิธีสร้างโทเค็นยืนยันตัวตนของเซิร์ฟเวอร์ในเอกสารไม่ชัดเจน จึงใช้คำสั่ง dev ของ CLI เพื่อสร้างโทเค็น และการที่โทเค็นถูกทิ้งไว้เป็น log แบบ plain text ใน system service นั้นไม่ดีในเชิงความปลอดภัย แต่ผมมองว่าต้องมีปัญหาเรื่องสิทธิ์เข้าถึงที่ใหญ่กว่านั้นเป็นเงื่อนไขอยู่ก่อน
    DSL สำหรับ query แบบกำหนดเองขาดความสามารถในการแสดงออกอย่าง UNIQUE, COUNT แบบ SQL ทำให้ต้องทำ aggregation บางส่วนเอง
    ช่วงหลังได้ดู Evolu https://www.evolu.dev/docs แล้วดูเหมือนมีขอบเขตและฟีเจอร์คล้ายกัน โดย Triplit มี .subscribe() แต่ Evolu ไม่มี ส่วน Evolu เป็น typed SQL ที่อิงกับ Kysely ทำให้ query คุ้นเคยและขั้นสูงกว่า และบนเบราว์เซอร์ Evolu ใช้ SQLite บน OPFS ขณะที่ Triplit ดูเหมือนจะใช้ IndexedDB
    โพสต์ที่ลงใน Reddit: https://www.reddit.com/r/sveltejs/comments/1dndpj8/cryptaa_a...

    • เอกสารการโฮสต์เองกำลังถูกจัดระเบียบให้การตั้งค่าชัดเจนขึ้น และจุดที่คุณชี้มามีประโยชน์มาก
      ฝั่ง query ตอนนี้ยังไม่มี aggregation แต่มีอยู่ใน roadmap และคิดว่าถ้าใช้ประโยชน์จาก incremental query engine จะเปิดทางที่น่าสนใจได้
      เช่น data dashboard ที่อัปเดตทุกชั่วโมง ในระบบเดิม ๆ (Postgres, MongoDB ฯลฯ) ต้องรัน query ใหม่ตั้งแต่ต้นทุกครั้ง แต่ถ้าประมวลผลเฉพาะข้อมูลใหม่ในแนวทางที่ใกล้เคียงกับ Materialize ก็จะอัปเดตต่อเนื่องได้อย่างมีประสิทธิภาพกว่ามาก
      ยังไม่ได้ลองใช้ Evolu เอง แต่ใน Discord อาจมีคนที่เคยเปรียบเทียบอยู่: https://triplit.dev/discord
    • ขอบคุณที่แนะนำ Evolu ทั้ง Triplit และ Evolu ดูน่าสนใจ เลยอยากเห็นการเปรียบเทียบระหว่างสองตัวนี้
    • Evolu ก็รองรับ subscribe ผ่าน useQuery หรือวิธีที่แยกออกมาต่างหากเช่นกัน
  • เวลาจะใช้ DB ที่มี โปรโตคอลซิงก์แบบออฟไลน์ ดี ๆ แบบนี้ อยากรู้ว่าจัดการ schema evolution กันอย่างไรในสถานการณ์ที่อัปเกรดไคลเอนต์หลายเวอร์ชันพร้อมกันไม่ได้
    เคยมีบริบทที่ต้องปวดหัวกับปัญหานี้ในแอปสุขภาพบนมือถือมาก่อน

    • ทางที่ดีคือสร้างแค่ตารางใหม่ และอย่าทำ การเปลี่ยนแปลงที่ทำลายความเข้ากันได้ กับตารางเดิม
      ถ้าจำเป็นก็ต้องทำ dual write ไปยังทั้งสองเวอร์ชันพร้อมกัน
      คล้ายกับการทำ live migration แบบไม่หยุดระบบสำหรับการเปลี่ยนแปลงที่ทำลายความเข้ากันได้ใน SQL DB แต่จุดเปลี่ยนผ่านขึ้นอยู่กับลูกค้า จึงต้องเก็บตรรกะนั้นไว้นานกว่า
      ตารางที่ใช้ประสานเวอร์ชันล่าสุดก็สำคัญ และถ้ามีการเปลี่ยนแปลงที่ทำให้ใช้ร่วมกันไม่ได้ ก็ควรให้ไคลเอนต์ที่ตามหลังแจ้งผู้ใช้ให้อัปเกรด
      ยังสามารถกำหนดได้ว่าจะต้องคงการอ่าน/เขียนสองทางไว้นานแค่ไหน โดยผูกกับเวอร์ชันขั้นต่ำที่ไคลเอนต์ทั้งหมดรองรับ
    • พูดสั้น ๆ คือ วิธีที่รับประกันความเข้ากันได้ง่ายที่สุดคือรักษา ความเข้ากันได้ย้อนหลัง ของ schema
      Triplit จะแสดงคำเตือนเมื่อคุณสร้างการเปลี่ยนแปลงที่ไม่เข้ากันได้ย้อนหลัง ดูได้ในเอกสาร: https://www.triplit.dev/docs/schemas/updating#pushing-the-sc...
      แต่เมื่อเวลาผ่านไป อาจเกิดนิยาม schema ที่รกและมีชื่อชวนสับสนจำนวนมากขึ้นตามธรรมชาติ
      ตอนนี้ยังไม่ได้ปล่อยโซลูชันสำหรับแก้เรื่องนี้ แต่กำลังทำบางอย่างให้เจ็บตัวน้อยลง และสำหรับพื้นหลังของแนวทางต่าง ๆ เอกสาร Cambria ถือว่ายอดเยี่ยม: https://www.inkandswitch.com/cambria/
    • ผมคิดว่าไคลเอนต์บางตัว เช่นเซิร์ฟเวอร์ ควรซิงก์กับ schema ที่เก่ามาก ๆ ได้ด้วย
      ผู้ใช้อาจเก็บมือถือไว้ในลิ้นชักเป็นเวลา 2 ปี ดังนั้นแต่ละไคลเอนต์ก็แค่มายเกรตตัวเองให้เร็วที่สุดเท่าที่ทำได้
    • ถ้ามี วิธีในตัว สำหรับนิยามและรองรับ migration ในอดีต น่าจะเป็น killer feature
      ทุกคนจะได้ไม่ต้องคิดระบบจัดการ migration ของตัวเองขึ้นมาใหม่
  • ยังไม่ค่อยเข้าใจว่าแอปแบบไหนที่การให้ไคลเอนต์เขียนลง DB ได้โดยตรงเป็นเรื่องโอเค และจะอยู่รอดได้อย่างไรโดย ไม่มี backend logic
    มีข้อสงสัยเดียวกันกับ Supabase และ Firestore ด้วย เลยรู้สึกว่าน่าจะพลาดอะไรไปบางอย่าง

    • สิ่งที่ถูกสร้างขึ้นส่วนใหญ่ในโลกจริงแทบไม่มี business logic และใกล้เคียงกับ CRUD เฉย ๆ
      ในสภาพแวดล้อมองค์กร แน่นอนว่าตรงกันข้าม และผมหงุดหงิดเวลาเห็นการคุยที่มองข้ามเรื่องนี้
      โดยเฉพาะเวลาเห็นคนใน tech Twitter สนับสนุนสแตกหรือวิธีทำงานบางแบบ จะเห็นชัดมากว่าเขาเคยทำแต่ CRUD โดยไม่เคยสร้างระบบธุรกิจจริง ๆ เลย จึงมักไม่เข้าใจว่าทำไมนักพัฒนาที่มีประสบการณ์ถึงไม่เห็นด้วย
    • เคยสร้างแอปทำงานร่วมกันด้วย Firebase ถ้าจำกัดอย่างเข้มงวดว่าแต่ละคนทำอะไรกับคอมเมนต์หรือการ์ดของตัวเองได้บ้าง และให้สิทธิ์เฉพาะบาง action ก็พอใช้งานได้
      แต่ดูไม่น่าจะเหมาะกับสิ่งที่มี backend logic เยอะ ๆ
    • ทั้งสองตัวมี access control ที่บังคับใช้ฝั่ง backend ดังนั้นจึงไม่ใช่ว่าไม่มี backend logic เลย
      ใน Supabase มีฟีเจอร์อย่าง row-level security เป็นต้น
      ไคลเอนต์ส่งคำขอไปยัง Supabase ได้ก็จริง แต่ Supabase จะรัน query เพิ่มเติมที่ backend เพื่อตัดสินว่าคำขอที่เข้ามานั้นได้รับอนุญาตหรือไม่
      ตัวอย่างง่าย ๆ คืออนุญาตให้อ่าน เขียน และอัปเดตแถวนั้นได้เฉพาะเมื่อค่าในคอลัมน์ UserID ตรงกับผู้ใช้ที่ยืนยันตัวตนในคำขอเท่านั้น
  • เคยเก็บการตั้งค่าผู้ใช้ไว้ใน Triplit และการตั้งค่าเหล่านี้จำเป็นต้องให้ผู้ดูแลจัดการได้
    ผู้ใช้ต้องรู้สึกว่าแอปทำงานอยู่ในเครื่องเสมอ และคุณภาพอินเทอร์เน็ตก็มักไม่ดี แต่เพราะต้องใช้งานข้ามอุปกรณ์หลายเครื่อง และผู้ดูแลต้องดูและจัดการการตั้งค่าของผู้ใช้อื่นได้ จึงจำเป็นต้องมี การซิงก์
    โดยรวมแล้ว Triplit ยอดเยี่ยมทั้งในด้านประสบการณ์นักพัฒนา frontend และการสนับสนุน เมื่อพบ issue หรือ feature request ทีมก็จัดการให้อย่างรวดเร็วมาก
    ถ้ามีคำตอบเรื่อง การ deploy แบบ high availability แล้ว ก็มีแผนจะย้ายข้อมูลที่สำคัญกว่านี้จาก Postgres มาด้วย

  • สงสัยว่าทำไมถึงเลือกไลเซนส์ AGPL

    • ต้องการให้ Triplit self-host ได้ง่ายภายใต้ไลเซนส์ AGPL พร้อมทั้งรับประกันว่าคนที่แก้ไขจะมีส่วนร่วมส่งการเปลี่ยนแปลงนั้นกลับคืนให้ชุมชน
    • แต่ถ้าฐานข้อมูลที่ใช้ทำให้ต้องทำให้ผลิตภัณฑ์เป็น AGPL ด้วย ก็อยากหลีกเลี่ยง
  • เหมือนเคยเห็นการนำเสนอบน YouTube https://www.youtube.com/playlist?list=PLTbD2QA-VMnXFsLbuPGz1... ในเซิร์ฟเวอร์ Discord ของ Local First https://localfirstweb.dev/ เลยดีใจที่ได้เห็นใน Show HN
    อาจไม่ใช่กลุ่มเป้าหมายหลักเพราะไม่ได้ใช้ TypeScript และโดยมากใช้แนวทาง local-first กับแอปมือถือที่การเชื่อมต่อไม่เสถียร ต่างจากเว็บ โดยใช้ Flutter กับ backend ที่เป็น Rust
    โซลูชัน local-first อื่น ๆ อย่าง ElectricSQL และ PowerSync ซิงก์ฐานข้อมูลฝั่ง client กับ server โดยตรง จึงเป็นอิสระจาก client/server มากกว่า
    โซลูชันที่ใช้ CRDT ก็ใช้ได้ทั้งฝั่ง client และ server ผ่าน FFI เช่น automerge เป็น Rust จึงใช้กับ Flutter ผ่าน FFI ด้วย flutter_rust_bridge หรือบนเว็บผ่าน WASM และบน backend ด้วย Rust ได้
    Triplit ดูเหมือนเป็นการซิงก์ client-server แบบดั้งเดิมมากกว่า โดยให้ server เป็นแหล่งความจริง แทนที่จะเป็นการแก้ conflict ระหว่าง client ต่าง ๆ แบบไร้การชนกัน
    สงสัยว่าทำไมถึงเลือก โซลูชันระดับภาษา แทนแนวทางชั้นฐานข้อมูลที่เป็นอิสระจาก client และ server มากกว่า และดูเหมือนในอนาคตจะรองรับภาษาและ framework ที่ไม่ใช่ฐาน JS ได้ยาก
    อีกทั้งดูเหมือนจะพยายามแข่งกับ Supabase แต่ Supabase เองก็กำลังทดลองการซิงก์ระดับฐานข้อมูลของ Postgres และ CRDT อยู่ จึงอาจไล่ทันได้ https://news.ycombinator.com/item?id=33931971

    • คิดเรื่องการรองรับ Flutter และ native อื่น ๆ มามากแล้ว โดยเฉพาะ Flutter ที่ถูกพูดถึงบ่อย
      แต่ตอนเริ่มต้นตัดสินใจโฟกัสที่ TypeScript ล้วน เพราะตลาดใหญ่พอ เชื่อในอนาคตของ PWA และมองว่าต้องโฟกัสตรงนั้นจึงจะสร้างประสบการณ์ที่ดีที่สุดได้
      สักวันหนึ่งคงจะสร้างอะไรที่เป็นอิสระจากแพลตฟอร์มมากกว่านี้ แต่ยังไม่แน่ชัดว่าเมื่อไร
      ทั้งทีม ElectricSQL และ Supabase ล้วนยอดเยี่ยมและรอบคอบ และน่าจะเติบโตต่อไปในสาย SQL ซึ่งนี่คือความแตกต่างพื้นฐานที่สุดของแนวทาง
      Triplit มองว่าการหลีกเลี่ยง SQL จะให้ประสบการณ์ที่ดีที่สุดแก่นักพัฒนาได้ และมีพื้นที่มากพอให้ทั้งสองปรัชญาอยู่ร่วมกัน
  • ถ้าเป็น LWW สงสัยว่าปริมาณข้อมูลของ client จะเพิ่มแบบเชิงเส้นตามจำนวน operation หรือไม่
    กล่าวคือ ยิ่งผู้ใช้แก้ไข DB มากขึ้น operation log ก็จะโตขึ้นเรื่อย ๆ หรือมี checkpoint หรือไม่ และถ้าผู้ใช้ทำ operation หลายล้านครั้งต่อวัน จะขยายตัวในแง่พื้นที่อย่างไร

    • Triplit เก็บประวัติการแก้ไขของ attribute เฉพาะ แต่ query ยังเร็วอยู่ด้วย index ของค่าล่าสุด
      อย่างไรก็ตาม LWW register เองไม่ได้บังคับว่าต้องเก็บประวัติ นี่เป็นเพียง implementation ปัจจุบันเพื่อให้ client ที่ offline ไปนานสามารถซิงก์ได้อย่างมีประสิทธิภาพ
      ยังพูดได้ไม่เต็มปากว่ารองรับถึงวันละหนึ่งล้าน operation แล้ว แต่ข้อดีคือ server มีอำนาจตัดสิน
      ในอนาคต Triplit server สามารถติดตาม timestamp การซิงก์ล่าสุดของ client แต่ละราย และค่อย ๆ prune ประวัติได้ คล้ายกับวิธีที่ Postgres ใช้ VACUUM จัดการ tuple ที่ตายแล้ว
  • ถ้ามี Rust bindings ให้ใช้กับ Tauri ได้ก็คงดี
    เมื่อรวมการเติบโตของ Tauri การรองรับอุปกรณ์มือถือที่กำลังจะมา และความนิยมของ SQLite ในช่วงหลัง อาจช่วยเติมช่องว่างของแอปแบบ offline-first และกลายเป็นตัวเลือกเริ่มต้นของทีมพัฒนาจำนวนมากได้

    • กำลังจะเพิ่ม Rust bindings ให้ ElectricSQL ซึ่งเป็นโซลูชันซิงก์ที่คล้ายกัน
      ElectricSQL ทำงานที่ชั้นฐานข้อมูลจึงเป็นอิสระจากภาษา และใช้ Rust บน server อยู่แล้ว ดังนั้น Rust bindings จึงทำงานได้ทั้งฝั่ง client และ server
      ถ้าอยากร่วมพัฒนาก็บอกได้
    • คิดว่า Tauri ใช้ native web renderer ไม่ใช่หรือ
      ถ้าเป็นอย่างนั้น Triplit ก็น่าจะทำงานได้ทันที
  • ใช้ Triplit ในแอป React Native มาพักหนึ่งแล้ว และทำงานได้ดีมาก
    แนะนำอย่างยิ่ง และเป็น DB แบบ local-first ตัวเดียวที่ตอบโจทย์เงื่อนไขที่ต้องการทั้งหมด
    มี query language ที่เหมาะสมและ sane (ไม่ใช่ SQL), รองรับ TypeScript ดีเยี่ยม, รองรับ offline, รองรับ React Native และยังดีที่เป็น open source กับ self-host ได้

  • สงสัยว่าใช้ร่วมกับ PostgreSQL DB ที่มีอยู่แล้วไม่ได้หรือ

    • ตอนนี้ยังไม่ได้ แต่มีเครื่องมือภายในที่ทำ การซิงก์สองทาง โดยใช้ replication protocol ของ Postgres และ WAL2JSON
      ยังไม่พร้อมเปิดเผย แต่ตั้งใจว่าจะให้คนได้ลองใช้เร็ว ๆ นี้
    • ลองดู ElectricSQL ที่ทำงานกับ Postgres เดิมได้ก็น่าจะดี
      ผมเองก็กำลังเอนเอียงไปทางใช้ตัวนั้น