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

@chatman-media/storage

v1.38.0

Published

PostgreSQL storage adapters for @chatman-media/sales — Drizzle ORM implementations of all engine interfaces.

Readme

@chatman-media/storage

npm CI TypeScript Bun License: MIT used by @chatman-media/sales

PostgreSQL storage adapters for @chatman-media/sales. Drizzle ORM implementations of all engine repository interfaces — users, conversations, leads, skills, ELO ratings, self-play matches, pairwise comparisons, and shadow evaluations.

Built from the production persistence layer of the Lead Engine platform — multi-tenant SaaS with Postgres RLS.


What's inside

| Repo class | Interface | What it does | |------------|-----------|-------------| | PgUsersRepo | IUsersRepo | Upsert Telegram user accounts by telegramId | | PgConversationsRepo | IConversationsRepo | Create conversations linked to a user + style slug | | PgLeadsRepo | ILeadsRepo | Create sales leads within a conversation | | PgSkillsRepo | ISkillsRepo | Fetch all skill definitions for a given style | | PgSkillOutcomesRepo | ISkillOutcomesRepo | Record per-lead skill outcomes; aggregate win/loss/draw counts | | PgStyleRatingsRepo | IStyleRatingsRepo | Get/set ELO ratings per style (default 1500, upserted on change) | | PgSelfPlayMatchesRepo | ISelfPlayMatchesRepo | Insert & query self-play match records with full transcripts | | PgPairwiseMatchesRepo | IPairwiseMatchesRepo | Record head-to-head comparisons between two self-play matches | | PgShadowEvaluationsRepo | IShadowEvaluationsRepo | Track evaluation run state (status, decision, pair counts, error) |


Install

bun add @chatman-media/storage     # Bun
npm install @chatman-media/storage # npm / pnpm / yarn

Peer dependencies:

bun add drizzle-orm postgres @chatman-media/sales

Quick start

import postgres from "postgres";
import { drizzle } from "drizzle-orm/postgres-js";
import { createPgRepos, schema } from "@chatman-media/storage";

const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client, { schema });

const { users, conversations, leads, skills, outcomes, ratings, matches, pairwise, shadowEvals } =
  createPgRepos(db);

// upsert a Telegram user
const { id: userId } = await users.upsert({ telegramId: 123456789, username: "alice" });

// start a conversation and a lead
const { id: convId } = await conversations.create({ userId, styleSlug: "marina-prime-v1" });
const { id: leadId } = await leads.create({ conversationId: convId });

// record a skill outcome
await outcomes.record({ skillSlug: "mirroring", styleSlug: "marina-prime-v1", leadId, outcome: "won", source: "judge" });

// read ELO rating
const elo = await ratings.getRating(42); // → 1500 (default)

Storage interfaces

All classes implement interfaces from @chatman-media/sales — swap the implementation without touching engine code:

import type { ISelfPlayMatchesRepo } from "@chatman-media/sales";

// Implement for any backend (SQLite, in-memory, …):
class MyMatchesRepo implements ISelfPlayMatchesRepo {
  async insert(match) { /* ... */ }
  async byId(id) { /* ... */ }
  async list(opts) { /* ... */ }
}

Database schema

| Table | Description | |-------|-------------| | users | Telegram user accounts (telegram_id unique) | | conversations | Conversations linked to a user and a style slug | | leads | Sales leads within a conversation | | skill_outcomes | Per-lead skill performance records (won / lost / draw) | | style_ratings | ELO ratings per style (default 1500), upserted on change | | skills | Skill definitions — slug, family, prompt fragment, applicable stages (JSONB) | | self_play_matches | Single-style match records with full transcript (JSONB) | | pairwise_matches | Head-to-head comparisons between two self-play matches | | shadow_evaluations | Evaluation run state — status, decision, pair counts, error |


Architecture

@chatman-media/storage
├── schema.ts          9 Drizzle table definitions (pgTable)
├── pg/
│   └── index.ts       All repo classes + createPgRepos()
└── index.ts           Public exports

Depends on @chatman-media/sales for repo interfaces and domain types (SelfPlayMatchRecord, SkillAggregate, SkillRow, …).


Environment variables

| Variable | Description | |----------|-------------| | DATABASE_URL | PostgreSQL connection string — used by drizzle-kit CLI commands |

Commands

| Command | Description | |---------|-------------| | npm run build | Bundle src/index.tsdist/ with type declarations | | npm run typecheck | TypeScript type check without emitting | | npm run check | Lint source with Biome | | npm run format | Auto-format source with Biome | | npm run db:generate | Generate Drizzle migration files from schema changes | | npm run db:migrate | Apply pending migrations to the database | | npm test | Run tests with bun |

Migrations

# After changing src/schema.ts, generate a new migration:
npm run db:generate

# Apply all pending migrations:
DATABASE_URL=postgres://... npm run db:migrate

Migration files are written to ./migrations/ and tracked in version control.


License

MIT — Alexander Kireev / chatman-media