2 poin oleh GN⁺ 2024-06-27 | 1 komentar | Bagikan ke WhatsApp
  • Triplit adalah database open-source yang menyinkronkan data secara real-time antara server dan browser, dan memosisikan diri sebagai database full-stack yang dapat dimasukkan ke aplikasi sebagai paket Typescript
  • Menangani penyimpanan server sekaligus sinkronisasi kueri klien, serta mendukung pembaruan inkremental, penyelesaian konflik pada tingkat atribut, caching lokal, mode offline, dan reconnect otomatis
  • Mendukung penyimpanan pluggable seperti SQLite, IndexedDB, LevelDB, dan Memory, serta menyediakan penyimpanan persisten di sisi server dan dashboard administrasi
  • API kueri dan perubahan dapat digunakan di React dan vanilla Javascript, serta disediakan sebagai monorepo yang terdiri dari binding React·Svelte, CLI, Console, Server, dan lainnya
  • Menyediakan optimistic update untuk interaksi cepat, rollback dan retry untuk update yang gagal, izin baca/tulis yang ditegakkan di server, serta fitur kolaborasi berbasis CRDT

Yang disediakan Triplit

  • Triplit adalah database open-source yang menyinkronkan data secara real-time antara server dan browser
  • Menyediakan penyimpanan data sinkronisasi yang dapat ditambahkan ke aplikasi sebagai paket Typescript
  • Menyimpan data di server dan secara cerdas menyinkronkan kueri klien
  • Triplit menyebut bentuk ini sebagai database full-stack
    • Video presentasi komunitas Local First juga tersedia: presentation

Fitur utama

  • Sinkronisasi real-time

    • Mendukung pembaruan inkremental
    • Menyediakan penyelesaian konflik pada tingkat atribut
  • Pengalaman local-first

    • Menyediakan caching lokal berbasis database sisi klien yang lengkap
    • Membuat semua interaksi terasa cepat dengan optimistic update
    • Mendukung mode offline, reconnect otomatis, dan jaminan konsistensi
  • Penyimpanan dan operasi server

    • Menyediakan penyimpanan persisten di sisi server
    • Menyertakan dashboard administrasi
    • Mendukung penyedia penyimpanan pluggable seperti SQLite, IndexedDB, LevelDB, dan Memory
  • Model data dan API

    • Mendukung kueri relasional untuk model data yang kompleks
    • Menyediakan keamanan data dan autocomplete Typescript melalui skema
    • Menyediakan API sederhana untuk kueri dan perubahan di vanilla Javascript dan React
  • Kolaborasi dan keamanan

    • Menegakkan izin untuk baca maupun tulis di server
    • Menyediakan fitur kolaborasi dan multiplayer berbasis CRDTs
    • Menggunakan delta patch untuk mengurangi traffic jaringan dan menargetkan latensi rendah
    • Mengelola rollback dan retry untuk update yang gagal

Struktur monorepo

  • TriplitDB: DB yang dirancang untuk berjalan di lingkungan JS seperti browser, Node, Deno, dan React Native; menyediakan kueri yang cepat dan live-updating sambil menjaga konsistensi dengan banyak penulis di jaringan
  • Client: Library browser untuk berinteraksi dengan TriplitDB lokal dan remote
  • CLI: Tool command-line untuk scaffolding proyek, menjalankan lingkungan pengembangan full-stack, migrasi server, dan lainnya
  • React: Binding React untuk @triplit/client
  • Svelte: Binding Svelte untuk @triplit/client
  • Console: Aplikasi untuk melihat dan mengubah data proyek Triplit serta mengelola skema
  • Server: Server Node yang menyinkronkan data antar-klien Triplit
  • Server-core: Library yang tidak bergantung protokol untuk membuat server Triplit
  • Docs: Dokumentasi Triplit yang dibuat dengan Nextra
  • Types: Tipe yang dibagikan oleh proyek-proyek Triplit
  • UI: Komponen UI bersama berbasis shadcn

Alur quick start

  • Proyek baru dimulai dengan npm create triplit-app@latest my-app
  • Untuk proyek yang sudah ada, instal @triplit/cli sebagai development dependency lalu jalankan npm run triplit init
  • Definisikan skema di my-app/triplit/schema.ts
    • Contohnya mendefinisikan field id, text, dan completed pada koleksi todos
    • completed disetel sebagai field Boolean dengan nilai default false
  • Mulai server sinkronisasi untuk pengembangan dengan npm run triplit dev
  • Server pengembangan menampilkan variabel lingkungan yang diperlukan agar aplikasi dapat tersinkron dengan server
    • Dalam contoh Vite: VITE_TRIPLIT_SERVER_URL=http://localhost:6543
    • VITE_TRIPLIT_TOKEN=copied-in-from-triplit-dev

