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

@tekmemo/graph

v0.1.0

Published

Provider-neutral graph memory primitives for TekMemo.

Readme

@tekmemo/graph

Provider-neutral graph memory primitives for TekMemo.

This package adds relationship memory without requiring Neo4j, Turso, Qdrant, Upstash, OpenAI, Voyage, TekMemo Cloud, or any external runtime dependency.

Why it exists

Vector recall answers:

What text is semantically close to this query?

Graph memory answers:

Which entities are connected?
Why are they connected?
Which facts came from which source?
Which relationship changed, expired, or superseded another fact?

TekMemo needs both because graph memory handles relationship questions that pure vector similarity often misses.

Package boundary

This package owns:

  • graph node and edge contracts
  • in-memory graph store
  • graph validation
  • metadata and source provenance validation
  • neighbor traversal
  • shortest path search
  • node merge
  • edge decay
  • temporal filtering
  • supersession invalidation helpers
  • deterministic rule-based extraction
  • JSONL parse/serialize helpers
  • graph import/export snapshots

It does not own:

  • filesystem writes to .tekmemo/
  • vector databases
  • embeddings
  • reranking
  • cloud sync
  • auth, billing, tenant logic, or plan checks
  • connector fetching
  • graph database adapters

.tekmemo fit

The package is designed to back this canonical protocol area:

.tekmemo/graph/
├─ nodes.jsonl
└─ edges.jsonl

A filesystem adapter such as @tekmemo/fs should read/write those files. This package only validates, serializes, parses, stores in memory, and queries graph records.

Install

pnpm add @tekmemo/graph

Basic usage

import { createInMemoryGraphStore } from "@tekmemo/graph";

const graph = createInMemoryGraphStore();

await graph.upsertNodes([
  {
    id: "project:tekmemo",
    type: "project",
    label: "TekMemo",
    summary: "File-first memory runtime for AI apps and agents.",
    metadata: { projectId: "proj_1" }
  },
  {
    id: "concept:local-first",
    type: "concept",
    label: "Local-first memory",
    aliases: ["local memory", ".tekmemo files"],
    metadata: { projectId: "proj_1" }
  }
]);

await graph.upsertEdges([
  {
    from: "project:tekmemo",
    to: "concept:local-first",
    type: "uses",
    weight: 0.9,
    directed: true,
    metadata: { projectId: "proj_1" }
  }
]);

const neighbors = await graph.neighbors({
  nodeId: "project:tekmemo",
  direction: "out"
});

Behind the scenes

The in-memory store keeps two maps:

Map<nodeId, StoredGraphNode>
Map<edgeId, StoredGraphEdge>

When an edge does not include an ID, the store creates a deterministic ID from:

from + type + to + directed

That prevents duplicate semantic relationships during repeated ingestion.

Production safety

The @tekmemo/graph package protects your graph memory by rejecting:

  • invalid graph IDs
  • missing nodes for new edges (when requireExistingNodes is enabled)
  • self-edges (unless explicitly enabled)
  • duplicate IDs within a single batch
  • metadata values that are not true JSON values (rejects circular references, NaN, undefined, functions, etc.)
  • unsafe or absolute source reference paths
  • malformed JSONL when parsing in strict mode
  • traversals that exceed depth or result limits

Temporal facts

Nodes and edges can use:

status?: "active" | "deprecated" | "conflicted" | "deleted";
validFrom?: string;
validUntil?: string;
expiresAt?: string;

By default, queries skip inactive and expired facts. Pass includeInactive or includeExpired when inspection tooling needs the full history.

Provenance

Nodes and edges can include source references:

sourceRefs: [
  {
    sourceType: "document",
    path: ".tekmemo/memory/core.md",
    span: { start: 120, end: 180 }
  }
]

This preserves explainability. TekMemo should never return graph memory without being able to explain where it came from.

Depth caps

Graph expansion has a default depth and a hard max. This avoids accidental infinite or explosive traversal on dense graphs.

import { expandFromEntities } from "@tekmemo/graph";

const result = await expandFromEntities({
  store: graph,
  seedNodeIds: ["project:tekmemo"],
  depth: 2,
  limit: 100
});

JSONL helpers

import {
  serializeGraphNodesJsonl,
  serializeGraphEdgesJsonl,
  parseGraphNodesJsonl,
  parseGraphEdgesJsonl
} from "@tekmemo/graph";

Malformed lines throw by default. Inspector tools can use detailed parsing with onInvalidLine: "skip":

import { parseGraphNodesJsonlDetailed } from "@tekmemo/graph";

const result = parseGraphNodesJsonlDetailed(content, {
  onInvalidLine: "skip"
});

console.log(result.rows);
console.log(result.issues);

Rule-based extraction

This package includes a deterministic extractor for simple structured text. It is intentionally not an LLM extractor.

import { extractGraphFactsRuleBased } from "@tekmemo/graph";

const facts = extractGraphFactsRuleBased({
  text: "TekMemo -> uses -> Local-first memory",
  sourceRef: {
    sourceType: "document",
    path: ".tekmemo/memory/core.md"
  }
});

Supported examples:

TekMemo -> uses -> Local-first memory
TekMemo depends on TypeScript
User prefers Rust examples
Decision supersedes old pricing model

For production LLM extraction, build a separate adapter later. Keep this package provider-neutral.

Cloud and Provider Neutrality

@tekmemo/graph is intentionally provider-neutral and contains no network code. It does not perform cloud calls and does not store provider credentials. It is designed to be wrapped by persistence adapters (like @tekmemo/fs) or hosted cloud services that handle long-term storage and LLM-assisted extraction.