npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@divinci-ai/do-graph-memory

v0.1.0

Published

SQLite-backed graph database for agent memory on Cloudflare Durable Objects or Node.js

Readme

@divinci-ai/do-graph-memory

SQLite-backed graph database for agent memory. Works with Cloudflare Durable Objects and Node.js (via better-sqlite3).

Inspired by Boris Tane's DO graph DB pattern and Mem0's memory classification.

Features

  • Graph database — Nodes + edges with typed relationships, BFS traversal, neighbor queries
  • Mem0 memory types — Semantic (facts), Procedural (skills), Episodic (events), Working (context)
  • FTS5 search with graceful LIKE fallback when FTS5 isn't available
  • Context aggregation — Build structured memory context for LLM agent reasoning
  • Skill registry — Register, search, track, and relate agent skills (separate subpath export)
  • Two adapters — Cloudflare Durable Object SQL or better-sqlite3 (Node.js)
  • Zero runtime dependencies@cloudflare/workers-types and better-sqlite3 are optional peer deps
  • Schema migrations with rollback support

Install

npm install @divinci-ai/do-graph-memory
# or
pnpm add @divinci-ai/do-graph-memory

For Node.js usage, also install better-sqlite3:

npm install better-sqlite3

Quick Start

Node.js (better-sqlite3)

import { GraphMemory, createBetterSqlite3Adapter } from "@divinci-ai/do-graph-memory";
import Database from "better-sqlite3";

const db = new Database("agent-memory.db");
const adapter = createBetterSqlite3Adapter(db);
const memory = new GraphMemory({ adapter });
memory.initialize();

// Add facts
memory.addFact("user:theme", "User theme preference", "dark");
memory.addFact("config:model", "Default model", "gpt-4");

// Add a skill
memory.addSkill("skill:summarize", "Summarize Text", "Summarizes long text into key points", {
  capabilities: ["text-read"],
});

// Connect nodes
memory.addEdge({
  source: "user:theme",
  target: "config:model",
  relationship: "configured_with",
});

// Traverse the graph
const result = memory.traverse("user:theme", { maxDepth: 3 });
console.log(`Found ${result.nodes.length} connected nodes`);

// Build context for LLM reasoning
const context = memory.buildContext({ anchor: "user:theme", depth: 2 });
// context.facts, context.skills, context.history, context.working

Cloudflare Durable Objects

import { GraphMemory, createDurableObjectAdapter } from "@divinci-ai/do-graph-memory";

export class AgentMemory extends DurableObject {
  private memory: GraphMemory;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    const adapter = createDurableObjectAdapter(ctx.storage);
    this.memory = new GraphMemory({ adapter });
    ctx.blockConcurrencyWhile(async () => this.memory.initialize());
  }

  async addFact(id: string, label: string, value: unknown) {
    return this.memory.addFact(id, label, value);
  }

  async buildContext(anchor: string) {
    return this.memory.buildContext({ anchor, depth: 3 });
  }
}

API

GraphMemory

new GraphMemory(options: {
  adapter: SqlAdapter;    // Required: DO or better-sqlite3 adapter
  logger?: Logger;        // Optional: defaults to silent
  autoId?: boolean;       // Optional: auto-generate UUIDs for nodes
})

Node Operations:

  • addNode(node) / addNodes(nodes) — Create one or many nodes
  • getNode(id) — Get by ID
  • updateNode(id, updates) — Partial update
  • deleteNode(id) — Delete (cascades to edges)
  • queryNodes(query) — Filter by type, subtype, label, data, dates
  • searchNodes(term, limit?) — Full-text search (FTS5 or LIKE fallback)

Edge Operations:

  • addEdge(edge) / addEdges(edges) — Create relationships
  • getEdges(nodeId, direction?) — Get edges for a node
  • deleteEdge(source, target, relationship) — Remove a relationship
  • findNeighbors(nodeId, options?) — Find connected nodes

Traversal & Context:

  • traverse(startId, options?) — BFS graph traversal
  • buildContext(options) — Aggregate memory context for agent reasoning

Convenience (Mem0-style):

  • addFact(id, label, value, options?) — Semantic node
  • addSkill(id, label, description, options?) — Procedural node
  • addEpisode(id, label, description, options?) — Episodic node
  • setWorkingContext(id, label, state, ttlMs?) — Working memory with TTL
  • getWorkingContext() — Get current working context

SkillRegistry

import { SkillRegistry } from "@divinci-ai/do-graph-memory/skill-registry";

const registry = new SkillRegistry(memory, memory.adapter);
registry.initialize(); // Runs skill_stats migration

registry.registerSkill({
  id: "skill:analyze",
  name: "Analyze Data",
  description: "Analyzes datasets",
  category: "data",
  capabilities: ["data-read"],
});

// Track executions
registry.recordExecution({
  skillId: "skill:analyze",
  outcome: "success",
  duration: 1200,
});

// Query stats
const stats = registry.getSkillStats("skill:analyze");
const topSkills = registry.getMostSuccessfulSkills(5);

Adapters

// Node.js
import { createBetterSqlite3Adapter } from "@divinci-ai/do-graph-memory/adapters/better-sqlite3";
import Database from "better-sqlite3";
const adapter = createBetterSqlite3Adapter(new Database("file.db"));

// Cloudflare Durable Objects
import { createDurableObjectAdapter } from "@divinci-ai/do-graph-memory/adapters/durable-object";
const adapter = createDurableObjectAdapter(ctx.storage);

SqlAdapter Interface

Implement this to bring your own SQLite driver:

interface SqlAdapter {
  exec(query: string, ...bindings: unknown[]): SqlRow[];
  run(query: string, ...bindings: unknown[]): { changes: number };
  transaction<T>(fn: () => T): T;
}

Data Filters

Query nodes by JSON data properties using json_extract:

memory.queryNodes({
  type: "semantic",
  dataFilters: { category: "network", priority: 1 },
});

Exports

| Import path | What you get | |---|---| | @divinci-ai/do-graph-memory | GraphMemory, types, adapters, schema utils | | @divinci-ai/do-graph-memory/skill-registry | SkillRegistry, skill types | | @divinci-ai/do-graph-memory/adapters/better-sqlite3 | createBetterSqlite3Adapter, hasFts5 | | @divinci-ai/do-graph-memory/adapters/durable-object | createDurableObjectAdapter |

License

MIT