Contoh penggunaan React dan verifikasi sinkronisasi

  • Contoh React menggunakan TriplitClient dan useQuery
  • Klien dibuat dengan menerima skema, URL server, dan token
  • Berlangganan hasil kueri todos dengan useQuery(client.query('todos'))
  • Saat checkbox berubah, nilai completed dibalik dengan client.update
  • Setelah menjalankan aplikasi lalu membuka tab browser lain, Anda dapat memastikan data tersinkronisasi secara real-time

Dokumentasi dan kanal kontak

1 komentar

 
GN⁺ 2024-06-27
Komentar Hacker News
  • Saya pernah mencoba Triplit di proyek https://github.com/thanhnguyen2187/cryptaa dan berjalan sesuai harapan
    Model datanya lebih cocok dengan gagasan yang lebih terdistribusi/P2P daripada menjadikan satu DB pusat sebagai sumber kebenaran tunggal, tetapi self-hosting dan bahasa kueri terasa kurang memuaskan
    Cara membuat token autentikasi server tidak jelas di dokumentasi, jadi saya membuat token dengan perintah dev di CLI, dan token yang tertinggal sebagai log teks biasa di layanan sistem memang tidak bagus dari sisi keamanan, meski menurut saya itu mengandaikan masalah hak akses yang lebih besar
    DSL kueri kustomnya kurang ekspresif seperti SQL untuk hal-hal seperti UNIQUE dan COUNT, sehingga sebagian agregasi harus dilakukan sendiri
    Baru-baru ini saya melihat Evolu https://www.evolu.dev/docs dan cakupan serta fiturnya tampak mirip; Triplit punya .subscribe() sedangkan Evolu tidak, Evolu memakai SQL bertipe berbasis Kysely sehingga kuerinya lebih familier dan lebih canggih, dan di browser Evolu memakai SQLite di atas OPFS sementara Triplit tampaknya memakai IndexedDB
    Tulisan yang saya unggah di Reddit: https://www.reddit.com/r/sveltejs/comments/1dndpj8/cryptaa_a...

    • Dokumentasi self-hosting sedang kami rapikan agar konfigurasinya lebih jelas, dan poin yang Anda tunjukkan sangat membantu
      Di sisi kueri, agregasi memang belum ada tetapi sudah ada di roadmap, dan menurut kami memanfaatkan mesin kueri inkremental bisa membuka arah yang menarik
      Misalnya, dasbor data yang diperbarui setiap jam, pada sistem yang ada (Postgres, MongoDB, dll.) harus menjalankan ulang kueri dari awal setiap kali, tetapi jika hanya memproses data baru dengan cara yang mirip Materialize, pembaruan berkelanjutan bisa jauh lebih efisien
      Saya belum sempat mencoba Evolu secara langsung, tetapi mungkin ada orang di Discord yang sudah membandingkannya: https://triplit.dev/discord
    • Terima kasih sudah memberi tahu tentang Evolu; Triplit dan Evolu sama-sama terlihat menarik, jadi saya ingin melihat perbandingan keduanya
    • Evolu juga mendukung subscribe melalui useQuery atau pendekatan terpisah
  • Saat memakai DB dengan protokol sinkronisasi offline yang sebagus ini, saya penasaran bagaimana evolusi skema ditangani ketika versi klien yang berbeda tidak bisa di-upgrade secara bersamaan
    Saya pernah mengalami konteks serupa yang merepotkan di aplikasi kesehatan mobile dulu

    • Sebaiknya hanya buat tabel baru dan jangan melakukan perubahan yang memutus kompatibilitas pada tabel yang sudah ada
      Jika perlu, lakukan penulisan ganda ke dua versi sekaligus
      Ini mirip dengan migrasi live tanpa downtime untuk perubahan yang memutus kompatibilitas di DB SQL, tetapi karena titik peralihannya bergantung pada pelanggan, logika tersebut harus dipertahankan lebih lama
      Tabel yang mengoordinasikan versi terbaru juga penting, dan jika ada perubahan yang memutus kompatibilitas, klien yang tertinggal harus meminta pengguna untuk melakukan upgrade
      Anda juga bisa menentukan berapa lama pembacaan/penulisan ganda dipertahankan dengan mengaitkannya ke versi minimum yang didukung di seluruh klien
    • Singkatnya, cara termudah untuk menjamin kompatibilitas adalah menjaga kompatibilitas mundur skema
      Triplit akan menampilkan peringatan jika Anda membuat perubahan yang tidak kompatibel ke belakang, dan ini bisa dilihat di dokumentasi: https://www.triplit.dev/docs/schemas/updating#pushing-the-sc...
      Namun seiring waktu, definisi skema yang berantakan dengan banyak nama membingungkan bisa muncul secara alami
      Kami belum merilis solusi untuk memperbaikinya, tetapi sedang mengerjakan beberapa hal agar prosesnya tidak terlalu menyakitkan; sebagai latar belakang untuk berbagai pendekatan, dokumen Cambria sangat bagus: https://www.inkandswitch.com/cambria/
    • Menurut saya sebagian klien, misalnya server, harus bisa tetap sinkron bahkan dengan skema yang sangat lama
      Pengguna mungkin menyimpan ponselnya di laci selama 2 tahun, jadi tiap klien cukup memigrasikan dirinya sendiri secepat mungkin
    • Jika ada cara bawaan untuk mendefinisikan dan mendukung migrasi lama, itu sepertinya akan menjadi fitur pembunuh
      Semua orang tidak perlu menciptakan ulang cara masing-masing untuk mengelola migrasi
  • Saya kurang paham untuk aplikasi seperti apa klien boleh menulis langsung ke DB, dan bagaimana itu bisa bertahan tanpa logika backend
    Saya punya pertanyaan yang sama tentang Supabase dan Firestore, jadi sepertinya ada sesuatu yang saya lewatkan

    • Sebagian besar hal yang dibuat di dunia nyata hampir tidak punya logika bisnis dan sekadar mirip CRUD
      Di lingkungan enterprise jelas kebalikannya, dan saya frustrasi melihat diskusi yang mengabaikan hal ini
      Terutama saat melihat orang di Twitter teknologi membela stack atau cara kerja tertentu, sering kali sangat jelas bahwa mereka hanya pernah membuat CRUD tanpa pernah membangun sistem bisnis, sehingga mereka tidak paham mengapa developer berpengalaman tidak setuju
    • Saya pernah membuat aplikasi kolaboratif dengan Firebase; kalau pembatasannya ketat, misalnya setiap orang hanya boleh melakukan hal tertentu pada komentar atau kartu miliknya sendiri dan hanya diberi izin untuk tindakan tertentu, itu cukup berjalan
      Sepertinya tidak cocok untuk sesuatu yang punya banyak logika backend
    • Keduanya punya kontrol akses yang ditegakkan di backend, jadi bukan berarti tidak ada logika backend sama sekali
      Di Supabase, misalnya, ada fitur bernama row-level security
      Klien memang bisa mengirim permintaan ke Supabase, tetapi Supabase menjalankan kueri tambahan di backend untuk menentukan apakah permintaan yang masuk diizinkan
      Contoh sederhana: hanya ketika nilai kolom UserID sama dengan pengguna terautentikasi yang membuat permintaan, baris tersebut boleh dibaca, ditulis, dan diperbarui
  • Selama ini pengaturan pengguna disimpan di Triplit, dan pengaturan ini harus bisa dikelola oleh admin
    Pengguna harus merasa aplikasi selalu berjalan secara lokal, dan kualitas internet juga sering tidak bagus, tetapi karena mereka memakai beberapa perangkat secara bergantian dan admin perlu melihat serta mengelola pengaturan pengguna lain, sinkronisasi diperlukan
    Secara keseluruhan, Triplit punya pengalaman developer frontend dan dukungan yang sama-sama sangat baik; ketika menemukan issue atau permintaan fitur, timnya menanganinya dengan sangat cepat
    Jika sudah ada jawaban soal deployment high availability, mereka berencana memindahkan data yang lebih penting juga dari Postgres

  • Penasaran mengapa memilih lisensi AGPL

    • Mereka ingin membuat Triplit mudah di-self-host dengan lisensi AGPL, sekaligus memastikan orang yang memodifikasinya mengontribusikan kembali perubahan itu ke komunitas
    • Mereka ingin menghindari situasi di mana produk juga harus dibuat AGPL karena DB yang digunakan
  • Sepertinya pernah melihat presentasi YouTube https://www.youtube.com/playlist?list=PLTbD2QA-VMnXFsLbuPGz1... di server Discord Local First https://localfirstweb.dev/, jadi senang melihatnya di Show HN
    Karena tidak memakai TypeScript, mungkin saya bukan target utama, dan berbeda dari web, saya terutama memakai pendekatan local-first pada aplikasi mobile dengan koneksi yang tidak stabil, menggunakan Flutter dan backend Rust
    Solusi local-first lain seperti ElectricSQL dan PowerSync menyinkronkan DB klien dan server secara langsung, sehingga lebih independen terhadap klien/server
    Solusi berbasis CRDT juga bisa dipakai di klien dan server lewat FFI; misalnya automerge berbasis Rust, jadi di sisi Flutter bisa dipakai lewat FFI melalui flutter_rust_bridge, di web lewat WASM, dan di backend dengan Rust
    Triplit tampaknya lebih seperti sinkronisasi klien-server klasik yang menempatkan server sebagai sumber kebenaran, bukan penyelesaian konflik tanpa konflik antar-klien yang berbeda
    Penasaran mengapa memilih solusi di level bahasa alih-alih pendekatan lapisan DB yang lebih independen terhadap klien dan server, dan tampaknya akan sulit mendukung bahasa serta framework di luar yang berbasis JS ke depannya
    Selain itu, kelihatannya mereka ingin bersaing dengan Supabase, tetapi Supabase juga sedang bereksperimen dengan sinkronisasi level DB Postgres dan CRDT, jadi bisa saja mengejar https://news.ycombinator.com/item?id=33931971

    • Dukungan Flutter dan native lain sudah banyak dipertimbangkan, dan Flutter khususnya sering dibahas
      Namun untuk awalnya mereka memutuskan fokus pada TypeScript murni; pasarnya cukup besar, mereka percaya pada masa depan PWA, dan menilai bahwa fokus di sana diperlukan untuk membuat pengalaman terbaik
      Suatu saat kemungkinan mereka akan membuat sesuatu yang lebih independen dari platform, tetapi waktunya belum pasti
      Tim ElectricSQL dan Supabase sama-sama hebat dan penuh pertimbangan, dan tampaknya akan terus berkembang di ranah SQL; inilah perbedaan paling mendasar dalam pendekatannya
      Triplit menilai bahwa dengan menghindari SQL, mereka bisa memberi developer pengalaman terbaik, dan ada cukup ruang bagi kedua filosofi untuk hidup berdampingan
  • Jika LWW, penasaran apakah jumlah informasi di klien bertambah linear terhadap jumlah operasi
    Dengan kata lain, semakin banyak pengguna memodifikasi DB, apakah log operasi terus membesar, atau apakah ada checkpoint; penasaran bagaimana skalanya dari sisi ruang ketika pengguna melakukan jutaan operasi per hari

    • Triplit menyimpan riwayat perubahan untuk atribut tertentu, tetapi kueri tetap cepat berkat indeks nilai terbaru
      Namun register LWW itu sendiri tidak mengharuskan penyimpanan riwayat; ini hanya implementasi saat ini agar klien yang sudah lama offline pun bisa disinkronkan secara efisien
      Mereka belum bisa dibilang sepenuhnya mencapai sejuta operasi per hari, tetapi ada keuntungan karena server memegang otoritas
      Ke depannya server Triplit dapat melacak timestamp sinkronisasi terakhir tiap klien, lalu memangkas riwayat secara bertahap, mirip dengan cara Postgres melakukan VACUUM pada tuple yang sudah mati
  • Akan bagus jika ada binding Rust agar bisa dipakai di Tauri
    Jika digabungkan dengan pertumbuhan Tauri, dukungan perangkat mobile yang segera hadir, dan popularitas SQLite belakangan ini, ini bisa mengisi celah untuk aplikasi offline-first dan menjadi pilihan default bagi banyak tim developer

    • Mereka sedang mencoba menambahkan binding Rust ke ElectricSQL, solusi sinkronisasi yang mirip
      ElectricSQL bekerja di lapisan DB sehingga independen bahasa, dan karena memakai Rust di server, binding Rust bisa berjalan di sisi klien maupun server
      Jika ingin ikut mengembangkan, beri tahu mereka
    • Sepertinya Tauri memakai renderer web native
      Kalau begitu, Triplit seharusnya langsung berjalan
  • Sudah beberapa waktu memakai Triplit di aplikasi React Native dan bekerja dengan sangat baik
    Sangat direkomendasikan; ini satu-satunya DB local-first yang memenuhi semua syarat yang saya butuhkan
    Ada bahasa kueri yang tepat dan sane (bukan SQL), dukungan TypeScript yang bagus, dukungan offline, dukungan React Native, dan bagus juga karena open source serta bisa di-self-host

  • Penasaran apakah tidak mungkin dipakai bersama DB PostgreSQL yang sudah ada

    • Saat ini belum, tetapi ada tool internal yang melakukan sinkronisasi dua arah menggunakan protokol replikasi Postgres dan WAL2JSON
      Belum sepenuhnya siap dirilis, tetapi mereka ingin segera membuatnya bisa dicoba orang-orang
    • Sebaiknya lihat ElectricSQL yang bekerja dengan Postgres yang sudah ada
      Saya sendiri juga cenderung akan memakai yang itu