Hi!<p>As I was working on a side project, I noticed I wanted to use SQLite like a Document Database on the server.
So I built Doculite. DocuLite lets you use SQLite like Firebase Firestore. It's written in Typescript and an adapter on top of sqlite3 and sqlite.<p>Reasons:<p>1) Using an SQL Database meant having less flexibility and iterating slower.<p>2) Alternative, proven Document Databases only offered client/server support.<p>3) No network. Having SQLite server-side next to the application is extremely fast.<p>4) Replicating Firestore's API makes it easy to use.<p>5) Listeners and real-time updates enhance UX greatly.<p>6) SQLite is a proven, stable, and well-liked standard. And, apparently one of the most deployed software modules right now. (src: <a href="https://www.sqlite.org/mostdeployed.html" rel="nofollow noreferrer">https://www.sqlite.org/mostdeployed.html</a>)<p>What do you think? Feel free to comment with questions, remarks, and thoughts.<p>Happy to hear them.<p>Thanks
I'm the core maintainer of the npm sqlite package that your library uses. I recommend that you don't make it a direct dependency, but use dependency injection or an adapter pattern that way your library isn't dependent on a specific package version of sqlite/sqlite3 (the npm sqlite package API is pretty static at this point though!).<p>The npm sqlite package used to have sqlite3 as a direct dependency in older major versions and most of the support issues were against sqlite3 instead of sqlite. Taking that dependency out and having the user inject it into sqlite instead removed 99% of the support issues. It's also really nice that sqlite has no dependencies at all.<p>If you go the adapter pattern route, you can support other sqlite libraries like better-sqlite3. Sometimes sqlite/sqlite3 doesn't fit a user's use-case and alternative libraries do.<p>Same deal with the pub/sub mechanism. You have the Typescript types defined to create abstractions. Would be nice to see adapters for Redis streams / kafka / etc, as in-memory pub/sub may not cut it after a certain point.<p>Great start on your library!
The one feature that I'd want out of this is atomic writes. If I have a document and want to increment the value of a field in it by one, I'm not sure that's possible with Doculite today: if two requests read the same document at the same time and both write an incremented value, the value is incremented by one, not two.<p>The way _I_ would expect to do this is something like this:<p><pre><code> const ref = db.collection('page').doc('foo');
do {
const current = await ref.get();
try {
await ref.set({ likes: current.likes + 1 }, { when: { likes: current.likes } });
} catch {
continue;
}
} while (false);
</code></pre>
If `set()` attempts to write to the ref when the conditions in `when` are not matched exactly, the write should fail and you should have to try the operation again. In this example, the `set()` call increments the like value by one, but specifies that the write is only valid if `likes` is equal to the value that the client read. In the scenario I provided, one of the two concurrent requests would fail and retry the write (and succeed on the second go).
Why do you have async reads and writes? There's no client-server setup here, using async / await just introduces pointless waiting.<p><a href="https://github.com/WiseLibs/better-sqlite3">https://github.com/WiseLibs/better-sqlite3</a>
Kind of nifty... Just curious if this is using the JSON functions/operators for SQLite under the covers?<p><a href="https://www.sqlite.org/json1.html" rel="nofollow noreferrer">https://www.sqlite.org/json1.html</a><p>Edit: where is the database file stored? A parameter for the Database() constructor seems obvious, but not seeing it in the basic sample.
>DocuLite lets you use SQLite like Firebase Firestore.<p>Honestly, that sounds absolutely frightening to my ear. There are redis, there is mongo, orient, and plenty of document-based rapid-development databases which will be a substantially better solution than turning sqlite into Firebase.<p>Yes, you can use data change notification callbacks. It is a cool feature of SQLite, but did you know that their performance is a big concern in a large-scale database (document database grows very quickly by design)? What about COUNTs? Batching operations? Deadlocks? This will go out of hand quickly, because a hammer is used as a shovel here.
If you are serious about transactionality, data consistency, and isolation levels, this sounds different from how you want to go. Both Firestore and Realm have shortcomings here. Fauna (where I work at, btw) and Surreal with FoundationDB on the backend, and Spanner are the only ones that can guarantee strict serializability in a distributed environment. I could argue that Fauna is the most turnkey (least pain to try, test, implement). With those "strict serializable" db's it is much easier to avoid data anomalies, as the ones mentioned in this thread.
I forgot to share this very cool alternative approach to realtime reactivity, via websockets, by subscribing to actual raw queries from the frontend!<p>- <a href="https://github.com/Rolands-Laucis/Socio">https://github.com/Rolands-Laucis/Socio</a><p>- <a href="https://www.youtube.com/watch?v=5MxAg-h38VA&list=PLuzV40bvrSqhXZF6HtB1u0nR_lw2Rn-e6&index=1">https://www.youtube.com/watch?v=5MxAg-h38VA&list=PLuzV40bvrS...</a> (video updates of the code and functionality)
I'd see if you can easily port the on top of browser based sqlite in wasm, that's expand your user base and lead to some of the "holy Grail" in the offline first/sync systems
This is cool. There are a tonne of options for local KV stores that likely outperform this by a large margin, but the obvious benefit here is that SQLite is really simple to configure and operate!
Here's the source: <a href="https://github.com/thenorthbay/doculite">https://github.com/thenorthbay/doculite</a>
That is an interesting approach.<p>> 6) SQLite is a proven, stable, and well-liked standard.<p>How does adding this adapter on top affect the stability?<p>Have you looked at SurrealDB? - <a href="https://surrealdb.com/" rel="nofollow noreferrer">https://surrealdb.com/</a><p>Seems like it would provide you with what you need.
> Alternative, proven Document Databases only offered client/server support.<p>We currently use Realm for this use case. It’s a local database just like SQLite, but with native support for documents and listeners. Did you try that out?
Thank you, this can be handy really. I would love to have compatible replicas (implementing both the same API and the same storage schema) for other languages like C# and Python.
Does this mean documents in a database, or a database as a document?<p>I've tried the second, but the time comes when you need to (re)order items which gets clumsy.