2 poin oleh GN⁺ 2024-10-16 | 1 komentar | Bagikan ke WhatsApp
  • Ini adalah hub yang mengumpulkan dokumentasi WebAssembly dan JavaScript API di satu tempat untuk pengembang yang ingin menggunakan sqlite3 secara langsung di browser modern yang mendukung WASM
  • Untuk mulai cepat, Anda bisa memulai dari HOWTO 3 langkah dan memeriksa jalur instalasi serta deployment melalui dokumentasi unduhan, modul npm, build, dan detail Emscripten
  • Dokumentasi API mencakup cara pemuatan, resep kode klien, penyimpanan persisten, struktur C pada JS API, hingga pembuatan virtual table dan table-valued function
  • Dokumen ini juga merangkum kasus penggunaan nyata seperti SQLime, Evolu, SQLiteNext, sqlite-wasm-esm, sqlite-wasm-http serta proyek pendahulu seperti sql.js, wa-sqlite, dan absurd-js
  • Dengan menautkan materi terkait browser SQLite, OPFS, IndexedDB, dan WASI, Anda dapat dengan cepat membandingkan opsi implementasi untuk menggunakan SQLite di lingkungan web

Cakupan dokumentasi sqlite3 WASM

Kasus penggunaan dan ekosistem terkait

  • Proyek pihak ketiga yang menggunakan proyek ini

    • SQLime: menyediakan antarmuka browser database
    • Evolu: platform local-first yang berfokus pada privasi, kemudahan penggunaan, dan tanpa ketergantungan vendor
    • SQLiteNext: demo integrasi proyek ini dengan next.js
    • sqlite-wasm-esm: mendemonstrasikan cara menggunakan proyek ini di toolchain Vite
    • sqlite-wasm-http: SQLite VFS yang menyediakan akses baca-saja ke database yang disajikan langsung melalui HTTP
  • Pekerjaan pendahulu dan proyek yang berdekatan

    • Alon Zakai sql.js: dikenal sebagai contoh paling awal penggunaan sqlite3 secara langsung di browser selain WebSQL, dan dapat ditelusuri hingga commit tahun 2012
    • Roy Hashimoto wa-sqlite: dikenal sebagai implementasi pertama OPFS storage untuk database sqlite3, dan juga mencakup pekerjaan terkait SQLite VFS di sisi JS
    • James Long absurd-js: mendemonstrasikan cara menyimpan database sqlite3 di dalam database IndexedDB
    • postgres-wasm: menjalankan Postgres database server di browser
    • Jaccwabyt: pustaka JS kecil untuk memanipulasi struktur C yang di-host di WASM dari kode JS, dibuat untuk mendukung implementasi OPFS sqlite3_vfs pada proyek ini
    • CoWasm: “Collaborative WebAssembly for Servers and Browsers”, dan demo app mencakup build WASM dari aplikasi shell sqlite3
    • absurder-js: proyek Nicholas G. Piesco yang membayangkan ulang absurd-js, dan juga memiliki presentasi di SQLite forum
    • sqlite-wasm-rs: menyediakan binding Rust SQLite untuk build wasm32-unknown-unknown
  • Dokumentasi dan artikel eksternal

