UNPKG

@jam.dev/recording-links

Version:

Capture bug reports from your users with the Jam recording links SDK

189 lines (137 loc) 5.85 kB
# @jam.dev/recording-links A TypeScript SDK for loading & initializing Jam Recording Links scripts across browser tabs and windows. [![npm version](https://badge.fury.io/js/%40jam.dev%2Frecording-links.svg)](https://www.npmjs.com/package/@jam.dev/recording-links) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) [![Bundle Size](https://img.shields.io/bundlephobia/min/%40jam.dev/recording-links?style=flat-square&label=bundle%20size)](https://bundlephobia.com/package/@jam.dev/recording-links) [![Gzipped Size](https://img.shields.io/bundlephobia/minzip/%40jam.dev/recording-links?style=flat-square&label=gzipped)](https://bundlephobia.com/package/@jam.dev/recording-links) ## Overview This SDK provides a lightweight interface for coordinating Jam recording sessions across multiple browser contexts. It handles dynamic script loading, cross-tab state synchronization, and recording lifecycle management. ## Benefits - ⚡ **Dynamic script loading:** uses dynamic imports for just-in-time script loading - 🚀 **Auto-initialization:** uses URL state and cross-tab reference counting to auto-load when necessary - 🌐 **Cross-browser support:** supports all modern ES2020+ browsers - 🔧 **Bundler compatibility:** pre-declares dynamic imports as external for popular bundlers - 📡 **Event system:** subscribe to SDK events like script loading - 📦 **TypeScript support:** full type definitions included ## Installation ```bash npm install @jam.dev/recording-links ``` ## Usage ### Basic Setup ```typescript import * as jam from "@jam.dev/recording-links/sdk"; // Initialize the SDK jam.initialize(); // Load the recorder when needed const Recorder = await jam.loadRecorder(); Recorder.open("recording-id"); ``` ### Auto-loading from URL The SDK automatically detects `jam-recording` and `jam-title` URL parameters and loads the recorder: ```typescript // On a page with URL: https://example.com?jam-recording=abc123&jam-title=My%20Recording jam.initialize(); // Automatically loads recorder and opens recording "abc123" ``` ### Custom Configuration ```typescript jam.initialize({ teamId: "team-123,team-456", // Manually provide team ID(s); default: reads `<meta name="jam:team">` from the page openImmediately: false, // Don't auto-open recorder from URL params // OR: "recording-123" to auto-open a recording by ID parseJamData: (href) => { // Custom logic to extract recording data from URL const url = new URL(href); return { recordingId: url.searchParams.get("jam-recording"), jamTitle: url.searchParams.get("jam-title") }; }, applyJamData: (data) => { // Custom logic to apply recording data to URL const url = new URL(window.location.href); url.searchParams.set("jam-recording", data.recordingId); url.searchParams.set("jam-title", data.jamTitle); return url.href; } }); ``` ### Event Listeners ```typescript // Listen for SDK events jam.addEventListener("loaded", (event) => { console.log(`Script loaded: ${event.detail.name}`); // "capture" or "recorder" }); ``` ## API Reference ### `initialize(options?)` Initializes the SDK with optional configuration. **Parameters:** - `options.teamId?: string` - Team ID for recording validation - `options.openImmediately?: boolean | string` - Whether to auto-open from URL (default: `true`), or a recording ID string to open immediately - `options.parseJamData?: (input: string) => SerializableJamData | null` - Custom URL parser - `options.applyJamData?: (data: SerializableJamData) => string` - Custom URL applier - `options.recorderRefCounter?: RefCounter` - Custom reference counter (advanced) **Throws:** - Error if SDK is already initialized ### `loadRecorder(options?)` Loads the Jam recorder module and returns a promise that resolves to the recorder interface. **Parameters:** - `Omit<InitializeOptions, "recorderRefCounter">` **Returns:** - `Promise<RecorderSingleton>` - The Recorder singleton **Throws:** - Error if SDK is not initialized ### `isInitialized()` Returns whether the SDK has been initialized. **Returns:** - `boolean` - True if the SDK has been initialized, false otherwise ### `addEventListener(type, listener, options?)` Add an event listener for SDK events. **Parameters:** - `type: "loaded"` - Event type - `listener: (event: CustomEvent) => void` - Event handler - `options?: AddEventListenerOptions` - Standard event listener options ### `removeEventListener(type, listener, options?)` Remove an event listener for SDK events. ### `Recorder` The loaded recorder singleton (null until `loadRecorder()` is called). **Methods:** - `open(recordingId, params?)` - Open recorder for specific recording - `recordingId: string` - The recording ID to open - `params.jamTitle?: string` - Optional title for the recording - `params.removeOnEscape?: boolean` - Whether to close recorder on Escape (default: true) ## Types The SDK exports several TypeScript types: ### `ScriptName` ```typescript type ScriptName = "capture" | "recorder"; ``` ### `SerializableJamData` ```typescript type SerializableJamData = { recordingId: string | null; jamTitle: string | null; }; ``` ### `InitializeOptions` ```typescript type InitializeOptions = { teamId?: string; openImmediately?: boolean | string | undefined | null; parseJamData?(input: string): SerializableJamData | null; applyJamData?(data: SerializableJamData): string; recorderRefCounter?: RefCounter; }; ``` ### `RecorderSingleton` ```typescript type RecorderSingleton = { open(recordingId: string, params?: { jamTitle?: string | null; removeOnEscape?: boolean; }): unknown; }; ``` ## Contributing See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, build commands, and release process.