UNPKG

userplex

Version:

Simple analytics SDK for Userplex - Track events, identify users, and log conversations

1 lines 8.85 kB
{"version":3,"sources":["../index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Userplex - Simple Analytics SDK\n * \n * Just install and use. No complex setup required.\n * \n * @example\n * ```ts\n * import Userplex from 'userplex';\n * \n * const userplex = new Userplex('upx_your_api_key');\n * \n * // Track events\n * await userplex.track('user123', 'button_clicked', { button: 'signup' });\n * \n * // Identify users\n * await userplex.identify('user123', { email: 'user@example.com' });\n * \n * // Log conversations\n * await userplex.logConversation({\n * messages: [\n * { role: 'user', content: 'Hello' },\n * { role: 'assistant', content: 'Hi there!' }\n * ]\n * });\n * ```\n */\n\nexport interface ConversationMessage {\n role: 'user' | 'assistant' | 'system';\n content: string;\n}\n\nexport interface UserplexOptions {\n /** Your Userplex instance URL (default: https://userplex.vercel.app) */\n baseUrl?: string;\n /** Request timeout in ms (default: 10000) */\n timeout?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport class UserplexError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public response?: any\n ) {\n super(message);\n this.name = 'UserplexError';\n }\n}\n\nclass Userplex {\n private apiKey: string;\n private baseUrl: string;\n private timeout: number;\n private debug: boolean;\n\n constructor(apiKey: string, options: UserplexOptions = {}) {\n if (!apiKey) {\n throw new Error('Userplex: API key is required');\n }\n if (!apiKey.startsWith('upx_')) {\n throw new Error('Userplex: API key must start with \"upx_\"');\n }\n\n this.apiKey = apiKey;\n this.baseUrl = (options.baseUrl || 'https://userplex.vercel.app').replace(/\\/$/, '');\n this.timeout = options.timeout || 10000;\n this.debug = options.debug || false;\n }\n\n /**\n * Track an event\n */\n async track(userId: string, event: string, properties?: Record<string, any>) {\n if (!userId || !event) {\n throw new Error('userId and event are required');\n }\n\n return this.request('/api/events', {\n userId,\n event,\n properties: properties || {}\n });\n }\n\n /**\n * Identify a user\n */\n async identify(externalId: string, properties?: Record<string, any>) {\n if (!externalId) {\n throw new Error('externalId is required');\n }\n\n return this.request('/api/identify', {\n externalId,\n ...properties\n }, {\n 'x-api-key': this.apiKey // identify endpoint uses this header too\n });\n }\n\n /**\n * Log a conversation\n */\n async logConversation(options: {\n messages: ConversationMessage[];\n userId?: string;\n conversationId?: string;\n conversationName?: string;\n }) {\n if (!options.messages || options.messages.length === 0) {\n throw new Error('messages array is required and cannot be empty');\n }\n\n return this.request('/api/conversations', {\n externalUserId: options.userId,\n conversationId: options.conversationId,\n conversationName: options.conversationName,\n messages: options.messages\n });\n }\n\n /**\n * Batch track multiple events\n */\n async trackBatch(events: Array<{\n userId: string;\n event: string;\n properties?: Record<string, any>;\n }>) {\n if (!events || events.length === 0) {\n throw new Error('events array is required and cannot be empty');\n }\n\n const promises = events.map(e => this.track(e.userId, e.event, e.properties));\n return Promise.all(promises);\n }\n\n private async request(endpoint: string, data: any, additionalHeaders?: Record<string, string>) {\n const url = `${this.baseUrl}${endpoint}`;\n \n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n if (this.debug) {\n console.log(`[Userplex] POST ${url}`, JSON.stringify(data, null, 2));\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n ...additionalHeaders\n },\n body: JSON.stringify(data),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n const responseData = await response.json() as any;\n\n if (this.debug) {\n console.log(`[Userplex] Response:`, JSON.stringify(responseData, null, 2));\n }\n\n if (!response.ok) {\n throw new UserplexError(\n responseData.error || `Request failed with status ${response.status}`,\n response.status,\n responseData\n );\n }\n\n return responseData;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new UserplexError('Request timeout', 408);\n }\n\n if (error instanceof UserplexError) {\n throw error;\n }\n\n throw new UserplexError(\n error.message || 'An unexpected error occurred',\n undefined,\n error\n );\n }\n }\n}\n\nexport default Userplex;\n\n// For environments that need it separate\nexport { Userplex };\n"]}