Skip to content

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 monad
  • chain : 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 context
  • to : transform the context with a function and return the plain value
  • tap : 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.