Live data from Hacker News

A type-safe, realtime collaborative Graph Database in a CRDT

codemix.com

31–40 of 50 posts

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#31
post #13

Eventually someone will figure out how to use a graph database to allow an agent to efficiency build & cull context to achieve near determinant activities. Seems like one needs a sufficiently powerful schema and a harness that properly builds the graph of agent knowledge, like how ants naturally figure how where sugar is, when that stockpile depletes and shifts to other sources. This looks neat, but if you want it to…

Working on exactly that! We're local first, but do distributed sync with iroh. Written in rust and fully open source. Imho having a graph database that is really easy to use and write new cli applications on top of works much better. You don't need strong schema validation so long as you can gracefully ignore what your schema doesn't expect by viewing queries as type/schema declarations. https://github.com/magic-lock…

Interesting! Triblespace seems similar to TerminusDB and the solution presented here - would you mind stating the differences ?

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#32
Oh this is cool. The Yjs as storage backend trick is clever, you basically get CRDT sync for free without having to build your own replication layer. And the pluggable storage means you can develop against in-memory and then flip to YGraph for collab mode without touching your queries. That's a nice developer experience.

The live queries also caught my eye. Having traversals auto reexecute when data changes sounds straightforward until you realize the underlying data is being merged from multiple peers concurrently. Getting that right without stale reads or phantom edges is genuinely hard.

I've been researching on something like this in a similar space but for source code, therefore built a tool called Weave(https://github.com/Ataraxy-Labs/weave) for entity level merges for git. Instead of merging lines of text, it extracts functions, classes, and methods, builds a dependency graph between them, and merges at that level.

Seeing codemix makes me think there might be something interesting here. Right now our entity graph and our CRDT state are two separate things. The graph lives our analysis engine and the CRDT lives in different crate. If something like @codemix/graph could unify those, you'd have a single data structure where the entity dependency graph is the CRDT.

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#33

Can anyone explain why it is a good idea to make a graphdb in typescript? This not a language flamewar question, more of an implementation details question. Though typescript is pretty fast, and the language is flexible, we all know how demanding graph databases are. How hard they are to shard, etc. It seems like this could be a performance trap. Are there successful rbdms or nosql databases out there written in type…

>Also why is everything about LLMs now? Can't we discuss technologies for their face value anymore. It's getting kind of old to me personally.

Fully agree with you, LLM's everywhere is getting churlsome, and trite. Sure, one can generate the code, but can one talk about the code?

Can one move, easily, beyond "but why should I?" into "I should because ..", whenever it comes to some realm, one is supposdely to have "conquered" with AI/ML/etc.?

Sure, we can all write great specs, sit back and watch the prompts rolling in off the horizon...

But seriously: the human reasoning of it is the most important part!

However everyone is busy building things secretly that they don't want anyone to know about with AI/ML (except the operators of course, duh, lol, kthxbai...) because, after all, then anyone else can do it .. and in this secrecy, human literature is transforming - imho - in non-positive ways, for the future.

Kids need to read books, and quick!

>old to me personally

I kind of regret seeing it in one of my favourite realms, retro- computing .. but .. what can we do, it is here and now and the kids are using it even if some don't.

I very much concur with you on the desire to continue being able to discuss technologies at face value, personally. We have to be reviewing the code; the point at which we don't review AI's output, is where we become subjects of it.

This is, probably, like the very early days of porno, or commercial tobacco, or indeed industrialized combustion, wherein it kind of took society a few big leaps and dark tumbles before the tech sort of stabilized. I'm not sure we'll get to the "Toyota" stages of AI, or indeed we're just going to blast right past into having AI control literally every device under the sun, whether we like it or not (and/or, have an impact on the technologically-obsolete curve, -/+'vely...)

Ain't no easily-accessible AI-hookery Typescript in 8-bit land .. I will have my retro- computing without that filthy stinking AI/ML please, mmkay, thanks!!!

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#34
post #13

Earlier quoted context omitted.

Working on exactly that! We're local first, but do distributed sync with iroh. Written in rust and fully open source. Imho having a graph database that is really easy to use and write new cli applications on top of works much better. You don't need strong schema validation so long as you can gracefully ignore what your schema doesn't expect by viewing queries as type/schema declarations. https://github.com/magic-lock…

Interesting! Triblespace seems similar to TerminusDB and the solution presented here - would you mind stating the differences ?

Spot on!

In one word. Simplicity!

TerminusDB is a RDF database with build-in prolog, a heavy focus on succinct data structure indexes, and has a client server model.

Triblespace is purposefully not RDF, because RDF has horrible DX, and it does not have a good reconciliation and distributed consistency story.

