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

opticore-profiler

v1.0.4

Published

Web debug toolbar

Readme

OptiCore Profiler

OptiCore profiler : collect → persist by token → display deferred.

Installation

npm install opticore-profiler

Requires opticore-express and opticore-router in the host app (both are declared dependencies and installed automatically) and Node.js >= 18.

The 4 principles, and where they live

  1. Collectors observe, they never intrude. DataCollector (types.ts) defines collect(ctx, error?) / getName() / getData() / reset(). RequestCollector/TimeCollector/MemoryCollector read only from the req/res objects the middleware already has. DatabaseCollector and LoggerCollector are fed by decorating a DB driver/client's prototype method and LoggerCore.prototype.{info,warn,error,debug,success} once, at bootstrap (instrumentDatabase/instrumentLogger) — business code keeps calling db.query(...) / logger.info(...) completely unmodified, and unaware profiling exists. instrumentDatabase is not tied to any one database: it wraps whichever method you point it at and turns that method's own arguments into { sql, bindings } via a small extract function you supply, so it works the same way for MySQL, MariaDB, Postgres, OracleDB, MongoDB, or any other driver. Ready-made presets (instrumentMySQL, instrumentMariaDB, instrumentPostgres, instrumentOracleDB, instrumentMongoDB) cover the common ones — see instrumentation/database.instrumentation.ts. The link between "a query just ran" and "which request is that for" is AsyncLocalStorage (context.ts), the Node analogue of what a DI container gives Symfony's collectors implicitly. Register custom collectors on the registry the middleware exposes: profiler.registry.register(() => new MyCollector()).

  2. Persistence is decoupled from collection, keyed by token. Every profiled request gets a short token (token.ts, 6–8 alphanumeric chars). On res.on('finish') — i.e. after the response has already been sent, so this adds zero perceived latency — every collector's getData() is assembled into a Profile and handed to a ProfilerStorage (MemoryStorage or FileStorage, under .opticore-profiler-cache/ by default). X-Debug-Token and X-Debug-Token-Link headers are set on every profiled response. Automatic purge runs after each write (retentionMs, default 24h).

  3. Display is deferred and AJAX-loaded, not embedded. The middleware never renders a toolbar into the page it's decorating. It buffers HTML responses (middleware/htmlInjector.ts) and, only when the response is text/html, splices a handful of lines before </body> (middleware/snippet.ts): a stylesheet <link> and a <script> that fetches GET ${routePrefix}/wdt/:token and swaps it in. That fragment, plus GET ${routePrefix} (list) and GET ${routePrefix}/:token (detail, one panel per collector), are the only 3 profiler routes — all excluded from profiling themselves. assets/js/toolbar.js also wraps fetch and XMLHttpRequest client-side so AJAX calls the page itself makes (which carry the same X-Debug-Token header, since they're profiled requests too) show up live in the toolbar's HTTP list.

  4. Ephemeral by default, safe by construction. enabled defaults to false — must be explicitly turned on (NODE_ENV === 'development'). RequestCollector masks configurable sensitive keys (security/masker.ts, default list in DEFAULT_SENSITIVE_KEYS: authorization, cookie, password, token, session, ...) in headers/cookies/query/body before the data is ever persisted. Nunjucks' autoescape: true covers template output; security/escape.ts and toolbar.js's own escapeHtml() cover the two spots that build HTML by hand. profiler.clear() purges everything on demand.

Integration example

import { express } from "opticore-express";
import { OptiCoreMySQLDriver } from "opticore-mysqldb";
import { LoggerCore } from "opticore-logger";
import {
    opticoreProfiler,
    profilerErrorHandler,
    registerProfilerViews,
    createProfilerRouter,
    instrumentMySQL,
    instrumentLogger,
    FileStorage,
} from "opticore-profiler";

const app = express();

// Decorate infrastructure once, at bootstrap — never touches business code.
instrumentMySQL(OptiCoreMySQLDriver);
instrumentLogger(LoggerCore);

const profiler = opticoreProfiler({
    enabled: process.env.NODE_ENV === "development",
    storage: new FileStorage(".profiler-cache"), // any writable directory of your choosing
});

app.use(profiler);                        // 1. collection + token + deferred display
registerProfilerViews(app, profiler);      // 2. view engine, static assets, "/" page

app.use(/* ...your feature routers, including createProfilerRouter(profiler)... */);

app.use(profilerErrorHandler());           // 3. after routes: feeds ExceptionCollector
app.use(yourOwnErrorHandler);              //    your app's error handling is untouched

Instrumenting other databases

instrumentMySQL is one preset among several, all built on the same driver-agnostic instrumentDatabase. Use whichever preset matches your stack, or call instrumentDatabase directly for anything else:

import { Pool } from "pg";
import {
    instrumentPostgres,   // pg's query(text, values)
    instrumentMariaDB,    // mariadb's query(sql, values)
    instrumentOracleDB,   // oracledb's execute(sql, binds)
    instrumentMongoDB,    // MongoDB's Collection CRUD methods
    instrumentDatabase,   // the generic engine, for anything else
} from "opticore-profiler";

instrumentPostgres(Pool);
instrumentMariaDB(MariaDbConnection);
instrumentOracleDB(OracleConnection);
instrumentMongoDB(MongoCollection);

// Any other driver: wrap its query method and describe how to read its arguments.
instrumentDatabase(SomeDriver, {
    type: "my-db",
    method: "runQuery",
    extract: (sql: string, params?: unknown[]) => ({ sql, bindings: params }),
});