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

@happyvertical/smrt-core

v0.36.0

Published

Core AI agent framework with standardized collections, object-relational mapping, and code generators

Downloads

7,224

Readme

@happyvertical/smrt-core

ORM, code generation, AI integration, and the DispatchBus. Everything else in the SMRT framework builds on this.

Installation

pnpm add @happyvertical/smrt-core

Usage

Define a class with @smrt()

import { smrt, SmrtObject, SmrtCollection, foreignKey } from '@happyvertical/smrt-core';

@smrt({ api: true, cli: true, mcp: true })
class Product extends SmrtObject {
  name: string = '';
  price: number = 0.0;          // DECIMAL (has decimal point)
  quantity: number = 0;          // INTEGER (no decimal point)
  isPublished: boolean = false;
  categoryId = foreignKey(Category);
}

class ProductCollection extends SmrtCollection<Product> {
  static readonly _itemClass = Product;
}

Basic CRUD

const products = await ProductCollection.create({ db: 'products.db' });

// Create
const product = await products.create({ name: 'Widget', price: 9.99 });
await product.save();

// Query
const results = await products.list({
  where: { isPublished: true, price: { op: '>', value: 5 } },
  orderBy: 'price DESC',
  limit: 20,
});

// AI operations
const isExpensive = await product.is('costs more than the average product');
const description = await product.do('Write a short marketing description');

Opt-In Read Cache

SSR apps that re-query read-heavy / write-rare collections on every request can memoize list() and get() results with an opt-in TTL. Defaults are off — nothing is cached unless a call or model opts in.

// Per call
const published = await resumes.list({
  where: { status: 'published' },
  cache: { ttl: 60_000 },
});

// Per model — list()/get() on this collection cache by default
@smrt({ cache: { ttl: 60_000 } })
class Resume extends SmrtObject {}

// Force a fresh read on hot paths that must read through
const latest = await resumes.list({ cache: false });

Because SMRT owns every mutation path (save(), delete(), collection.create(), getOrUpsert(), junction attach/detach), any write automatically invalidates the affected table's cached entries in-process — including STI siblings sharing the table. Cached values are raw rows: hydration and read interceptors (tenancy, audit) still run on every call.

Caches are per-process. For multi-replica deployments, add crossProcess: true to broadcast invalidations over the database adapter's notification capability (e.g. Postgres LISTEN/NOTIFY) so peers drop their entries immediately instead of waiting out the TTL:

@smrt({ cache: { ttl: 60_000, crossProcess: true } })
class Resume extends SmrtObject {}

Model-level config is the reliable cross-process opt-in: every process writing the model knows to broadcast, and STI children writing the shared table broadcast even if they opted out of caching their own reads. As a per-call option (list({ cache: { ttl, crossProcess: true } })), writes broadcast only from processes that have already performed such a read — typical for homogeneous replicas running the same routes, but a write-only process never learns about a call-site opt-in.

Writes that bypass SMRT (raw SQL, external processes without crossProcess) are only bounded by the TTL — pick one that matches how stale the data may be.

Bundled Runtimes And External Manifests

Long-lived bundled runtimes such as SvelteKit servers, background workers, and CLI entrypoints should ship two things together:

  1. The generated smrt-register runtime entrypoint for local class registration.
  2. The manifest.json exports for any installed external @happyvertical/smrt-* packages the runtime needs to hydrate at query time.

ObjectRegistry.ensureManifestLoaded() can now auto-load installed external classes by either simple name ('EventType') or qualified name ('@happyvertical/smrt-events:EventType'). SmrtCollection.list() and SmrtCollection.get() use that path when they encounter STI discriminators from external packages, so bundled runtimes do not need to import every child class eagerly just to hydrate rows correctly.

If you want to avoid on-demand manifest discovery in a long-lived process, call ObjectRegistry.loadAllManifests() during startup after your local registration file has run.

API

Core Classes

| Export | Description | |--------|------------| | SmrtClass | Base class with DB, AI, and filesystem access | | SmrtObject | Persistent object — save, delete, is(), do() | | SmrtCollection | CRUD collection — list, get, create, upsert | | ObjectRegistry | Global singleton for class/field metadata | | smrt (decorator) | Registers a class for code generation and AI |