It's virtually impossible to get RDF data into a canonical form [https://www.w3.org/TR/rdf-canon/#how-to-read] and trivial stuff like equality of two datasets is NP-Hard.

Triblespace, while also a data exchange standard like RDF, is closer to Datascript or Datomic. It's a Rust library, and great care has been taken to give it extremely nice DX.

In-memory datasets are cheaply clonable, and support efficient set operations. There's macros that integrate fully into the type system to perform data generation and queries.

    // The entity! macro returns a rooted fragment; merge its facts into
    // a TribleSet via `+=`.
    let herbert = ufoid();
    let dune = ufoid();
    let mut library = TribleSet::new();

    library += entity! { &herbert @
        literature::firstname: "Frank",
        literature::lastname: "Herbert",
    };

    library += entity! { &dune @
        literature::title: "Dune",
        literature::author: &herbert,
        literature::quote: ws.put(
            "I must not fear. Fear is the mind-killer."
        ),
    };

    ws.commit(library, "import dune");

    // `checkout(..)` returns a Checkout — a TribleSet paired with the
    // commits that produced it, usable for incremental delta queries.
    let catalog = ws.checkout(..)?;
    let title = "Dune";

    // Multi-entity join: find quotes by authors of a given title.
    // `_?author` is a pattern-local variable that joins without projecting.
    for (f, l, quote) in find!(
        (first: String, last: String, quote),
        pattern!(&catalog, [
            { _?author @
                literature::firstname: ?first,
                literature::lastname: ?last
            },
            { _?book @
                literature::title: title,
                literature::author: _?author,
                literature::quote: ?quote
            }
        ])
    ) {
        let quote: View = ws.get(quote)?;
        let quote = quote.as_ref();
        println!("'{quote}'\n - from {title} by {f} {l}.");
    }
Data has a fully tracked history like in terminus, but we are overall more CRDT-like with multiple scopes of transactionality.

You can store stuff in either S3 or a single local file (for the local file you can union two databases by concatenating them with `cat`).

We also have just recently added sync through Iroh.

The core idea and main difference between RDF is that RDF is text based and weakly typed, we are binary and strongly typed.

We split everything into two basic structures: - the tribles (a pun on binary triple), 64byte units that are split into [16byte entity id | 16byte attribute id | 32byte Value] where the first two are basically high entropy identifiers like UUIDs, and the last is either a Blake3 hash, or an inlined It's pretty easy to see why canonical representations are pretty easy for us, we just take all of the tribles, sort them lexicographically, dedup them, store the resulting array in a blob. Done.

Everythign else is build up from that. Oh and we also have succinct datastructures, but because those are dense but slower, and immutable, we have a custom 256-ary radix trie to do all of the immutable set operations.

The query engine is also custom, we don't have a query planner which gives us 0.5-2.5microseconds of latency for queries depending on the number of joins, with a query engine that is fully extensible via traits in rust.

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#35

Cypher-over-Gremlin is a smart call — LLMs can write Cypher, makes the MCP angle viable in a new way. How dos Yjs handle schema migrations? If I add a property to a vertex type that existing peers have cached, does it conflict or drop the unknown field?

The CRDT enables eventual consistency on these schema updates, so a new field will be eventually consistent

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#36

Oh this is cool. The Yjs as storage backend trick is clever, you basically get CRDT sync for free without having to build your own replication layer. And the pluggable storage means you can develop against in-memory and then flip to YGraph for collab mode without touching your queries. That's a nice developer experience. The live queries also caught my eye. Having traversals auto reexecute when data changes sounds st…

Semantic merge. PlasticSCM had that a feature many years back

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#37

I'm not terribly familiar with graph databases, but perhaps someone who is can explain the advantage of this awfully complicated seeming design. There's gremlin, cypher, yjs, and zod, all of which I understand are different languages for different problems. What's the advantage of using all these different things in one system? You can do all of this in datalog. You get strong eventual consistency naturally. LLMs kno…

The advantage for property graph databases using Cypher query language is that the queries for things like "show me all systems connected to this system by links greater than 10Gbps up to n hops away" are vastly easier to write and faster to complete compared to SQL and relational databases. Cypher lets you easily search for arbitrary graph patters and the result is also a graph, not a denormalized table.

Parent commenter was asking compare to datalog (not SQL) which eats recursive graph transitions like this for lunch, making the queries very elegant to read ... while still staying relational.

I'm personally of the opinion that "graph databases" should be relational databases; the relational model can subsume "graph" queries, but for all the reasons Codd laid out back in the 60s... network (aka connected graph) databases cannot do the latter.