1 komentar

 
GN⁺ 2024-10-16
Komentar Hacker News
  • Akan menarik jika menjalankan SQLite dalam memori di browser sambil men-stream salinan log WAL ke server, seperti cara Litestream dan Cloudflare Durable Objects menggunakannya
    Bisa memakai WebSocket, dan tampaknya juga memungkinkan dengan POST fetch() yang sesekali dijalankan. Saat kunjungan berikutnya, SQLite klien diisi ulang menggunakan data sisi server
    Namun, jika melihat postingan forum SQLite, mode WAL tidak disertakan dalam build SQLite WASM bawaan, jadi sepertinya perlu build kustom

    • Ada beberapa lapisan alasan mengapa “itu tidak bekerja seperti itu”
      SQLite dalam memori tidak menggunakan WAL, dan Wasm di browser juga tidak mendukung hal-hal seperti API memori bersama yang diharapkan mode WAL SQLite
      Litestream memerlukan konfigurasi WAL yang sangat presisi, dan pada SQLite native konfigurasi default-nya kebetulan cocok, tetapi sulit direproduksi di Wasm
      Cloudflare Durable Objects mungkin terinspirasi oleh Litestream, tetapi cara kerjanya dalam praktik cukup berbeda, begitu juga LiteFS dan Turso
      Gagasan besarnya, yaitu men-stream perubahan SQLite, memang memungkinkan, tetapi beban kerjanya besar dan implementasinya rumit karena model konkurensi Wasm di browser
      Saya dulu yang menulis postingan forum itu, dan pada build SQLite Wasm sisi server saya berhasil membuat WAL berjalan, tetapi itu bukan pilihan yang layak atau praktis untuk dipakai di browser
    • Pada Agustus 2022 saya membuat proof of concept yang mirip dan mengirim DM di Twitter, tetapi tidak mendapat balasan. Handle saya justjs14
      Kodenya perlu saya cari lagi, tetapi saat itu saya mengompilasi SQLite dengan VFS ke Wasm agar bisa membuka DB di browser, melakukan perubahan, lalu push/pull WAL ke server. Sinkronisasi antar-browser juga bisa dilakukan, baik secara manual maupun lewat WebRTC, dan jika klien browser diberi token GitHub, ini juga berjalan di GitHub Pages
      Kalau ada yang tertarik, saya bisa coba membuatnya bisa dijalankan lagi dari awal. Waktu itu saya banyak bereksperimen dengan pendekatan ini, dan menurut saya setidaknya berguna untuk sebagian aplikasi
      Ada juga demo yang hanya memiliki fungsi pull di sini: https://just.billywhizz.io/sqlite/demo/#https://just.billywhizz.io/sqlite/demo/db/chinook.db
    • Berbeda dari beberapa gagasan lain di sini, saya rasa streaming salinan WAL secara teknis memang memungkinkan. Hanya saja, itu harus diimplementasikan di dalam VFS
      “Memori bersama” bisa berupa SharedArrayBuffer, dan jika koneksi DB dibatasi satu per satu, buffer biasa juga bisa dipakai. Misalnya, ini bisa dilakukan di dalam SharedWorker yang sudah cukup umum digunakan
      Implementasinya memang tidak sederhana, tetapi jelas memungkinkan. Sebenarnya masalah yang lebih besar adalah bahwa yang ditangkap itu bukan perubahan tingkat baris, melainkan perubahan tingkat blok
      Jadi ini bisa dipakai untuk mereplikasi seluruh DB, tetapi sulit untuk sinkronisasi parsial seperti hanya membagikan sebagian baris kepada pengguna lain
      Jika membutuhkan perubahan tingkat baris untuk sinkronisasi parsial, Anda harus memakai trigger atau ekstensi sesi SQLite seperti ini: https://sqlite.org/sessionintro.html
      Di PowerSync kami memakai trigger di sisi klien, dan selain pekerjaan pemeliharaan trigger, saya belum menemukan kekurangan besar
    • Apakah yang Anda pikirkan sesuatu seperti https://electric-sql.com/?
    • Saya belum sepenuhnya memahami ide “hydration” ini, tetapi belakangan saya mulai tertarik menjalankan sebagian logika backend di browser dengan memanfaatkan Wasm
      Misalnya, jika rendering template biasa atau beberapa endpoint Htmx dijalankan dengan Wasm, bahkan framework web sisi server yang umum pun bisa menyediakan fitur offline dengan penyimpanan SQLite Wasm mirip seperti yang disebut OP
      Contoh lengkap Django: https://github.com/m-butterfield/django_webassembly
      Contoh Rust minimal yang memisahkan klien/server dengan macro: https://github.com/richardanaya/wasm-service
      Clojure Electric yang melakukan hal serupa tanpa Wasm tetapi dengan lebih banyak macro: https://github.com/hyperfiddle/electric
      Ada juga alat web dari Microsoft belakangan ini yang namanya diawali huruf B
      Dalam beberapa tahun terakhir, ternyata cukup banyak bagian dari ekosistem Python yang mendapatkan dukungan Wasm, sehingga bisa dimanfaatkan untuk pendekatan ini. Bukan hanya library machine learning yang sudah jelas, tetapi juga library game seperti Pygame dan Pyxel, dan karena SDL2 sudah menambahkan dukungan, dukungan untuk Kivy, library UI multitouch, juga tampaknya tidak lama lagi akan memungkinkan
      Tampaknya ada banyak kemungkinan baru untuk menjalankan kode di komputer mana pun, dan bila perlu menghindari birokrasi platform atau biaya dengan tetap berada di dalam sandbox browser web
  • Dokumentasinya menyebutkan bahwa komponen-komponen ini pertama kali muncul sebagai beta publik di 3.40, dan API direncanakan akan distabilkan di 3.41 berdasarkan masukan komunitas
    Namun rilis SQLite terbaru adalah 3.46.1 pada 2024-08-13, jadi kemungkinan API-nya memang sudah stabil tetapi dokumentasinya belum diperbarui
    Akan menjadi sarana distribusi yang bagus jika tim SQLite merilis paket npm resmi yang membundel versi WASM. Belakangan saya lihat dari balasan ternyata itu sudah ada
    Secara pribadi, SQLite-in-WASM favorit saya masih varian Pyodide. Itu sudah ada jauh lebih lama daripada implementasi resmi SQLite, dan jika memakai Pyodide, WASM SQLite ikut terbawa sebagai bagian dari sebagian pustaka standar Python
    Itu dipakai seperti itu di https://lite.datasette.io/, dan bisa juga diuji di https://pyodide.org/en/stable/console.html
    Jika menjalankan sqlite3.connect(':memory:') lalu select sqlite_version(), yang muncul adalah 3.39.0 dari 2022-06-25, jadi Pyodide tampaknya perlu pembaruan versi. Versi ini sepertinya diwarisi dari emscripten: https://github.com/emscripten-core/emscripten/blob/main/tools/ports/sqlite3.py

    • API-nya memang sudah stabil. Nanti saat saya kembali di depan komputer, saya akan coba memperbarui kalimat itu
      Namun tim SQLite tidak akan merilis paket npm resmi. Kami hanya mendistribusikan JS murni, dan dengan tegas menolak masuk ke lubang kelinci dukungan alat di luar bahasa tersebut. Tidak ada anggota proyek yang memakai alat semacam itu
      Kami mendukung build npm yang “disetujui resmi” dan dipelihara oleh Thomas Steiner, tetapi tidak secara aktif menjadikan framework JS mana pun sebagai target pengembangan
      Jika kami mendukung langsung framework tertentu, termasuk npm, itu bisa memberi kesan bahwa kami menjamin framework tersebut, dan kami secara aktif menghindari menjamin proyek pihak ketiga
    • Tim SQLite tampaknya sudah melakukan itu selama beberapa waktu. Dari modul JS, cukup impor @sqlite.org/sqlite-wasm melalui jsdelivr lalu muat sqlite3-bundler-friendly.mjs dan sqlite3.wasm
      Setelah itu Anda bisa memakai C API SQLite dan API berorientasi objek oo1, dan ini juga berjalan di tag skrip type=module biasa maupun Deno
      Contoh HTML ada di sini: https://github.com/Ciantic/experimenting-sqlite-wasm/blob/main/standalone.html
    • https://github.com/sqlite/sqlite-wasm
      sqlite-wasm dimuat jauh lebih cepat daripada Pyodide, jadi jika Anda tidak membutuhkan Python, yang pertama adalah pilihan yang lebih baik
    • DuckDB WASM bisa dipakai secara terpisah dari Pyodide dan juga dapat memakai ekstensi SQLite
      Namun tampaknya cukup terbatas. sqlite_version() tidak ada, jadi saya bahkan tidak bisa memeriksa versinya, dan versi di repositorinya adalah 3.38.1 yang sudah cukup lama
      Web shell DuckDB saat ini belum bisa memuat ekstensi SQLite karena ekstensi SQLite untuk 1.1.2 yang dirilis kemarin masih belum dirilis. Versi sebelumnya berjalan di edisi WASM yang baru diperbarui
      Ekstensi spasial, GDAL, pencarian vektor, dan lainnya juga bisa dipasang: https://github.com/duckdb/duckdb-wasm/releases/tag/v1.29.0
      Membuat “web shell SQL” sendiri juga tidak terlalu sulit, tetapi dokumentasinya belum cukup lengkap
      https://github.com/duckdb/sqlite_scanner/blob/main/src/sqlite/sqlite3.h
    • Membaca FAQ di halaman itu mungkin bisa membantu
  • Saat dipakai di Go, saya sangat menyukai paket Wasm SQLite dari ncruces, https://github.com/ncruces/go-sqlite3
    Paket Go dari cznic juga luar biasa, tetapi versi Wasm ini bekerja dengan baik bahkan di lingkungan seperti OpenBSD

  • WebSQL seharusnya memang hanya SQLite, dan kalau begitu ekosistem penyimpanan aplikasi secara umum serta pendekatan offline-first akan jauh lebih baik
    Apakah masih ada kemungkinan sekarang? Daripada mengabstraksikan SQLite dan membuat spesifikasi yang berlebihan, bukankah lebih baik spesifikasi menentukan versi API SQLite yang harus didukung browser lalu menaikkan versinya secara berkala?

    • Pendekatan “menaikkan versi secara berkala” di browser sangat mungkin menimbulkan masalah
      Salah satu inti web adalah sebisa mungkin hal lama tetap berjalan, dan perubahan yang merusak seperti itu sulit dilakukan
      Bahkan jika spesifikasi mencantumkan beberapa versi dan halaman web bisa memilihnya, browser tetap harus menanggung beban rumit untuk mempertahankan versi-versi SQLite lama yang mungkin sudah tidak didukung lagi. Tiap versi juga memakan sekitar 1MB
      Kalau begitu, bukankah lebih baik membiarkan tiap situs web menanggung konsekuensi dari pilihannya sendiri seperti sekarang
      Jika yang dikhawatirkan adalah pengunduhan berulang atas sumber daya bersama, itu sudah menjadi masalah yang diterima di CDN lain juga. Solusi shared caching untuk dependensi umum akan jauh lebih bernilai daripada sesuatu yang hanya berlaku untuk SQLite
      Pendekatan saat ini tampak lebih baik daripada versi yang disediakan browser
    • Saya suka SQLite, tetapi kita harus mengakui bahwa ada berbagai perilaku yang cukup aneh untuk dimasukkan ke semua browser. Jadi mungkin API yang mirip SQLite akan lebih baik
    • Saya justru senang WebSQL tidak sempat mapan
      Sekarang, saat diperlukan, kita bisa mengambil SQLite terbaru sebagai blob WASM terkompresi 410KB. Kalau kita terikat pada versi SQLite yang dipaksakan browser, mungkin sekarang kita masih memakai versi yang sudah berusia 10 tahun
  • Dengan melihat sekilas halaman ini, saya masih belum benar-benar paham kasus penggunaannya.
    Lebih spesifik lagi, apakah ini bisa menjadi pengganti IndexedDB? Apakah datanya persisten, atau file SQLite-nya harus disimpan langsung ke File System API atau IndexedDB/localStorage?

    • Menurut halaman pengantar, salah satu tujuan proyek ini adalah mendukung penyimpanan persisten sisi klien melalui API JS yang tersedia sejauh memungkinkan.
      Saat ini mencakup Origin-Private FileSystem (OPFS), dan juga penyimpanan melalui backend window.localStorage serta window.sessionStorage, meski sangat terbatas
  • Belakangan ini saya cukup tertarik pada ranah local-first, tetapi dibanding memakai API penyimpanan bawaan browser, khususnya IndexedDB, menanamkan SQLite terasa cukup berat.
    Sepertinya pustaka open source utama juga kebanyakan memakai API bawaan.
    Daripada menambahkan executable lain lewat WebAssembly, saya ingin melihat solusi open source yang menyediakan API mirip SQLite dan sinkronisasi di atas penyimpanan native browser

    • Bisa dibilang SQL lebih nyaman digunakan daripada API IndexedDB, dan misalnya memakai klausa WHERE alih-alih filter if() juga bisa menghemat memori dan CPU
    • Mungkin Anda tertarik dengan TinyBase. Itu pustaka yang saya buat sendiri
  • Jika diunduh dari halaman resmi dan bahkan setelah menghapus file mjs serta file “bundler-friendly”, dependensi minimum SQLite Wasm tetap sekitar 1,3MB
    Untuk aplikasi browser ini tampak agak besar, tetapi Wasm sekarang juga berjalan di tempat lain, jadi di lingkungan seperti itu ini bisa lebih masuk akal

    • Meski begitu, kompresinya cukup bagus. sqlite3.js dan Wasm berukuran asli 1,3MB, tetapi setelah JS diminifikasi dan kedua file dikompresi dengan Brotli, ukurannya turun sampai 410KB
    • Menurut saya 1,3MB adalah ukuran yang cukup masuk akal untuk aplikasi web modern. Terutama karena setelah kunjungan pertama ke situs, itu akan di-cache
      Tentu saja, untuk sekadar menyimpan preferensi pengguna tidak perlu mengunduh SQLite, tetapi bila pekerjaannya memang diuntungkan oleh database penuh, tidak perlu terlalu khawatir soal 1MB sampai akhirnya malah menemukan kembali roda
      Jika komentar lain benar, di jaringan ukurannya bahkan memang bukan 1,3MB sejak awal
    • Ini perlu dipertimbangkan bersama fakta bahwa browser sudah memiliki IndexedDB bawaan
      Namun, untuk aplikasi browser yang memang sejak awal punya kode aplikasi dan data besar, seperti aplikasi mirip Figma atau Photoshop, maupun aplikasi machine learning, tambahan 1,3MB mungkin bukan beban besar
      Perlu juga dipertimbangkan bahwa parsing Wasm jauh lebih cepat daripada JS. Saya tidak bisa menemukan sumber untuk klaim ini sekarang, tetapi setidaknya pernah ada satu tulisan bagus terkait hal itu
      https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
    • Model sandbox WebAssembly juga perlu dipertimbangkan. Secara teori, programnya—dalam hal ini SQLite—bisa berjalan di mana pun yang cocok untuk mengeksekusinya
      Bisa di lokal, bisa di server pusat, atau bisa juga di edge terdekat
    • Di sisi server, kemungkinan besar dibutuhkan build Wasm SQLite terpisah yang menangani konkurensi dan file locking secara berbeda
      Selain itu, WASI masih jauh dari jawaban. SQLite amalgamation bisa dibangun dengan baik di WASI, tetapi konkurensi masih merupakan masalah yang belum terpecahkan
      Untuk membuat driver SQLite berbasis Wasm sampai cukup layak digunakan, VFS harus dibuat dari nol
      https://github.com/ncruces/go-sqlite3/blob/main/vfs/README.md
  • Saya sempat mencoba membuat ini berjalan di ekosistem Rust selama beberapa waktu, tetapi pembungkus SQL di blessed.rs seperti rusqlite dan sqlx tampaknya masih belum bisa memanfaatkannya
    Membungkusnya sendiri juga rumit, karena saya tidak berhasil menemukan cara agar kode Wasm emscripten bisa bekerja cocok dengan wasm32-unknown-unknown
    Pada akhirnya, bagaimanapun bentuknya, tetap dibutuhkan pembungkus JS, dan itu berarti harus mengimplementasikan antarmuka yang diharapkan crate-crate tersebut lalu mengeksposnya dari JS. Akan sangat bagus jika ini bisa diselesaikan di Rust

    • Sedang ada pekerjaan terkait ini. Jika tertarik atau ingin berkontribusi, bisa ikut di sini: https://github.com/rhashimoto/wa-sqlite/discussions/154
      Intinya, build emscripten SQLite perlu dibawa ke wasm-bindgen melalui header extern C, lalu VFS harus diimplementasikan ulang dalam Rust sambil mengompilasinya dalam mode multithread agar akses shared array buffer dimungkinkan
      Setelah itu, baris-baris SQLite bisa diakses sebagai byte Wasm mentah, dan pembungkus atau integrasi bergaya Rust-SQLite bisa dibuat
      Fitur kemudahan seperti connection pooling tetap belum ada, tetapi di Wasm kemungkinan memang lebih baik memakai DB dalam mode eksklusif
    • Ada yang berhasil membuat build SQLite ini bekerja bersama Diesel SQLite milik Rust di sini: https://github.com/xmtp/diesel-wasm-sqlite
      Rilis 0.2 sedang disiapkan minggu ini dan beberapa masalah akan dirapikan. Selain itu, Diesel ORM bisa dipakai seperti native
    • Ada kabar baik soal mencocokkan kode Wasm emscripten dengan wasm32-unknown-unknown
      Ada rencana untuk membuat Emscripten dan Rust bekerja baik bersama di Wasm: https://github.com/rustwasm/wasm-bindgen/pull/4014#issuecomment-2356908451
    • Saya juga sudah menunggu ini cukup lama. Ada beberapa PR yang tertunda sekitar setahun, dan meski saya pernah melihat proof of concept, itu masih jauh dari sesuatu yang benar-benar layak dipakai
  • Dengan menggunakan build Wasm SQLite dan runtime Chicory, seseorang membuat pustaka SQLite yang berjalan di JVM murni: https://github.com/dylibso/sqlite-zero
    Ini tampaknya lebih merupakan eksperimen daripada sesuatu yang ditujukan untuk siap produksi, tetapi bisa berguna untuk membawa alat SQLite tanpa dependensi ke ekosistem JVM

    • Bagaimana cara akses sistem berkasnya? Apakah melalui WASI?
  • Ini pertanyaan umum, tetapi dalam situasi seperti apa mengirim seluruh DB dan membiarkan browser memproses kuerinya justru lebih menguntungkan?
    Dengan kata lain, kapan ini digunakan untuk meningkatkan pengalaman pengguna dibanding model DB yang dihosting server tradisional?

    • Secara pribadi, saya memakainya untuk situs web hosting statis, jadi database yang dihosting server sejak awal bukan pilihan
      Dengan driver yang tepat, alih-alih mengirim seluruh database, Anda bisa melakukan streaming chunk database yang dibutuhkan: https://github.com/mmomtchev/sqlite-wasm-http
      Ini memungkinkan pencarian teks penuh SQLite tanpa harus mengunduh seluruh database FTS. Jika istilah pencariannya cukup pendek, sebagian besar data memang akan diterima, tetapi bukan semuanya
    • Saat melihat judul tulisan ini, hal pertama yang terlintas secara intuitif adalah cara PouchDB dan CouchDB berinteraksi dalam aplikasi offline-first
      https://medium.com/offline-camp/couchdb-pouchdb-and-hoodie-as-a-stack-for-progressive-web-apps-a6078a985f18
    • Untuk penggunaan offline, ini bisa bagus saat menangani data dalam jumlah besar
      Bisa diterapkan mulai dari pustaka audio hingga perangkat lunak pemodelan 3D. Perubahan dibuat dan disimpan secara lokal, lalu disinkronkan dengan sisi server secara berkala atau saat kembali online
    • Saya sedang membuat dasbor yang berkomunikasi langsung dengan beberapa layanan. Di server saya hanya ada sangat sedikit data untuk kontrol akses dan pengelolaan token, dan data sebenarnya tidak pernah masuk ke server saya
      Aplikasi semacam ini adalah kandidat yang sangat cocok untuk DB tertanam sisi klien