Field Decorators

| Export | Description | |--------|------------| | field | General-purpose field decorator | | foreignKey | Foreign key relationship | | oneToMany | One-to-many relationship | | manyToMany | Many-to-many relationship | | meta | STI child field stored in _meta_data JSONB |

Dispatch (Inter-Agent Messaging)

| Export | Description | |--------|------------| | DispatchBus | Persistent message bus with wildcard subscriptions | | createDispatchBus | Factory function for DispatchBus | | Dispatch | Dispatch record model | | DispatchSubscription | Persistent subscription model |

Code Generators

| Export | Description | |--------|------------| | APIGenerator | Generates OpenAPI-compliant REST endpoints | | MCPGenerator | Generates Model Context Protocol tool servers | | createRestServer | Creates an Express REST server from config | | generateOpenAPISpec | Generates OpenAPI/Swagger spec |

Embeddings (Semantic Search)

| Export | Description | |--------|------------| | EmbeddingProvider | Generates embeddings via AI provider | | EmbeddingStorage | Persists/queries embedding vectors | | CosineSimilarity | Ranks results by vector similarity | | ContentHasher | Content hashing for change detection |

Signals (Observability)

| Export | Description | |--------|------------| | SignalBus | Universal method-tracking event bus | | SignalSanitizer | Sanitizes sensitive data in signals | | MetricsAdapter | Prometheus-compatible metrics adapter | | PubSubAdapter | Broadcast signals to subscribers |

Manifest (Build-Time Metadata)

| Export | Description | |--------|------------| | ManifestManager | Reads, writes, and generates manifests | | ManifestBuilder | Orchestrates scanning to manifest | | ManifestGenerator | Converts scan results to manifest format | | getManifest | Async getter for static manifest data |

Runtime

| Export | Description | |--------|------------| | createMCPServer / SmrtMCPServer | MCP server runtime | | createSmrtServer | REST server runtime | | createSmrtClient | API client runtime |

Schema & Migrations

| Export | Description | |--------|------------| | SchemaComparer | Compares current vs. desired schema | | generateSchemaDiff | Produces a diff between two schemas | | getSQLFromDiff | Converts schema diff to SQL statements |

Interceptors

| Export | Description | |--------|------------| | GlobalInterceptors | Plugin hooks for beforeList/Get/Save/Delete | | createInterceptorContext | Creates context for interceptor execution |

Errors

| Export | Description | |--------|------------| | SmrtError | Abstract base error class | | DatabaseError | Database operation failures | | AIError | AI provider failures | | ValidationError | Field/object validation failures | | RuntimeError | General runtime failures | | ErrorUtils | Sanitization and formatting helpers |

Tools (AI Function Calling)

| Export | Description | |--------|------------| | generateToolManifest | Generates AI tool definitions from methods | | executeToolCall / executeToolCalls | Executes AI tool calls |

Utilities

| Export | Description | |--------|------------| | config | Global SMRT configuration function | | resolveDatabase | Resolves DB config to a DatabaseInterface | | smrtPlugin | Vite plugin for auto-service generation | | generateSvelteKitRoutes | SvelteKit route generator | | resetVerifiedTables | Resets table verification cache (testing) | | getTestDatabase | Creates isolated test databases | | parse / stringify / clone | JSON utilities with optional SIMD | | createQualifiedName / parseQualifiedName | STI qualified name helpers |

Code Generation

The @smrt() decorator controls what gets generated. Set api, cli, or mcp to true or { include: [...] }:

@smrt({
  api: { include: ['list', 'get', 'create'] },
  mcp: true,
  cli: true,
})
class Product extends SmrtObject { /* ... */ }

Generators produce OpenAPI REST endpoints, Commander CLI commands, and MCP server tools respectively. The Vite plugin (smrtPlugin) generates virtual modules at dev time for routes, clients, and manifests.

Dependencies

  • @happyvertical/ai -- AI client (is/do operations, embeddings)
  • @happyvertical/sql -- Database interface (SQLite, PostgreSQL)
  • @happyvertical/files -- Filesystem adapter
  • @happyvertical/logger -- Structured logging
  • @happyvertical/smrt-types -- Shared type definitions