Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

## ⚡ Highlights

- **Native TypeScript**: Written entirely in strict TypeScript with complete auto-generated type declarations (`.d.ts`).
- **Zero External Dependencies**: Lightweight and fast, zero extra npm package footprint.
- **Embedded Real-Time Dashboard**: Built-in dark mode dashboard UI with Server-Sent Events (SSE) live streaming.
- **True Percentile Latencies**: Sliding window calculation of **p50, p90, p95, and p99** response times globally and per-route.
Expand Down
109 changes: 0 additions & 109 deletions index.js

This file was deleted.

115 changes: 115 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import createMiddleware from './src/middleware.ts';
import type { ExpressLensOptions } from './src/middleware.ts';
import store from './src/store.ts';
import type { ExpressLensMetrics, Percentiles } from './src/store.ts';
import {
prometheusHandler as createPrometheusHandler,
getPrometheusMetrics as generatePrometheusMetrics,
} from './src/prometheus.ts';
import { dashboardHandler as createDashboardHandler } from './src/dashboard.ts';
import { generateCurl as buildCurl } from './src/utils.ts';
import type { RequestPayload } from './src/utils.ts';

/**
* Express Monitor Middleware Factory
* @param options Configuration options
* @returns Express middleware function
*/
export default function monitor(options: ExpressLensOptions = {}): (req: any, res: any, next: any) => void {
return createMiddleware(options);
}

/**
* Get a JSON snapshot of all current metrics.
* @returns Current metrics object
*/
export function getMetrics(): ExpressLensMetrics {
return store.getMetrics();
}

/**
* Calculate percentiles (p50, p90, p95, p99) for latency samples.
* @param samples Optional latency samples array
* @returns Percentiles object { p50, p90, p95, p99 }
*/
export function getPercentiles(samples?: number[]): Percentiles {
return store.getPercentiles(samples);
}

/**
* Reset all stored metrics to their initial state.
*/
export function resetMetrics(): void {
store.reset();
}

/**
* Express middleware route handler to serve metrics JSON over HTTP.
* @returns Express request handler (req, res)
*/
export function metricsHandler(): (req: any, res: any) => void {
return function (_req: any, res: any): void {
if (typeof res.setHeader === 'function') {
res.setHeader('Content-Type', 'application/json');
}
if (typeof res.json === 'function') {
res.json(getMetrics());
} else if (typeof res.send === 'function') {
res.send(JSON.stringify(getMetrics(), null, 2));
} else if (typeof res.end === 'function') {
res.end(JSON.stringify(getMetrics(), null, 2));
}
};
}

/**
* Formats metrics in standard Prometheus exposition format text.
* @returns Prometheus formatted string
*/
export function getPrometheusMetrics(): string {
return generatePrometheusMetrics();
}

/**
* Express middleware route handler to serve Prometheus format metrics over HTTP.
* @returns Express request handler (req, res)
*/
export function prometheusHandler(): (_req: any, res: any) => void {
return createPrometheusHandler();
}

/**
* Express middleware route handler to serve the interactive web dashboard & SSE events stream.
* @returns Express request handler (req, res, next)
*/
export function dashboardHandler(): (req: any, res: any, next: any) => void {
return createDashboardHandler();
}

/**
* Exports stored requests as a standard HTTP Archive (HAR 1.2) JSON object.
* @param title Optional log title
* @returns HAR 1.2 compliant log object
*/
export function exportHAR(title?: string): any {
return store.exportHAR(title);
}

/**
* Replays a previously captured HTTP request by its ID.
* @param requestId Unique ID of the captured request
* @param fetchFn Custom fetch implementation
* @returns Execution result promise
*/
export function replayRequest(requestId: string, fetchFn?: any): Promise<any> {
return store.replayRequest(requestId, fetchFn);
}

/**
* Generates a cURL command string for an HTTP request object.
* @param req Request payload { method, url, headers, body }
* @returns Formatted cURL command
*/
export function generateCurl(req?: RequestPayload): string {
return buildCurl(req);
}
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codebygarv/express-lens",
"version": "2.2.0",
"version": "2.3.0",
"type": "module",
"publishConfig": {
"access": "public"
Expand Down Expand Up @@ -76,6 +76,7 @@
"express": "^4.0.0 || ^5.0.0"
},
"devDependencies": {
"@types/node": "^26.1.2",
"tsup": "^8.5.1",
"tsx": "^4.23.1",
"typescript": "^6.0.3"
Expand Down
12 changes: 5 additions & 7 deletions src/dashboard.js → src/dashboard.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import store from './store.js';
import store from './store.ts';

/**
* Returns the embedded single-page HTML dashboard UI template.
* @returns {string} HTML document
* @returns HTML document
*/
export function getDashboardHTML() {
export function getDashboardHTML(): string {
return `<!DOCTYPE html>
<html lang="en">
<head>
Expand Down Expand Up @@ -213,7 +213,6 @@ export function getDashboardHTML() {
document.getElementById('valP99').innerText = metrics.percentiles.p99 || 0;
}

// Render routes
if (metrics.routes) {
const routesBody = document.getElementById('routesBody');
routesBody.innerHTML = '';
Expand All @@ -231,7 +230,6 @@ export function getDashboardHTML() {
}
}

// Render slow requests
if (metrics.slowRequests && metrics.slowRequests.length > 0) {
const slowBody = document.getElementById('slowBody');
slowBody.innerHTML = '';
Expand Down Expand Up @@ -307,10 +305,10 @@ export function getDashboardHTML() {

/**
* Express middleware route handler to serve the interactive web dashboard & SSE events stream.
* @returns {Function} Express request handler (req, res)
* @returns Express request handler (req, res, next)
*/
export function dashboardHandler() {
return function (req, res, next) {
return function (req: any, res: any, next: any): void {
const url = req.url || req.originalUrl || '';

// 1. SSE Events endpoint
Expand Down
Loading
Loading