Modular Database
Monadic Pipelines
The entire database processing is expressed as monad in Category Theory of Mathematics. And monad makes every step of the computation mathematically provable, composable and also swappable.
To explain monad in the simplest way possible, it has 3 core functions - of
, map
and chain
.
of
: create a monad with a context.map
: mutate the context with a plain function and return the monadchain
: mutate the context with a function to return a monad and flatten the nested monads
const add1 = (ctx) => ctx + 1
const mul2 = (ctx) => ctx * 2
const sub3 = (ctx) => ctx - 3
const add2 = (ctx) => of(ctx).map(add1).map(add1) // returns a monad
const monad = of(2).map(add1).map(mul2).map(sub3).chain(add2)
We added 3 functions for utility.
val
: return the plain contextto
: transform the context with a function and return the plain valuetap
: execute side effects without mutating the context
const n2 = monad.val() // 5
const n3 = monad.to((n)=> n + 4) // 9
const n4 = monad.tap((n)=> console.log(n)).val() // 5
We also added Kleisli arrows as fn
, which create composable functions without the context, and can be passed to chain
.
const calc = fn().map(add1).map(mul2).map(sub3).chain(add2)
const monad = of(2).chain(calc).val() // 5
For example, this is how some of the WeaveDB operations are defined.
const handlers = {
get: args => of(args).map(init).to(getDocs),
add: args => of(args).map(verify).chain(add).tap(commit),
set: args => of(args).map(verify).chain(set).tap(commit),
del: args => of(args).map(verify).chain(del).tap(commit),
update: args => of(args).map(verify).chain(update).tap(commit),
upsert: args => of(args).map(verify).chain(upsert).tap(commit)
}
And each function or Kleisli arrow has a sub monad pipeline, each of witch could have yet another sub monad pipeline.
const set = fn()
.map(init)
.map(setData)
.map(auth)
.tap(validateSchema)
.map(putData)
In this way, every step of the data processing pipeline can be explained with Category Theory (Math). And every step is easily composable and swappable, which makes WeaveDB the ultimate modular database.
Multi-Paradigm Database Substrate
The modular architecture of the WeaveDB protocol allows developers to swap or extend any component within the monadic pipeline, enabling the creation of custom databases across various paradigms.
NoSQL
The reference implementation of WeaveDB comes with a set of query parser, quary planner, index manager and B+ trees that enable Firestore-like NoSQL database, but fully decentralized.
Relational
Relational database can be designed as a subset of NoSQL database, you can implement it by replacing the index layer and setting the right schemas.
Vector
Vector databse is basically an index layer on top of NoSQL/SQL database. You can implment it by buiding an additional embedding layer.
GraphQL
GraphQL is not a database but a query language on top of NoSQL/Relational database. You can implement it by replacing the quary parser and query planner.