SQLite3 WebAssembly Belge Dizini
(sqlite.org)- Güncel WASM destekli tarayıcılarda sqlite3’ü doğrudan kullanmak isteyen geliştiriciler için WebAssembly ve JavaScript API belgelerini tek yerde toplayan bir merkez
- Hızlı çalıştırma için 3 adımlı HOWTO ile başlanabilir; indirme, npm modülü, derleme ve Emscripten ayrıntı belgeleriyle kurulum ve dağıtım yolları kontrol edilebilir
- API belgeleri; yükleme yöntemleri, istemci kodu tarifleri, kalıcı depolama, JS API’de C yapıları, sanal tablolar ve tablo değerli fonksiyonlar yazmaya kadar uzanır
- SQLime, Evolu, SQLiteNext, sqlite-wasm-esm, sqlite-wasm-http gibi gerçek kullanım örnekleri ile sql.js, wa-sqlite, absurd-js gibi öncü projeler birlikte derlenmiş
- Tarayıcı SQLite, OPFS, IndexedDB ve WASI ile ilgili kaynakları bağlayarak web ortamında SQLite kullanmak için uygulama seçeneklerini hızlıca karşılaştırmayı sağlar
sqlite3 WASM belgelerinin kapsamı
- SQLite projesinin WebAssembly ve JavaScript API belgeleridir; güncel WASM destekli tarayıcılarda sqlite3 kullanılmasını sağlayan API’leri kapsar
-
Proje bilgileri ve destek kanalları
- About the sqlite3 WASM subproject
- Project news
- FAQ: Frequently Asked Questions
- TODOs: planlanan ve planlanmayan özellikleri birlikte ele alır
- Teknik destek ve geri bildirim SQLite forum üzerinden alınır; commercial SQLite support contracts sahipleri mevcut destek kanallarını kullanabilir
-
Çalıştırma, kurulum ve derleme belgeleri
- three-step HOWTO: sqlite3 WASM modülünü ve ilgili JavaScript API’lerini dahil edip çalıştırmayı gösterir
- Downloads: ana proje indirme sayfasında sunulur
- Prerelease snapshots: sık sık güncellenir
- npm module
- Building sqlite3 WASM: sqlite3 WASM ve ilgili JS kodu için derleme sürecini ele alır
- Emscripten derleme ayrıntıları
-
API ve uygulama ayrıntı belgeleri
- The API index: çeşitli API varyantlarını ve yükleme/erişim yöntemlerini açıklar
- Cookbook: istemci düzeyi kod için tarifler
- Persistent storage options: kalıcı depolama seçenekleri
- C-structs: JS API’de C yapılarının nasıl kullanılacağı
- virtual tables: JS içinde sanal tablolar ve tablo değerli fonksiyonlar oluşturma yöntemi
- API changes: istemcileri etkileyebilecek API değişiklikleri
- module symbols app: JavaScript/WASM modülünde sqlite3 API sembollerinin listesini üretir
-
Belge ve depo bakımı
Kullanım örnekleri ve ilgili ekosistem
-
Bu projeyi kullanan üçüncü taraf projeler
- SQLime: veritabanı tarayıcı arayüzü sağlar
- Evolu: gizlilik, kullanım kolaylığı ve tedarikçiye bağımlı olmamaya odaklanan local-first platform
- SQLiteNext: bu projeyi next.js ile entegre eden demo
- sqlite-wasm-esm: bu projenin Vite araç zincirinde nasıl kullanılacağını gösterir
- sqlite-wasm-http: HTTP üzerinden doğrudan sunulan veritabanlarına salt okunur erişim sağlayan SQLite VFS
-
Önceki çalışmalar ve komşu projeler
- Alon Zakai’nin sql.js projesi: WebSQL hariç tutulduğunda tarayıcıda sqlite3’ün doğrudan kullanıldığı ilk örnek olarak bilinir ve 2012 tarihli commit’e kadar uzanır
- Roy Hashimoto’nun wa-sqlite projesi: sqlite3 veritabanları için OPFS storage uygulamasının ilk örneği olarak bilinir; JS tarafındaki SQLite VFS çalışmalarını da içerir
- James Long’un absurd-js projesi: sqlite3 veritabanını IndexedDB veritabanı içinde saklama yöntemini gösterir
- postgres-wasm: tarayıcıda Postgres database server çalıştırır
- Jaccwabyt: WASM’de barındırılan C yapılarını JS koduyla manipüle etmeye yarayan küçük bir JS kütüphanesidir; bu projenin OPFS sqlite3_vfs uygulamasını desteklemek için oluşturulmuştur
- CoWasm: “Collaborative WebAssembly for Servers and Browsers” projesidir; demo app içinde sqlite3 shell uygulamasının WASM derlemesi yer alır
- absurder-js: Nicholas G. Piesco’nun absurd-js’i yeniden tasarladığı projedir; ayrıca bir SQLite forum duyurusu vardır
- sqlite-wasm-rs:
wasm32-unknown-unknownderlemeleri için Rust SQLite binding’leri sağlar
-
Dış belgeler ve yazılar
- Porting WebSQL to OPFS: Google Chrome geliştirici ekibinin SQLite WASM ile ilgili yazısı
- building SQLite3 for WASI: VMWare OCTO ekibinin WASI için SQLite3 derleme yazısı
1 yorum
Hacker News yorumları
Tarayıcıda bellek içi SQLite çalıştırırken, Litestream ve Cloudflare Durable Objects’in kullandığı yönteme benzer şekilde WAL günlük kopyalarını sunucuya akıtmak ilginç olabilir
WebSocket kullanılabilir; aralıklı
fetch()POST istekleriyle de mümkün görünüyor. Sonraki ziyaretlerde sunucu tarafındaki veriler kullanılarak istemci SQLite yeniden doldurulurAncak SQLite forum yazısına bakılırsa, varsayılan SQLite WASM derlemesinde WAL modu olmadığı için özel bir derleme gerekecek gibi
Bellek içi SQLite WAL kullanmaz ve tarayıcı Wasm’ı, SQLite’ın WAL modunun beklediği paylaşımlı bellek API’si gibi şeyleri desteklemez
Litestream çok hassas bir WAL yapılandırması gerektirir; yerel SQLite’ın varsayılan yapılandırmasında tesadüfen iyi örtüşür, ancak Wasm’da bunu yeniden üretmek zordur
Cloudflare Durable Objects Litestream’den ilham almış olabilir ama gerçek çalışma biçimi oldukça farklıdır; LiteFS ve Turso için de aynı şey geçerlidir
SQLite değişikliklerini akıtma şeklindeki büyük fikir mümkündür, ancak iş yükü büyüktür ve tarayıcı Wasm’ının eşzamanlılık modeli nedeniyle uygulaması zordur
Söz konusu forum yazısını daha önce ben yazmıştım ve sunucu tarafı Wasm SQLite derlemesinde WAL’ı çalıştırmıştım; ancak bu, tarayıcıda kullanılabilir ya da mümkün bir seçenek değildi
justjs14O zamanki kodu bulmam gerekir, ancak tarayıcıda VFS’li SQLite’ı Wasm’a derleyip DB’yi açıyor, değişiklik yaptıktan sonra WAL’ı sunucuya push/pull edebiliyordum. İster elle ister WebRTC ile tarayıcılar arasında senkronizasyon da mümkündü; tarayıcı istemcisine GitHub token’ı verirseniz GitHub Pages üzerinde de çalışıyordu
İlgilenirseniz yeniden baştan çalıştırılabilir hale getirebilirim. O dönemde bu yaklaşımla çok deney yaptım ve en azından bazı uygulamalar için yararlı olabileceğini düşünüyorum
Yalnızca pull özelliği olan demo da burada: https://just.billywhizz.io/sqlite/demo/#https://just.billywhizz.io/sqlite/demo/db/chinook.db
“Paylaşımlı bellek”
SharedArrayBufferolabilir; DB bağlantısını aynı anda yalnızca bir tane açarsanız normal buffer da mümkün olur. Örneğin zaten yaygın olan birSharedWorkeriçinde bu yapılabilirUygulaması basit olmayacaktır ama kesinlikle mümkündür. Aslında daha büyük sorun, satır düzeyinde değil blok düzeyindeki değişiklikleri yakalamasıdır
Bu nedenle tüm DB replikasyonu için kullanılabilir, ancak bazı satırları başka kullanıcılarla paylaşmak gibi kısmi senkronizasyon zordur
Kısmi senkronizasyon için satır düzeyinde değişiklik gerekiyorsa tetikleyiciler veya SQLite session extension gibi şeyler kullanmak gerekir: https://sqlite.org/sessionintro.html
PowerSync’te istemci tarafı tetikleyiciler kullanıyoruz ve tetikleyici bakım işi dışında büyük bir dezavantaj bulamadım
Örneğin genel şablon render etme veya bazı Htmx endpoint’leri Wasm ile çalıştırılırsa, sıradan sunucu tarafı web framework’lerinde de OP’nin bahsettiğine benzer bir SQLite Wasm deposuyla çevrimdışı özellikler sunulabilir
Tam Django örneği: https://github.com/m-butterfield/django_webassembly
Makrolarla istemci/sunucu ayrımı yapan minimal Rust örneği: https://github.com/richardanaya/wasm-service
Wasm olmadan benzer bir işi daha fazla makroyla yapan Clojure Electric: https://github.com/hyperfiddle/electric
Microsoft tarafındaki son web araçlarından B ile başlayan bir şey de var
Son birkaç yılda Python ekosisteminin şaşırtıcı derecede büyük bir kısmı Wasm desteği kazandı ve bu yaklaşımda kullanılabilir hale geldi. Yalnızca bariz makine öğrenmesiyle ilgili kütüphaneler değil, Pygame ve Pyxel gibi oyun kütüphaneleri de var; SDL2 destek eklediğine göre çoklu dokunmatik UI kütüphanesi Kivy desteği de yakında mümkün görünüyor
Herhangi bir bilgisayarda kod çalıştırmak ve gerekirse web tarayıcısı sanal alanı içinde platform bürokrasisinden veya ücretlerinden kaçınmak için pek çok yeni olasılık var gibi görünüyor
Belgede bu bileşenlerin ilk olarak 3.40’ta açık beta olarak çıktığı, topluluk geri bildirimlerine göre 3.41’de API’nin kararlı hale getirilmesinin planlandığı yazıyor
Ancak en güncel SQLite sürümü 2024-08-13 tarihli 3.46.1 olduğu için, muhtemelen API kararlılığı çoktan sağlandı ama belge güncellenmemiş gibi görünüyor
SQLite ekibi WASM sürümünü paketleyen resmi bir npm paketi çıkarsa iyi bir dağıtım yolu olur gibi. Sonradan gördüğüme göre yanıtlara bakılırsa zaten varmış
Kişisel olarak en sevdiğim SQLite-in-WASM hâlâ Pyodide varyantı. Resmi SQLite uygulamasından çok daha uzun süredir var ve Pyodide kullanınca WASM SQLite, Python standart kütüphanesinin bir parçası olarak beraberinde geliyor
https://lite.datasette.io/ adresinde bu şekilde kullanılıyor ve https://pyodide.org/en/stable/console.html üzerinde de denenebiliyor
sqlite3.connect(':memory:')ileselect sqlite_version()çalıştırınca 2022-06-25 tarihli 3.39.0 çıkıyor; bu yüzden Pyodide’ın sürüm yükseltmeye ihtiyacı var gibi görünüyor. Bu sürüm emscripten’den devralınıyor gibi: https://github.com/emscripten-core/emscripten/blob/main/tools/ports/sqlite3.pyAncak SQLite ekibinin resmi bir npm paketi çıkarması söz konusu olmayacak. Biz yalnızca saf JS dağıtıyoruz ve dil dışı araç desteği tavşan deliğine girmeyi kesin biçimde reddediyoruz. Proje üyelerinin hiçbiri bu tür araçları kullanmıyor
Thomas Steiner’ın bakımını yaptığı “resmen onaylı” npm derlemesini destekliyoruz, ancak hiçbir JS framework’ünü aktif geliştirme hedefi olarak görmüyoruz
npm dâhil belirli bir framework’ü doğrudan desteklemek, o framework’ü onayladığımız izlenimi yaratabilir; biz de üçüncü taraf projeleri onaylama izleniminden aktif olarak kaçınıyoruz
@sqlite.org/sqlite-wasmpaketinijsdelivrüzerinden getiripsqlite3-bundler-friendly.mjsvesqlite3.wasmdosyalarını yüklemek yeterliBöylece SQLite’ın C API’si ve
oo1nesne yönelimli API’si kullanılabiliyor; normaltype=modulescript etiketiyle ya da Deno’da da çalışıyorÖrnek HTML burada: https://github.com/Ciantic/experimenting-sqlite-wasm/blob/main/standalone.html
sqlite-wasm, Pyodide’dan çok daha hızlı yüklendiği için Python’a ihtiyacınız yoksa ilki daha iyi bir seçenekAncak epey sınırlı görünüyor.
sqlite_version()olmadığı için sürümü bile kontrol edemedim; depodaki sürüm de 3.38.1 ile oldukça eskiMevcut DuckDB web shell’i, dün çıkan 1.1.2 için SQLite eklentisi henüz yayımlanmadığından SQLite eklentisini yükleyemiyor. Önceki sürüm yakın zamanda güncellenen WASM edisyonuyla çalışıyor
Spatial extension, GDAL, vektör arama gibi şeyler de eklenebiliyor: https://github.com/duckdb/duckdb-wasm/releases/tag/v1.29.0
Kendi “SQL web shell”inizi yapmak da çok zor değildi, fakat dokümantasyon yeterince eksiksiz değildi
https://github.com/duckdb/sqlite_scanner/blob/main/src/sqlite/sqlite3.h
Go’da kullanırken ncruces’in Wasm SQLite paketi https://github.com/ncruces/go-sqlite3 gerçekten hoşuma gidiyor
cznic’in Go paketi de harika, ama bu Wasm sürümü OpenBSD gibi ortamlarda da iyi çalışıyor
WebSQL aslında sadece SQLite olmalıydı; öyle olsaydı offline-first ve genel uygulama depolama ekosistemi çok daha iyi olurdu
Şimdi bile bir ihtimal var mı? SQLite’ı soyutlayıp aşırı ayrıntılı şekilde spesifikasyona bağlamak yerine, tarayıcıların desteklemesi gereken SQLite API sürümünü belirtip bunu düzenli olarak yükseltemez miyiz?
Web’in temel noktalarından biri, mümkün olduğunca mevcut şeylerin çalışmaya devam etmesi gerektiğidir; böyle breaking change’ler zordur
Spesifikasyon birkaç sürümü listeleyip web sayfasının seçmesine izin verse bile, tarayıcılar artık desteklenmiyor olabilecek eski SQLite sürümlerini tutmak gibi zorlu bir yük üstlenmek zorunda kalır. Her sürüm de yaklaşık 1 MB yer kaplıyor
Bu durumda, her web sitesinin kendi seçiminin bedelini şimdi olduğu gibi üstlenmesine izin vermek daha iyi değil mi diye düşünüyorum
Ortak kaynakların tekrar tekrar indirilmesinden endişe ediliyorsa, bu başka CDN’lerin de zaten kabullendiği bir sorun. Ortak bağımlılıklar için paylaşımlı önbellekleme çözümü, yalnızca SQLite’a özgü bir çözümden çok daha değerli olurdu
Mevcut yaklaşım, tarayıcının sağladığı bir sürümden daha iyi görünüyor
Artık gerektiğinde 410 KB sıkıştırılmış WASM blob olarak güncel SQLite’ı getirebiliyoruz. Tarayıcının dayattığı SQLite sürümüne bağlı kalsaydık, şu anda 10 yıllık bir sürümü kullanıyor olabilirdik
Sayfayı hızlıca gözden geçirince kullanım senaryosunu pek anlayamadım
Daha somut olarak, bu IndexedDB’nin alternatifi olabilir mi? Veriler kalıcı mı tutuluyor, yoksa SQLite dosyasını doğrudan File System API ya da IndexedDB/localStorage içinde mi saklamak gerekiyor?
Şu anda Origin-Private FileSystem (OPFS) ve çok sınırlı da olsa
window.localStorage,window.sessionStoragebackend’leri üzerinden depolama buna dahilSon dönemde local-first alanına çok ilgi duyuyorum ama tarayıcının yerleşik depolama API’lerini, özellikle IndexedDB’yi kullanmakla karşılaştırınca SQLite’ı gömmek epey ağır geliyor
Başlıca açık kaynak kütüphaneler de genel olarak yerleşik API’leri kullanıyor gibi görünüyor
WebAssembly ile bir başka çalıştırılabilir dosya eklemeye çalışmak yerine, tarayıcının yerel depolaması üzerinde SQLite benzeri bir API ve senkronizasyon sağlayan açık kaynak bir çözüm görmek isterdim
if()filtresi yerineWHEREcümlesi kullanmak bellek ve CPU kullanımını azaltabilirResmî indirme sayfasından alıp
mjsdosyalarını ve “bundler-friendly” dosyaları tamamen kaldırsanız bile, asgari SQLite Wasm bağımlılığı yaklaşık 1,3 MB oluyorTarayıcı uygulamaları için biraz büyük görünüyor; ancak günümüzde Wasm başka yerlerde de çalıştırıldığı için bu tür ortamlarda daha mantıklı olabilir
sqlite3.jsve Wasm ham hâliyle 1,3 MB ama JS’i küçültüp iki dosyayı Brotli ile sıkıştırınca 410 KB’a kadar düşüyorSadece kullanıcı ayarlarını saklamak gibi bir iş için elbette SQLite indirmeye gerek yok; ama tam teşekküllü bir veritabanının avantaj sağladığı işler için 1 MB yüzünden fazla endişelenip boşuna tekerleği yeniden icat etmeye gerek yok
Diğer yorum doğruysa ağ üzerinden zaten en başta 1,3 MB bile olmayacaktır
Yine de Figma veya Photoshop benzeri uygulamalar, makine öğrenimi uygulamaları gibi uygulama kodu ve verisi zaten büyük olan tarayıcı uygulamalarında 1,3 MB ciddi bir ek yük olmayabilir
Wasm ayrıştırmasının JS’e göre oldukça hızlı olduğu da dikkate değer. Bu iddia için şu anda kaynak bulamadım ama konuyla ilgili en az bir iyi yazı vardı
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
Yerel makine de olabilir, merkezi sunucu da olabilir, yakındaki bir edge de olabilir
Ayrıca WASI hâlâ bir cevap olmaktan çok uzak. SQLite amalgamation WASI ile düzgün derleniyor, ancak eşzamanlılık çözülmemiş bir sorun
Wasm tabanlı SQLite sürücüsünü kullanılabilir hâle getirmek için VFS’yi sıfırdan oluşturmam gerekti
https://github.com/ncruces/go-sqlite3/blob/main/vfs/README.md
Bir süre Rust ekosisteminde bunu çalıştırmaya uğraştım ama blessed.rs’in SQL wrapper’ları olan
rusqlite,sqlxhenüz bundan yararlanamıyor gibi görünüyorduDoğrudan sarmalamak da zordu; emscripten Wasm kodunun
wasm32-unknown-unknownile uyumlu çalışmasını sağlamanın yolunu bulamadımSonuçta bir şekilde JS wrapper gerekiyor; bu durumda da söz konusu crate’lerin beklediği arayüzleri uygulayıp JS’ten dışa açmak gerekiyor. Bu Rust tarafında çözülürse gerçekten harika olur
Esasen
wasm-bindgeniçinde SQLite emscripten build’iniextern Cheader’ı olarak içe almak, paylaşımlı dizi tamponlarına erişim mümkün olacak şekilde çok iş parçacıklı modda derlemek ve VFS’yi Rust ile yeniden uygulamak gerekiyorBundan sonra SQLite satırlarına ham Wasm baytları olarak erişilebilecek ve Rust-SQLite tarzı bir wrapper ya da entegrasyon yapılabilecek
Bağlantı havuzu gibi kolaylıklar hâlâ olmayacak; ancak Wasm’da DB’yi exclusive mode ile kullanmak muhtemelen daha iyi olacaktır
Bu hafta 0.2 sürümünü hazırlıyoruz ve birkaç sorunu düzelteceğiz. Bunun dışında Diesel ORM’yi native gibi kullanabilirsiniz
emscriptenWasm kodu ilewasm32-unknown-unknown’ı uyumlu hâle getirme konusunda iyi haberler varEmscripten ve Rust’ın Wasm üzerinde iyi birlikte çalışmasını sağlamaya yönelik bir plan var: https://github.com/rustwasm/wasm-bindgen/pull/4014#issuecomment-2356908451
SQLite’in Wasm derlemesini ve Chicory çalışma zamanını kullanarak saf JVM üzerinde çalışan bir SQLite kütüphanesi oluşturmuşlar: https://github.com/dylibso/sqlite-zero
Üretime hazır olmayı hedeflemekten çok bir deney gibi, ancak bağımlılıksız SQLite araçlarını JVM ekosistemine getirmek için yararlı olabilir diye düşünüyorum
Genel bir soru: Hangi durumlarda tüm veritabanını gönderip sorguları tarayıcının işlemesine bırakmak daha avantajlı olur?
Başka bir deyişle, kullanıcı deneyimini geleneksel sunucuda barındırılan DB modeline göre iyileştirmek için bunu ne zaman kullanırsınız?
Uygun bir sürücüyle tüm veritabanını göndermek yerine gerekli veritabanı parçalarını stream edebilirsiniz: https://github.com/mmomtchev/sqlite-wasm-http
Tüm FTS veritabanını indirmeden SQLite tam metin araması yapabilirsiniz. Arama terimi yeterince kısaysa çoğunu alırsınız ama tamamını değil
https://medium.com/offline-camp/couchdb-pouchdb-and-hoodie-as-a-stack-for-progressive-web-apps-a6078a985f18
Ses kütüphanesinden 3D modelleme yazılımına kadar pek çok şey mümkün. Değişiklikleri yerelde oluşturup kalıcı hale getirir, ardından düzenli olarak veya tekrar çevrimiçi olduğunda sunucu tarafıyla senkronize edersiniz
Bu tür uygulamalar istemci tarafı gömülü DB için iyi adaylar