/** * Cache read/write layer for @npm-safe/core. * * {@link CacheManager} sits on top of a {@link DatabaseManager} connection and * provides typed accessors for the cached npm metadata, security scan reports, * watchlist, and key-value settings tables. It owns the TTL policy for the * `packages` table: every {@link CacheManager.setPackage} call stamps the row * with an expiry timestamp (`ttl_until`) computed as `now + cacheTtlMs`, and * {@link CacheManager.getPackage} refuses to return rows whose TTL has * elapsed. Scheduling of refreshes is intentionally out of scope — that is * the job of the refresh-scheduler; this module only reads and writes. * * All methods return `Promise`s for API consistency and future async backing * stores, even though the underlying `better-sqlite3` calls are synchronous. * * @module store/cache-manager */ import { DatabaseManager } from "./database.js"; import type { PackageMetadata } from "../registry/types.js"; import { type LlmScanReport, type StaticScanReport } from "../scanner/types.js"; /** * Default cache time-to-live for package metadata: 1 hour in milliseconds. */ export declare const DEFAULT_CACHE_TTL_MS = 3600000; /** * Options accepted by the {@link CacheManager} constructor. */ export interface CacheManagerOptions { /** * Time-to-live for cached package metadata, in milliseconds. A row fetched * via {@link CacheManager.getPackage} is considered stale once `ttl_until` * is in the past. Sub-second TTLs (e.g. `500`) are supported and stored * with millisecond precision. Defaults to {@link DEFAULT_CACHE_TTL_MS} * (1 hour). */ readonly cacheTtlMs?: number; } /** * Cache read/write manager backed by a {@link DatabaseManager} connection. * * The manager is stateless beyond the TTL configuration and the injected * database handle, so it is safe to construct one per request or to share a * long-lived instance. All public methods are async-returning for API * consistency; the underlying `better-sqlite3` calls are synchronous. */ export declare class CacheManager { /** Underlying better-sqlite3 connection accessor. */ private readonly db; /** Cache TTL in milliseconds applied to newly written package rows. */ private readonly cacheTtlMs; /** * @param database - The {@link DatabaseManager} supplying the connection. * @param options - Optional configuration; see {@link CacheManagerOptions}. */ constructor(database: DatabaseManager, options?: CacheManagerOptions); /** * Returns cached package metadata for `name` if the row is still fresh * (i.e. `ttl_until >= now`). Returns `null` when the row is missing or * stale; callers are expected to re-fetch from the registry and call * {@link CacheManager.setPackage} to refresh the cache. * * @param name - Fully-qualified package name (scope included when scoped). * @returns The cached {@link PackageMetadata}, or `null` if absent/stale. */ getPackage(name: string): Promise; /** * Upserts a package metadata row, stamping it with a fresh TTL computed as * `now + cacheTtlMs`. The full packument is serialized into the * `registry_data` JSON column; the scalar columns (`latest_version`, * `description`, `homepage`, `repository`) are denormalized for cheap * listing queries. * * @param meta - The packument returned by the npm registry. */ setPackage(meta: PackageMetadata): Promise; /** * Returns the most recent static security report for `pkg`@`version`, or * `null` if none is cached. The {@link SecurityLevel} is reconstructed from * the persisted numeric score because the `security_reports` table stores * only the score, not the enum. * * @param pkg - Fully-qualified package name. * @param version - Semver version string. * @returns The cached {@link StaticScanReport}, or `null` if absent. */ getSecurityReport(pkg: string, version: string): Promise; /** * Upserts a static security report into the `security_reports` table. The * findings array is serialized to JSON in the `findings_json` column; the * numeric score is stored in `overall_score`. The row is keyed by * `(package_name, version, scan_type)` via the table's UNIQUE constraint. * * @param report - The static scan report to persist. */ setSecurityReport(report: StaticScanReport): Promise; getLlmScanReport(pkg: string, version: string): Promise; setLlmScanReport(packageName: string, version: string, report: LlmScanReport): Promise; /** * Returns the list of package names currently on the user's watchlist. * * @returns All watched package names, in insertion order. */ getWatchlist(): Promise; /** * Adds `name` to the watchlist. Idempotent: inserting a name that is * already watched is a no-op (INSERT OR IGNORE). * * @param name - Fully-qualified package name to watch. */ addToWatchlist(name: string): Promise; /** * Removes `name` from the watchlist. No-op if the name was not watched. * * @param name - Fully-qualified package name to stop watching. */ removeFromWatchlist(name: string): Promise; /** * Returns the value stored under `key` in the settings table, or `null` * if the key is unset. * * @param key - Settings key. * @returns The stored value, or `null` if absent. */ getSetting(key: string): Promise; /** * Upserts `value` under `key` in the settings table (INSERT OR REPLACE). * * @param key - Settings key. * @param value - Settings value to persist. */ setSetting(key: string, value: string): Promise; /** * Returns the names of all cached package rows whose TTL has elapsed * (`ttl_until < now`). These are candidates for an incremental refresh by * the refresh-scheduler. * * @returns Package names with expired cache entries. */ getStalePackages(): Promise; /** * Append an entry to the persistent check history, keeping only the most * recent {@link MAX_CHECK_HISTORY} entries. */ addHistoryEntry(entry: { readonly packageName: string; readonly level: string; readonly score: number; readonly timestamp: string; }): Promise; /** * Return the persistent check history, newest first. */ getHistory(limit?: number): Promise>; /** * Remove every entry from the persistent check history. */ clearHistory(): Promise; } /** Maximum number of check-history entries retained in the database. */ export declare const MAX_CHECK_HISTORY = 1000; //# sourceMappingURL=cache-manager.d.ts.map