UNPKG

kromemo

Version:

Browser event capture SDK for Kromemo: batching, retries, dedupe, TypeScript-first.

238 lines (174 loc) 5.6 kB
# Kromemo Browser SDK A lightweight, high-performance browser SDK for sending events to your Kromemo ingest endpoint. Built for reliability (batching + retries), graceful shutdown, and TypeScript-first DX. [![npm version](https://img.shields.io/npm/v/kromemo.svg?logo=npm)](https://www.npmjs.com/package/kromemo) [![npm downloads](https://img.shields.io/npm/dm/kromemo.svg?color=34D058&label=downloads)](https://www.npmjs.com/package/kromemo) [![Bundle size](https://img.shields.io/bundlephobia/minzip/kromemo?label=bundle%20size)](https://bundlephobia.com/package/kromemo) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-3178C6?logo=typescript&logoColor=white)](#) --- ## Features - **Zero Dependencies**: Small footprint for minimal impact on bundle size. - **Smart Batching**: Configurable byte-size limits and periodic flushing. - **Reliable Delivery**: Automatic retries with exponential backoff for transient failures. - **Graceful Shutdown**: Ensures pending events are sent when the user leaves the page using `sendBeacon` or `fetch` with `keepalive`. - **Type Safety**: First-class TypeScript support for a robust development experience. - **Data Sanitization**: Automatically handles circular references and truncates long strings. ### Why Kromemo? - ~4.4 kB min+gzip, zero dependencies (bundlephobia). - Tree-shakeable (`sideEffects: false`) with ESM/CJS/UMD builds. - Built for modern SPAs: dedupe window for React Strict Mode, byte/queue limits to protect the main thread, beacon fallback on unload. - Clean ingest contract: `POST /{projectId}/events` with `x-api-ingest-key` header. --- ## Installation ```bash npm install kromemo # or pnpm add kromemo # or yarn add kromemo ``` ### CDN (UMD) ```html <script src="https://unpkg.com/kromemo/dist/index.umd.js"></script> <script> window.kromemo.init({ projectId: 'pub_xxx', apiKey: 'kro_abcdef' }); </script> ``` --- ## Quick Start ```ts import kromemo from 'kromemo'; // Initialize the SDK kromemo.init({ projectId: 'pub_xxx', apiKey: 'kro_abcdef...', endpointBase: 'https://metrics.your-domain.com', // Optional }); // Track a page view kromemo.trackView({ name: 'Home', url: '/home' }); // Track a custom event kromemo.trackEvent({ name: 'clicked_buy', payload: { plan: 'pro', value: 99 }, }); // Track an error try { throw new Error('Something went wrong'); } catch (err) { kromemo.trackError({ error: err, payload: { context: 'checkout' } }); } ``` ### React / Next.js ```tsx import { useEffect } from 'react'; import kromemo from 'kromemo'; export default function AppLayout({ children }) { useEffect(() => { const { deviceId } = kromemo.init({ projectId: process.env.NEXT_PUBLIC_KROMEMO_PROJECT_ID!, apiKey: process.env.NEXT_PUBLIC_KROMEMO_API_KEY!, endpointBase: process.env.NEXT_PUBLIC_KROMEMO_ENDPOINT, // optional dedupeWindowMs: 1000, }); console.info('kromemo device', deviceId); kromemo.trackView(); }, []); return children; } ``` --- ## API Reference ### `init(options)` Initializes the SDK. Must be called before tracking any events. ```ts init(options: KromemoInitOptions): { deviceId: string } ``` #### Options | Option | Type | Default | Description | | :--- | :--- | :--- | :--- | | `projectId` | `string` | **Required** | Your project's public identifier. | | `apiKey` | `string` | **Required** | Public API key sent via `x-api-ingest-key`. | | `endpointBase` | `string` | | Base URL for the ingest endpoint. | | `maxBatchSize` | `number` | `100` | Maximum number of events per batch. | | `maxQueueBytes` | `number` | `500,000` | Maximum size of the memory queue in bytes. | | `flushIntervalMs` | `number` | `5000` | Interval in milliseconds to flush the queue. | | `retryMaxAttempts` | `number` | `3` | Maximum retry attempts for transient errors. | | `dedupeWindowMs` | `number` | `0` | Time window (ms) to drop duplicate events (same type/name/url). | --- ### `trackEvent(input)` Tracks a custom event. ```ts trackEvent(input: { name: string; payload?: Record<string, any>; ts?: number | string; }): void ``` ### `trackView(input)` Tracks a page view. ```ts trackView(input?: { name?: string; url?: string; payload?: Record<string, any>; }): void ``` ### `trackError(input)` Tracks an error. ```ts trackError(input: { error: Error | string; payload?: Record<string, any>; }): void ``` ### `flush()` Forces the queue to send all pending events immediately. ```ts flush(): Promise<void> ``` ### `shutdown()` Stops the queue and cleans up resources. ```ts shutdown(): void ``` --- ## Advanced Usage ### Deduplication To prevent duplicate events (e.g., from React Strict Mode double-invocations), you can enable client-side deduplication. ```ts kromemo.init({ projectId: '...', apiKey: '...', dedupeWindowMs: 1000, // Drop duplicates within 1 second }); ``` ### HTTP Contract Events are sent via `POST` to `{endpointBase}/{projectId}/events`. **Headers:** - `Content-Type: application/json` - `x-api-ingest-key: <your-public-api-key>` **Body:** ```json { "events": [ { "name": "event_name", "type": "event", "ts": 1730394050000, "device_id": "generated_uuid", "url": "https://...", "os": "macOS", "country": "US", "payload": { ... } } ] } ``` --- ## Projects Admin UI This repository includes a lightweight admin UI for managing projects. 1. Open `examples/projects/index.html` in your browser. 2. Configure your API endpoint and credentials. 3. Manage your projects directly. --- ## License MIT