Let the query planner figure out the connectivity story, not a hardcoded data model.

  % 1. Base case: Directly connected systems (1 hop) with   bandwidth > 10
  fast_path(StartSys, EndSys, 1) :- 
      link(StartSys, EndSys, Bandwidth), 
      Bandwidth > 10.

  % 2. Recursive case: N-hop connections via an intermediate system
  fast_path(StartSys, EndSys, Hops) :- 
      fast_path(StartSys, IntermediateSys, PrevHops), 
      link(IntermediateSys, EndSys, Bandwidth), 
      Bandwidth > 10,
      Hops = PrevHops + 1.

  % 3. The Query: Find all systems connected to 'System_A' within 5 hops
  ?- fast_path('System_A', TargetSystem, Hops), Hops 
or in RelationalAI's "Rel" language, such as I remember it, this is AI assisted it could be wrong:

  // 1. Base case: Directly connected systems (1 hop)
  def fast_path(start_sys, end_sys, hops) =
    exists(bw: link(start_sys, end_sys, bw) and bw > 10 and hops = 1)

  // 2. Recursive case: Traverse to the next system
  def fast_path(start_sys, end_sys, hops) =
    exists(mid_sys, prev_hops, bw:
      fast_path(start_sys, mid_sys, prev_hops) and
      link(mid_sys, end_sys, bw) and bw > 10 and hops = prev_hops + 1)

  // 3. The Query: Select targets connected to "System_A" within 5 hops
  def output(target_sys, hops) =
    fast_path("System_A", target_sys, hops) and hops 
https://www.relational.ai/post/graph-normal-form

https://www.dataversity.net/articles/say-hello-to-graph-norm...

...

That said, modern SQL can do this just fine, just... much harder to read.

  WITH RECURSIVE fast_path AS (
    -- 1. Base case: Directly connected systems from our starting node
    SELECT
      start_sys,
      end_sys,
      1 AS hops
    FROM link
    WHERE start_sys = 'System_A' AND bandwidth > 10
    UNION ALL

    -- 2. Recursive case: Traverse to the next system
    SELECT 
      fp.start_sys, 
      l.end_sys, 
      fp.hops + 1
    FROM fast_path fp
    JOIN link l ON fp.end_sys = l.start_sys
    WHERE l.bandwidth > 10 AND fp.hops 

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#38
post #34

Earlier quoted context omitted.

Interesting! Triblespace seems similar to TerminusDB and the solution presented here - would you mind stating the differences ?

Spot on! In one word. Simplicity! TerminusDB is a RDF database with build-in prolog, a heavy focus on succinct data structure indexes, and has a client server model. Triblespace is purposefully not RDF, because RDF has horrible DX, and it does not have a good reconciliation and distributed consistency story. It's virtually impossible to get RDF data into a canonical form [ https://www.w3.org/TR/rdf-canon/#how-to-read…

This sounds all great - I just wish there was a JS/TS port to be able to use it in the browser or from node/deno/bun!

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#39

Earlier quoted context omitted.

The advantage for property graph databases using Cypher query language is that the queries for things like "show me all systems connected to this system by links greater than 10Gbps up to n hops away" are vastly easier to write and faster to complete compared to SQL and relational databases. Cypher lets you easily search for arbitrary graph patters and the result is also a graph, not a denormalized table.

Parent commenter was asking compare to datalog (not SQL) which eats recursive graph transitions like this for lunch, making the queries very elegant to read ... while still staying relational. I'm personally of the opinion that "graph databases" should be relational databases; the relational model can subsume "graph" queries, but for all the reasons Codd laid out back in the 60s... network (aka connected graph) datab…

JOINS make these kinds of queries get slower as the number of hops gets larger. And property graph databases have the big advantage of not having to mutilate their query results to fit into a flat table. A path query returns a path object of connected nodes. Property graphs are superior for applications with deep, variable-length connections, such as social networks, recommendation engines, fraud detection, and IT network mapping. Property graph databases work well with object oriented programming where objects map to nodes very well.

RelationalAI's model is very cool but it is cloud only software.

Re: A type-safe, realtime collaborative Graph Database in a CRDT

#40
post #34

Earlier quoted context omitted.

Spot on! In one word. Simplicity! TerminusDB is a RDF database with build-in prolog, a heavy focus on succinct data structure indexes, and has a client server model. Triblespace is purposefully not RDF, because RDF has horrible DX, and it does not have a good reconciliation and distributed consistency story. It's virtually impossible to get RDF data into a canonical form [ https://www.w3.org/TR/rdf-canon/#how-to-read…

This sounds all great - I just wish there was a JS/TS port to be able to use it in the browser or from node/deno/bun!

Fair, it actually started out in JS, moved to Deno, then Zig and ended in Rust.

If I ever find the time I'd like to back port what I have now, up the chain.

It is supposed to be a RDF replacement so it will eventually have to happen, but it's hard work to make everything extremely idiomatically integrated into the host language.

Post reply on HN