@novahelm/analytics
v2026.6.1
Published
NovaHelm analytics — event tracking and aggregation.
Maintainers
Readme
@novahelm/analytics
Built-in analytics engine for NovaHelm — server-side event tracking, daily aggregation, funnel analysis, retention cohorts, session metrics, realtime visitor streams, and optional dual-write to PostHog, Plausible, or Amplitude.
Quick Start
pnpm add @novahelm/analyticsServer-Side Tracking
import { trackEvent, trackPageView, flushAnalytics } from "@novahelm/analytics";
// Track a custom event
trackEvent({
projectId: "proj_123",
event: "button_click",
properties: { buttonId: "cta-hero" },
userId: "u_456",
path: "/landing",
});
// Track a page view
trackPageView({
projectId: "proj_123",
path: "/blog/hello-world",
referrer: "https://google.com",
userId: "u_456",
});
// Events are buffered — flush before shutdown
await flushAnalytics();Client-Side Hook
import { useAnalytics } from "@novahelm/analytics/client";
function App() {
const { track } = useAnalytics(); // auto-tracks page views
return (
<button onClick={() => track("signup_click", { plan: "pro" })}>
Sign Up
</button>
);
}Aggregation and Time Series
Roll up raw events into daily summaries and query time series:
import { aggregateDaily, getTimeSeries, getDimensionBreakdown } from "@novahelm/analytics";
// Run daily aggregation (call from a cron job or BullMQ worker)
await aggregateDaily(db, projectId, new Date("2025-01-15"));
// Query time series data
const series = await getTimeSeries(db, {
projectId: "proj_123",
metric: "page_views",
dateRange: { start: "2025-01-01", end: "2025-01-31" },
granularity: "day",
});
// Break down by dimension (browser, country, device, etc.)
const breakdown = await getDimensionBreakdown(db, {
projectId: "proj_123",
metric: "page_views",
dimension: "country",
dateRange: { start: "2025-01-01", end: "2025-01-31" },
});Funnels
Analyze conversion through a sequence of events:
import { computeFunnel } from "@novahelm/analytics";
const funnel = await computeFunnel(db, {
projectId: "proj_123",
steps: [
{ event: "page_view", filter: { path: "/pricing" } },
{ event: "signup_click" },
{ event: "signup_complete" },
],
dateRange: { start: "2025-01-01", end: "2025-01-31" },
});
// funnel.steps[0].count, funnel.steps[1].conversionRate, ...Retention Cohorts
Measure user retention over time:
import { computeRetention } from "@novahelm/analytics";
const retention = await computeRetention(db, {
projectId: "proj_123",
cohortEvent: "signup_complete",
returnEvent: "page_view",
periods: 8, // weeks
dateRange: { start: "2025-01-01", end: "2025-03-01" },
});External Providers (Dual-Write)
Send events to external analytics alongside the built-in engine:
import { createAnalyticsProvider, PostHogProvider, PlausibleProvider } from "@novahelm/analytics";
const analytics = createAnalyticsProvider({
db,
externalProviders: [
new PostHogProvider({ apiKey: "phc_..." }),
new PlausibleProvider({ domain: "example.com" }),
],
});Table Partitioning
Automatic monthly partitioning for the events table:
import { ensurePartitions, pruneOldPartitions } from "@novahelm/analytics";
// Create partitions for the next 3 months
await ensurePartitions(db, { monthsAhead: 3 });
// Drop partitions older than 12 months
await pruneOldPartitions(db, { retentionMonths: 12 });API Reference
| Export | Description |
|--------|-------------|
| trackEvent(opts) | Track a custom event (buffered) |
| trackPageView(opts) | Track a page view (buffered) |
| flushAnalytics() | Flush the event buffer to Postgres |
| createAnalyticsProvider(config) | Create provider with optional dual-write |
| aggregateDaily(db, projectId, date) | Roll up raw events into daily summaries |
| getTimeSeries(db, opts) | Query time series metrics |
| getDimensionBreakdown(db, opts) | Break down metrics by dimension |
| getRealtimeVisitors(db, projectId) | Count currently active visitors |
| computeFunnel(db, opts) | Compute funnel conversion rates |
| computeRetention(db, opts) | Compute retention cohort matrix |
| getSessionMetrics(db, opts) | Aggregate session statistics |
| getSessionDetails(db, opts) | List individual session details |
| getRealtimeEvents(db, opts) | Stream live events |
| createAnalyticsHandler(config) | Create a Next.js API route handler |
| createPerfReportHandler(config) | Create a Web Vitals report handler |
| ensurePartitions(db, opts) | Create monthly table partitions |
| pruneOldPartitions(db, opts) | Drop old partitions |
| useAnalytics(opts) | React hook for client-side tracking (from /client) |
