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

@zvk/db-kit

v0.2.3

Published

Framework-agnostic repository, query, transaction, idempotency, and adapter helpers for ZVK applications.

Readme

@zvk/db-kit

Framework-agnostic repository, query, transaction, idempotency, and adapter helpers for ZVK applications.

import { createRepositoryService, createRepositoryWorkflow } from "@zvk/db-kit";
import { evaluateIdempotencyClaim } from "@zvk/db-kit/idempotency";
import { firstRowOrNull, hasReturnedRow, normalizeCursorPaginationInput } from "@zvk/db-kit/query";
import type { CursorPaginationQuery, PaginationQuery } from "@zvk/db-kit/query";
import { resolveLocalDatabasePath, createSqlitePragmaStatements, createMigrationJournalTableSql } from "@zvk/db-kit/local-sqlite";
import { createDrizzleRepositoryAdapter } from "@zvk/db-kit/drizzle";
import { createDrizzleSelectLimitChain, createMemoryRepository } from "@zvk/db-kit/test-utils";
import { openBunSqliteDatabase, applySqlitePragmas } from "@zvk/db-kit/local-sqlite/bun";
import { createTemporarySqlitePath, createInMemoryMigrationJournal } from "@zvk/db-kit/local-sqlite/test-utils";

See ../../docs/package-boundary-matrix.md for the package-family runtime boundary matrix. The root package and pure query/repository subpaths stay browser-safe; Drizzle and local SQLite helpers stay on explicit adapter, Node-only, or test-only subpaths.

Use evaluateIdempotencyClaim for provider-neutral webhook/job claim decisions after an app maps its own persistence row into an idempotency claim snapshot.

Use firstRowOrNull, exactlyOneRowOrNull, and hasReturnedRow for common database row-array normalization around app-owned query builders.

Use createRepositoryWorkflow when an app already has a repository port and wants a small service recipe for CRUD operations plus paginated lists and single-row list lookups:

const projectWorkflow = createRepositoryWorkflow<
  Project,
  ProjectCreate,
  ProjectUpdate,
  PaginationQuery & { readonly organizationId: string }
>({
  entityName: "Project",
  repository: projectRepository,
  pagination: {
    defaultLimit: 20,
    maxLimit: 100
  }
});

const projects = await projectWorkflow.listPage({
  organizationId,
  limit: 50,
  offset: 0
});

const firstProject = await projectWorkflow.findFirst({
  organizationId
});

The workflow helper only normalizes limit/offset, calls the repository list and optional count ports, returns createPaginatedListResult, and keeps all data inside Result envelopes. App code still owns schemas, filters, authorization, tenancy, SQL, logging, and whether count ignores pagination while respecting app-owned filters.

For cursor or seek pagination, extend an app-owned query type from CursorPaginationQuery and pass opaque cursor fields through the workflow:

type ProjectCursorQuery = CursorPaginationQuery & {
  readonly organizationId: string;
};

const pagination = normalizeCursorPaginationInput({
  afterCursor: request.query.after,
  limit: 50,
  maxLimit: 100
});

normalizeCursorPaginationInput only normalizes limit/offset and preserves cursor, beforeCursor, and afterCursor values as app-owned opaque strings. Apps remain responsible for cursor encoding, stable sort keys, seek predicates, database-specific SQL, and deciding whether offset and cursor fields may be combined for a route.

Use @zvk/db-kit/local-sqlite for local database path resolution, pragma plan generation, and journal-table SQL helpers. This keeps app bootstrapping and migration state setup deterministic without forcing app frameworks to own these reusable concerns.

Use @zvk/db-kit/local-sqlite/bun for Bun-specific SQLite open/exec helpers. Open adapters accept an open callback and apply pragma statements before returning the live handle.

Use @zvk/db-kit/local-sqlite/test-utils for framework-neutral filesystem and migration-journal test helpers.

The root package stays runtime-dependent only on @zvk/contracts. The optional @zvk/db-kit/drizzle subpath provides structural helpers for apps that already use Drizzle ORM, without owning app schemas, migrations, or database policy.

Apps remain responsible for concrete schemas, migration SQL files, migration ordering, repair policy, authorization, tenancy checks, product naming, and business rules.

Use @zvk/db-kit/test-utils for framework-neutral repository fakes and Drizzle chain test doubles. The Drizzle chain helpers do not import a test framework; apps that need spy assertions can pass their own mock-function wrapper.

Repo Skill

Use .codex/skills/use-zvk-db-kit/SKILL.md when maintaining this package.

See ../../docs/package-boundary-matrix.md for the browser-safe, adapter-only, Node-only, and test-only subpaths.