From 45e71ff9449672bba6e90b96bf0411bdb0a79f66 Mon Sep 17 00:00:00 2001 From: CahidArda Date: Mon, 25 May 2026 13:38:10 +0300 Subject: [PATCH] Remove dead search config flags and add README Remove search.autoUpdate and search.rebuildOnStartup from AnalyticsConfig; both were set but never read. Add a repo README documenting setup and usage. --- README.md | 200 ++++++++++++++++++++++++++++- packages/app/lib/config.ts | 2 - packages/sdk/src/backend-client.ts | 2 - packages/sdk/src/types.ts | 2 - 4 files changed, 199 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5173136..79aecdf 100644 --- a/README.md +++ b/README.md @@ -1 +1,199 @@ -# redis-analytics \ No newline at end of file +# redis-analytics + +A lightweight, typed analytics SDK backed by [Upstash Redis](https://upstash.com/). +Capture pageviews, clicks, and custom events; manage sessions; resolve feature +flags server-side; and query everything through Redis Search. + +It's designed for serverless / edge runtimes (Next.js App Router, etc.): a single +HTTP endpoint on the backend, a typed client on the frontend, and an optional React +hook. + +> **Status:** early (`0.x`). APIs may change. + +## Packages + +This is a pnpm + Turborepo monorepo. + +| Package | Description | +| -------------- | ---------------------------------------------- | +| `packages/sdk` | The published SDK — `@upstash/redis-analytics` | +| `packages/app` | Example Next.js app wiring the SDK end-to-end | +| `packages/ui` | Dashboard UI for exploring captured analytics | + +## Installation + +```bash +npm install @upstash/redis-analytics @upstash/redis +``` + +## Concepts + +- **Session** — created on the backend, identified by a `sessionId`. Carries the + resolved feature flags and optional server-set metadata. Sessions expire after + `session.expirationMs`. +- **Event** — a named occurrence tied to a session. Standard events (`pageview`, + `click`, `error`, `warning`, `info`) are built in; custom events are fully typed. +- **Feature flag** — resolved server-side (typically in middleware) and frozen onto + the session at creation time. +- **Schema registry** — infers property types from captured events and powers the + Redis Search index. +- **Single endpoint** — the frontend client and backend talk over one route + (`/api/analytics` by default) using a typed request/response protocol. + +## Quick start (Next.js App Router) + +### 1. Configure the backend client + +```ts +// lib/analytics.ts +import { AnalyticsBackendClient } from "@upstash/redis-analytics"; + +export const analytics = new AnalyticsBackendClient({ + redis: { + url: process.env.UPSTASH_REDIS_REST_URL!, + token: process.env.UPSTASH_REDIS_REST_TOKEN!, + }, + // optional + config: { + session: { expirationMs: 3_600_000 }, // 1 hour + featureFlags: { + theme: { + possibleValues: ["light", "dark"], + defaultValue: "light", + }, + }, + events: { customEventRetentionDays: 7, maxBatchSize: 20 }, + schemaValidation: { checkFrequency: 1 }, + logging: { + retentionDays: 30, + enabledTypes: ["schema_update", "feature_flag_update", "index_update"], + }, + search: { indexName: "events-idx" }, + }, +}); +``` + +### 2. Expose the single endpoint + +```ts +// app/api/analytics/route.ts +import { analytics } from "@/lib/analytics"; + +const handler = analytics.getHandler({ + // Middleware runs before every request. Resolve feature flags here. + middleware: ({ analyticsRequest }) => { + if (analyticsRequest.requestType !== "createSession") return; + + return { + featureFlags: { theme: Math.random() < 0.5 ? "light" : "dark" }, + // sessionMetadata: { ... } // attach server-side metadata if needed + }; + }, +}); + +export const POST = handler; +export const GET = handler; +``` + +Middleware can also return a `Response` to short-circuit (e.g. `401`), and you can +pass an array of middlewares that run in order. + +### 3. Use the React hook on the frontend + +```ts +// lib/use-analytics.ts +import { createAnalyticsHook } from "@upstash/redis-analytics/react"; + +type Events = { + "custom:purchase": { productId: string; amount: number; currency: string }; +}; +type Flags = { theme: "light" | "dark" }; + +export const useAnalytics = createAnalyticsHook({ + endpoint: "/api/analytics", + flushInterval: 2000, // debounce + batch event sends +}); +``` + +```tsx +"use client"; +import { useAnalytics } from "@/lib/use-analytics"; + +export function BuyButton() { + const { captureEvent, featureFlags, sessionId } = useAnalytics(); + + return ( + + ); +} +``` + +The hook auto-creates a session, auto-captures a `pageview` on path change, and +exposes the resolved feature flags. No provider needed — call `createAnalyticsHook` +once at module level. + +### Using the client directly (no React) + +```ts +import { AnalyticsClient } from "@upstash/redis-analytics"; + +const client = new AnalyticsClient({ endpoint: "/api/analytics" }); + +const session = await client.createSession(); +await client.capturePageView(session.id, "/products"); +const theme = await client.getFeatureFlag(session.id, "theme"); +``` + +## Configuration reference + +`AnalyticsConfig` passed to `AnalyticsBackendClient` (config is optional; defaults +shown): + +| Field | Default | Description | +| --------------------------------- | ------------ | -------------------------------------------------------- | +| `session.expirationMs` | `3_600_000` | Session TTL in ms. | +| `featureFlags` | `{}` | Flag definitions (`possibleValues`, `defaultValue`). | +| `events.customEventRetentionDays` | `7` | Retention window for custom events. | +| `events.maxBatchSize` | `20` | Max events per batch request. | +| `schemaValidation.checkFrequency` | `1` | Probability (0–1) of running schema inference per event. | +| `logging.retentionDays` | `30` | System-log retention. | +| `logging.enabledTypes` | see source | Which `LogType`s to persist. | +| `search.indexName` | `events-idx` | Redis Search index name. | + +`ClientConfig` passed to `AnalyticsClient` / `createAnalyticsHook`: + +| Field | Default | Description | +| --------------- | ---------------- | ------------------------------------------------------ | +| `endpoint` | `/api/analytics` | Backend endpoint URL. | +| `flushInterval` | `0` | Debounce window (ms) for batching captures. `0` = off. | +| `maxBatchSize` | `20` | Max events per batch request from the client. | + +## Development + +```bash +pnpm install +pnpm dev # turbo dev across packages +pnpm build # turbo build +pnpm lint # turbo lint +``` + +The example app and dashboard need Upstash Redis credentials: + +```bash +UPSTASH_REDIS_REST_URL=... +UPSTASH_REDIS_REST_TOKEN=... +``` + +## License + +See [LICENSE](./LICENSE). diff --git a/packages/app/lib/config.ts b/packages/app/lib/config.ts index 31b0abd..8880d06 100644 --- a/packages/app/lib/config.ts +++ b/packages/app/lib/config.ts @@ -35,8 +35,6 @@ export const CONFIG: AnalyticsConfig = { }, search: { indexName: "events-idx", - autoUpdate: true, - rebuildOnStartup: false, }, }; diff --git a/packages/sdk/src/backend-client.ts b/packages/sdk/src/backend-client.ts index d477745..56cbd4c 100644 --- a/packages/sdk/src/backend-client.ts +++ b/packages/sdk/src/backend-client.ts @@ -44,8 +44,6 @@ const DEFAULT_CONFIG: AnalyticsConfig = { }, search: { indexName: "events-idx", - autoUpdate: true, - rebuildOnStartup: false, }, }; diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 1955e1e..0c7982b 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -162,8 +162,6 @@ export type AnalyticsConfig = { }; search: { indexName: string; - autoUpdate: boolean; - rebuildOnStartup: boolean; }; };