@sessionlens/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # SessionLens SDK
2
+
3
+ A lightweight TypeScript SDK for analytics and user tracking.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @sessionlens/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### Basic Usage
14
+
15
+ ```javascript
16
+ import sessionLens from '@sessionlens/sdk';
17
+
18
+ // Initialize the SDK with your credentials
19
+ await sessionLens.sessionLensInit({
20
+ sdk_key: 'your-sdk-key-here',
21
+ user_id: 'user123',
22
+ org_id: 'org456',
23
+ debug: true // Optional: enable debug logging
24
+ });
25
+
26
+ // Track events
27
+ sessionLens.sessionLensTrack({
28
+ event_name: 'button_click',
29
+ properties: {
30
+ button_id: 'signup',
31
+ page: 'landing'
32
+ }
33
+ });
34
+
35
+ // Identify users
36
+ sessionLens.sessionLensIdentify({
37
+ user_id: 'user123',
38
+ properties: {
39
+ email: 'user@example.com',
40
+ plan: 'premium'
41
+ }
42
+ });
43
+
44
+ // Reset tracking (e.g., on logout)
45
+ sessionLens.sessionLensReset();
46
+ ```
47
+
48
+ ### React Integration
49
+
50
+ ```jsx
51
+ import React from 'react';
52
+ import { useSessionLens, useSessionLensTrack, useSessionLensIdentify } from '@sessionlens/sdk';
53
+
54
+ function App() {
55
+ // Initialize SDK
56
+ useSessionLens({
57
+ sdk_key: 'your-sdk-key-here',
58
+ user_id: 'user123',
59
+ org_id: 'org456',
60
+ debug: true
61
+ });
62
+
63
+ const track = useSessionLensTrack();
64
+ const identify = useSessionLensIdentify();
65
+
66
+ const handleClick = () => {
67
+ track({
68
+ event_name: 'button_click',
69
+ properties: { button: 'header_cta' }
70
+ });
71
+ };
72
+
73
+ const handleLogin = () => {
74
+ identify({
75
+ user_id: 'user123',
76
+ properties: { email: 'user@example.com' }
77
+ });
78
+ };
79
+
80
+ return (
81
+ <div>
82
+ <button onClick={handleClick}>Track Event</button>
83
+ <button onClick={handleLogin}>Identify User</button>
84
+ </div>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ## Configuration
90
+
91
+ ### Environment Variables
92
+
93
+ The SDK supports configuration through environment variables:
94
+
95
+ #### API Base URL
96
+
97
+ Configure the API base URL for different environments:
98
+
99
+ ```bash
100
+ # For Node.js applications
101
+ SESSIONLENS_API_BASE_URL=https://api.sessionlens.com/v1
102
+
103
+ # For React applications (Create React App)
104
+ REACT_APP_SESSIONLENS_API_BASE_URL=https://api.sessionlens.com/v1
105
+
106
+ # For development/staging environments
107
+ SESSIONLENS_API_BASE_URL=https://staging-api.sessionlens.com/v1
108
+ REACT_APP_SESSIONLENS_API_BASE_URL=https://staging-api.sessionlens.com/v1
109
+ ```
110
+
111
+ **Default:** `https://api.sessionlens.com/v1`
112
+
113
+ ### Environment Setup Examples
114
+
115
+ #### Development (.env.development)
116
+ ```bash
117
+ REACT_APP_SESSIONLENS_API_BASE_URL=https://dev-api.sessionlens.com/v1
118
+ REACT_APP_SESSIONLENS_SDK_KEY=sk_dev_your_development_key
119
+ ```
120
+
121
+ #### Staging (.env.staging)
122
+ ```bash
123
+ REACT_APP_SESSIONLENS_API_BASE_URL=https://staging-api.sessionlens.com/v1
124
+ REACT_APP_SESSIONLENS_SDK_KEY=sk_staging_your_staging_key
125
+ ```
126
+
127
+ #### Production (.env.production)
128
+ ```bash
129
+ REACT_APP_SESSIONLENS_API_BASE_URL=https://api.sessionlens.com/v1
130
+ REACT_APP_SESSIONLENS_SDK_KEY=sk_live_your_production_key
131
+ ```
132
+
133
+ ## API Reference
134
+
135
+ ### Configuration
136
+
137
+ The SDK requires initialization with your credentials:
138
+
139
+ ```typescript
140
+ interface SessionLensConfig {
141
+ sdk_key: string; // Your SessionLens SDK key
142
+ user_id: string; // Unique identifier for the user
143
+ org_id: string; // Your organization ID
144
+ debug?: boolean; // Optional: enable debug logging
145
+ }
146
+ ```
147
+
148
+ ### Methods
149
+
150
+ #### `sessionLensInit(config: SessionLensConfig): Promise<void>`
151
+
152
+ Initialize the SDK with your configuration. This method validates your credentials with the SessionLens backend using a RESTful GET request.
153
+
154
+ **API Call:** `GET /validate?org_id={org_id}&user_id={user_id}` with `Authorization: Bearer {sdk_key}` header
155
+
156
+ **Error Handling:**
157
+ - `401`: Invalid SDK key
158
+ - `403`: Access denied - check organization permissions
159
+ - `404`: Organization not found
160
+ - `429`: Rate limit exceeded
161
+ - Network errors: SDK runs in offline mode
162
+
163
+ #### `sessionLensTrack(event: SessionLensEvent): void`
164
+
165
+ Track custom events.
166
+
167
+ ```typescript
168
+ interface SessionLensEvent {
169
+ event_name: string;
170
+ properties?: Record<string, any>;
171
+ timestamp?: number; // Optional: will be auto-generated if not provided
172
+ }
173
+ ```
174
+
175
+ #### `sessionLensIdentify(user: SessionLensUser): void`
176
+
177
+ Identify and update user properties.
178
+
179
+ ```typescript
180
+ interface SessionLensUser {
181
+ user_id: string;
182
+ properties?: Record<string, any>;
183
+ }
184
+ ```
185
+
186
+ #### `sessionLensReset(): void`
187
+
188
+ Reset tracking state. Useful when users log out.
189
+
190
+ ## API Design
191
+
192
+ The SDK follows RESTful principles:
193
+
194
+ - **GET /validate**: Validates SDK key and organization/user access (idempotent)
195
+ - **POST /events**: Creates new tracking events
196
+ - **POST /identify**: Creates/updates user identification
197
+ - **POST /reset**: Resets user tracking state
198
+
199
+ This design ensures:
200
+ - Proper HTTP semantics (GET for reads, POST for writes)
201
+ - Better caching behavior for validation requests
202
+ - Cleaner server logs (sensitive data in headers, not URLs)
203
+
204
+ ## Security
205
+
206
+ The SDK key is used for:
207
+ - Backend validation during initialization
208
+ - Authentication for all API requests
209
+ - Secure event transmission
210
+
211
+ **Best Practices:**
212
+ - Store SDK keys securely (environment variables, secure storage)
213
+ - Use different SDK keys for different environments
214
+ - Rotate SDK keys regularly
215
+ - Never expose SDK keys in client-side code for production
216
+ - Use environment-specific API base URLs for development/staging
217
+
218
+ ## Error Handling
219
+
220
+ The SDK includes comprehensive error handling:
221
+
222
+ ```javascript
223
+ try {
224
+ await sessionLens.sessionLensInit({
225
+ sdk_key: 'your-sdk-key',
226
+ user_id: 'user123',
227
+ org_id: 'org456'
228
+ });
229
+ console.log('SDK initialized successfully');
230
+ } catch (error) {
231
+ console.error('Initialization failed:', error.message);
232
+ // Handle specific errors:
233
+ // - Invalid SDK key
234
+ // - Network issues
235
+ // - Organization access issues
236
+ }
237
+ ```
238
+
239
+ ## Examples
240
+
241
+ Check the `/examples` directory for complete implementation examples:
242
+ - Basic JavaScript usage
243
+ - React integration
244
+ - Error handling patterns
245
+ - Offline mode handling
246
+ - Environment configuration
247
+
248
+ ## Development
249
+
250
+ ```bash
251
+ # Install dependencies
252
+ npm install
253
+
254
+ # Build the project
255
+ npm run build
256
+
257
+ # Run tests
258
+ npm test
259
+
260
+ # Run linting
261
+ npm run lint
262
+ ```
263
+
264
+ ## License
265
+
266
+ MIT
@@ -0,0 +1,21 @@
1
+ export interface SessionLensConfig {
2
+ sdk_key: string;
3
+ user_id: string;
4
+ org_id: string;
5
+ project_id?: string;
6
+ debug?: boolean;
7
+ }
8
+ interface SessionInfo {
9
+ session_id: string;
10
+ client_id: string;
11
+ org_id: string;
12
+ project_id: string;
13
+ user_id: string;
14
+ started_at: number;
15
+ last_activity: number;
16
+ }
17
+ export declare function sessionLensInit(config: SessionLensConfig): Promise<void>;
18
+ export declare function sessionLensGetConfig(): SessionLensConfig;
19
+ export declare function getSessionInfo(): SessionInfo;
20
+ export declare function getSessionLensApiBaseUrl(): string;
21
+ export {};
@@ -0,0 +1,4 @@
1
+ import { SessionLensEvent, SessionLensUser } from '../types';
2
+ export declare function sessionLensTrack(event: SessionLensEvent): void;
3
+ export declare function sessionLensIdentify(user: SessionLensUser): void;
4
+ export declare function sessionLensReset(): void;
@@ -0,0 +1,13 @@
1
+ import { SessionLensConfig } from './core/config';
2
+ import { SessionLensEvent, SessionLensUser, SessionLensInstance } from './types';
3
+ export * from './types';
4
+ export { SessionLensConfig } from './core/config';
5
+ export * from './integrations/react';
6
+ declare class SessionLens implements SessionLensInstance {
7
+ sessionLensInit(config: SessionLensConfig): Promise<void>;
8
+ sessionLensTrack(event: SessionLensEvent): void;
9
+ sessionLensIdentify(user: SessionLensUser): void;
10
+ sessionLensReset(): void;
11
+ }
12
+ declare const sessionLens: SessionLens;
13
+ export default sessionLens;
@@ -0,0 +1,384 @@
1
+ import { useEffect } from 'react';
2
+
3
+ // Session timeout (30 minutes of inactivity)
4
+ const SESSION_TIMEOUT = 30 * 60 * 1000;
5
+ // Store the config and session info
6
+ let currentConfig = null;
7
+ let currentSession = null;
8
+ // Extract project ID from SDK key pattern: sdk_prod_0000_684f15_5e0e72ac_35d2
9
+ const extractProjectFromSDKKey = (sdk_key) => {
10
+ const parts = sdk_key.split('_');
11
+ return parts.length >= 4 ? `proj_${parts[3]}` : 'default';
12
+ };
13
+ // Generate crypto-grade unique IDs with hierarchical structure
14
+ const generateUniqueId = (config, prefix) => {
15
+ const timestamp = Date.now();
16
+ const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);
17
+ // Use crypto.randomUUID() for true uniqueness, fallback to secure random
18
+ const uuid = (() => {
19
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
20
+ return crypto.randomUUID().replace(/-/g, '').substring(0, 12);
21
+ }
22
+ // Fallback: combine multiple random values for better entropy
23
+ const random1 = Math.random().toString(36).substring(2, 15);
24
+ const random2 = Math.random().toString(36).substring(2, 15);
25
+ return (random1 + random2).substring(0, 12);
26
+ })();
27
+ // Format: {org_id}_{project_id}_{prefix}_{timestamp}_{uuid}
28
+ return `${config.org_id}_${project_id}_${prefix}_${timestamp}_${uuid}`;
29
+ };
30
+ // Get or create persistent client ID (per project)
31
+ const getOrCreateClientId = (config) => {
32
+ const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);
33
+ const storageKey = `sessionlens_client_${config.org_id}_${project_id}`;
34
+ if (typeof window !== 'undefined' && window.localStorage) {
35
+ try {
36
+ let clientId = localStorage.getItem(storageKey);
37
+ if (!clientId) {
38
+ clientId = generateUniqueId(config, 'client');
39
+ localStorage.setItem(storageKey, clientId);
40
+ }
41
+ return clientId;
42
+ }
43
+ catch (error) {
44
+ // localStorage might be disabled, fallback to session-only ID
45
+ return generateUniqueId(config, 'client');
46
+ }
47
+ }
48
+ // Fallback for non-browser environments
49
+ return generateUniqueId(config, 'client');
50
+ };
51
+ // Start new session with collision-proof IDs
52
+ const startNewSession = (config) => {
53
+ const now = Date.now();
54
+ const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);
55
+ currentSession = {
56
+ session_id: generateUniqueId(config, 'sess'),
57
+ client_id: getOrCreateClientId(config),
58
+ org_id: config.org_id,
59
+ project_id: project_id,
60
+ user_id: config.user_id,
61
+ started_at: now,
62
+ last_activity: now
63
+ };
64
+ if (config.debug) {
65
+ console.log('SessionLens: New session started', {
66
+ session_id: currentSession.session_id,
67
+ client_id: currentSession.client_id,
68
+ project_id: currentSession.project_id
69
+ });
70
+ }
71
+ };
72
+ // Check if session is expired
73
+ const isSessionExpired = () => {
74
+ if (!currentSession)
75
+ return true;
76
+ return Date.now() - currentSession.last_activity > SESSION_TIMEOUT;
77
+ };
78
+ // Update session activity timestamp
79
+ const updateSessionActivity = () => {
80
+ if (currentSession) {
81
+ currentSession.last_activity = Date.now();
82
+ }
83
+ };
84
+ // Get API base URL from environment variable or use default
85
+ const getApiBaseUrl = () => {
86
+ // Check for environment variable (works in Node.js and bundlers like Webpack/Vite)
87
+ if (typeof process !== 'undefined' && process.env) {
88
+ return process.env.SESSIONLENS_API_BASE_URL || process.env.REACT_APP_SESSIONLENS_API_BASE_URL || 'https://api.sessionlens.com/v1';
89
+ }
90
+ // Fallback for browser environments without build-time env vars
91
+ return 'https://api.sessionlens.com/v1';
92
+ };
93
+ // `sessionLensInit()` sets the config and validates with backend
94
+ async function sessionLensInit(config) {
95
+ // Validate required fields
96
+ if (!config.sdk_key) {
97
+ throw new Error('[SessionLens] sdk_key is required');
98
+ }
99
+ if (!config.user_id) {
100
+ throw new Error('[SessionLens] user_id is required');
101
+ }
102
+ if (!config.org_id) {
103
+ throw new Error('[SessionLens] org_id is required');
104
+ }
105
+ // Store the configuration
106
+ currentConfig = config;
107
+ // Start new session with scalable ID generation
108
+ startNewSession(config);
109
+ // Validate configuration with backend using GET (more RESTful)
110
+ const apiBaseUrl = getApiBaseUrl();
111
+ try {
112
+ // Use GET with query parameters for org_id and user_id validation
113
+ const validationUrl = new URL(`${apiBaseUrl}/org/validate`);
114
+ validationUrl.searchParams.set('org_id', config.org_id);
115
+ validationUrl.searchParams.set('user_id', config.user_id);
116
+ const response = await fetch(validationUrl.toString(), {
117
+ method: 'GET',
118
+ headers: {
119
+ 'Authorization': `Bearer ${config.sdk_key}`
120
+ }
121
+ });
122
+ if (!response.ok) {
123
+ switch (response.status) {
124
+ case 401:
125
+ throw new Error('Invalid SDK key. Please check your credentials.');
126
+ case 403:
127
+ throw new Error('Access denied. Please verify your organization permissions.');
128
+ case 404:
129
+ throw new Error('Organization not found. Please check your org_id.');
130
+ case 429:
131
+ throw new Error('Rate limit exceeded. Please try again later.');
132
+ default:
133
+ throw new Error(`Validation failed with status ${response.status}`);
134
+ }
135
+ }
136
+ const result = await response.json();
137
+ if (config.debug) {
138
+ console.log('SessionLens SDK initialized successfully:', result);
139
+ console.log('Using API base URL:', apiBaseUrl);
140
+ console.log('Validation endpoint:', validationUrl.toString());
141
+ console.log('Session Info:', currentSession);
142
+ }
143
+ }
144
+ catch (error) {
145
+ if (error instanceof TypeError && error.message.includes('fetch')) {
146
+ // Network error - allow offline mode
147
+ if (config.debug) {
148
+ console.warn('SessionLens SDK: Running in offline mode due to network error');
149
+ }
150
+ return;
151
+ }
152
+ // Re-throw validation errors
153
+ throw error;
154
+ }
155
+ }
156
+ // `sessionLensGetConfig()` returns it later (for use in tracker, etc)
157
+ function sessionLensGetConfig() {
158
+ if (!currentConfig) {
159
+ throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');
160
+ }
161
+ return currentConfig;
162
+ }
163
+ // Get current session info with auto-renewal and activity tracking
164
+ function getSessionInfo() {
165
+ if (!currentConfig) {
166
+ throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');
167
+ }
168
+ // Check if session expired or doesn't exist
169
+ if (!currentSession || isSessionExpired()) {
170
+ startNewSession(currentConfig);
171
+ }
172
+ else {
173
+ // Update activity timestamp
174
+ updateSessionActivity();
175
+ }
176
+ return currentSession;
177
+ }
178
+ // Export function to get API base URL for use in other modules
179
+ function getSessionLensApiBaseUrl() {
180
+ return getApiBaseUrl();
181
+ }
182
+
183
+ function sessionLensTrack(event) {
184
+ const config = sessionLensGetConfig();
185
+ const sessionInfo = getSessionInfo(); // Get current session with activity update
186
+ // Add timestamp if not provided
187
+ const eventWithTimestamp = {
188
+ ...event,
189
+ timestamp: event.timestamp || Date.now()
190
+ };
191
+ if (config.debug) {
192
+ console.log('SessionLens Track:', eventWithTimestamp);
193
+ console.log('Session Context:', {
194
+ session_id: sessionInfo.session_id,
195
+ client_id: sessionInfo.client_id,
196
+ project_id: sessionInfo.project_id
197
+ });
198
+ }
199
+ // Send event to backend with session context
200
+ sendEventToBackend(eventWithTimestamp, config, sessionInfo);
201
+ }
202
+ function sessionLensIdentify(user) {
203
+ const config = sessionLensGetConfig();
204
+ const sessionInfo = getSessionInfo(); // Get current session with activity update
205
+ if (config.debug) {
206
+ console.log('SessionLens Identify:', user);
207
+ console.log('Session Context:', {
208
+ session_id: sessionInfo.session_id,
209
+ client_id: sessionInfo.client_id,
210
+ project_id: sessionInfo.project_id
211
+ });
212
+ }
213
+ // Send identify event to backend with session context
214
+ sendIdentifyToBackend(user, config, sessionInfo);
215
+ }
216
+ function sessionLensReset() {
217
+ const config = sessionLensGetConfig();
218
+ const sessionInfo = getSessionInfo(); // Get current session with activity update
219
+ if (config.debug) {
220
+ console.log('SessionLens Reset');
221
+ console.log('Session Context:', {
222
+ session_id: sessionInfo.session_id,
223
+ client_id: sessionInfo.client_id,
224
+ project_id: sessionInfo.project_id
225
+ });
226
+ }
227
+ // Clear any stored user data and send reset event to backend
228
+ sendResetToBackend(config, sessionInfo);
229
+ }
230
+ // Helper functions for backend communication with session context
231
+ async function sendEventToBackend(event, config, sessionInfo) {
232
+ const apiBaseUrl = getSessionLensApiBaseUrl();
233
+ try {
234
+ const response = await fetch(`${apiBaseUrl}/events/ingest`, {
235
+ method: 'POST',
236
+ headers: {
237
+ 'Content-Type': 'application/json',
238
+ 'Authorization': `Bearer ${config.sdk_key}`
239
+ },
240
+ body: JSON.stringify({
241
+ org_id: config.org_id,
242
+ project_id: sessionInfo.project_id,
243
+ user_id: config.user_id,
244
+ session_id: sessionInfo.session_id,
245
+ client_id: sessionInfo.client_id,
246
+ session_started_at: sessionInfo.started_at,
247
+ event: event
248
+ })
249
+ });
250
+ if (!response.ok && config.debug) {
251
+ console.warn('SessionLens: Failed to send event:', response.status);
252
+ }
253
+ else if (config.debug) {
254
+ console.log('SessionLens: Event sent successfully with session context');
255
+ }
256
+ }
257
+ catch (error) {
258
+ if (config.debug) {
259
+ console.warn('SessionLens: Network error sending event:', error);
260
+ }
261
+ }
262
+ }
263
+ async function sendIdentifyToBackend(user, config, sessionInfo) {
264
+ const apiBaseUrl = getSessionLensApiBaseUrl();
265
+ try {
266
+ const response = await fetch(`${apiBaseUrl}/identify`, {
267
+ method: 'POST',
268
+ headers: {
269
+ 'Content-Type': 'application/json',
270
+ 'Authorization': `Bearer ${config.sdk_key}`
271
+ },
272
+ body: JSON.stringify({
273
+ org_id: config.org_id,
274
+ project_id: sessionInfo.project_id,
275
+ user_id: user.user_id,
276
+ session_id: sessionInfo.session_id,
277
+ client_id: sessionInfo.client_id,
278
+ session_started_at: sessionInfo.started_at,
279
+ properties: user.properties
280
+ })
281
+ });
282
+ if (!response.ok && config.debug) {
283
+ console.warn('SessionLens: Failed to send identify:', response.status);
284
+ }
285
+ else if (config.debug) {
286
+ console.log('SessionLens: Identify sent successfully with session context');
287
+ }
288
+ }
289
+ catch (error) {
290
+ if (config.debug) {
291
+ console.warn('SessionLens: Network error sending identify:', error);
292
+ }
293
+ }
294
+ }
295
+ async function sendResetToBackend(config, sessionInfo) {
296
+ const apiBaseUrl = getSessionLensApiBaseUrl();
297
+ try {
298
+ const response = await fetch(`${apiBaseUrl}/reset`, {
299
+ method: 'POST',
300
+ headers: {
301
+ 'Content-Type': 'application/json',
302
+ 'Authorization': `Bearer ${config.sdk_key}`
303
+ },
304
+ body: JSON.stringify({
305
+ org_id: config.org_id,
306
+ project_id: sessionInfo.project_id,
307
+ user_id: config.user_id,
308
+ session_id: sessionInfo.session_id,
309
+ client_id: sessionInfo.client_id,
310
+ session_started_at: sessionInfo.started_at
311
+ })
312
+ });
313
+ if (!response.ok && config.debug) {
314
+ console.warn('SessionLens: Failed to send reset:', response.status);
315
+ }
316
+ else if (config.debug) {
317
+ console.log('SessionLens: Reset sent successfully with session context');
318
+ }
319
+ }
320
+ catch (error) {
321
+ if (config.debug) {
322
+ console.warn('SessionLens: Network error sending reset:', error);
323
+ }
324
+ }
325
+ }
326
+
327
+ const useSessionLens = (config) => {
328
+ useEffect(() => {
329
+ // Initialize SDK asynchronously
330
+ const initializeSDK = async () => {
331
+ try {
332
+ await sessionLensInit(config);
333
+ }
334
+ catch (error) {
335
+ console.error('[SessionLens] Initialization failed:', error);
336
+ }
337
+ };
338
+ initializeSDK();
339
+ // Cleanup on unmount
340
+ return () => {
341
+ sessionLensReset();
342
+ };
343
+ }, [config]);
344
+ };
345
+ const useSessionLensTrack = () => {
346
+ return (event) => {
347
+ try {
348
+ sessionLensTrack(event);
349
+ }
350
+ catch (error) {
351
+ console.error('[SessionLens] Track failed:', error);
352
+ }
353
+ };
354
+ };
355
+ const useSessionLensIdentify = () => {
356
+ return (user) => {
357
+ try {
358
+ sessionLensIdentify(user);
359
+ }
360
+ catch (error) {
361
+ console.error('[SessionLens] Identify failed:', error);
362
+ }
363
+ };
364
+ };
365
+
366
+ class SessionLens {
367
+ async sessionLensInit(config) {
368
+ await sessionLensInit(config);
369
+ }
370
+ sessionLensTrack(event) {
371
+ sessionLensTrack(event);
372
+ }
373
+ sessionLensIdentify(user) {
374
+ sessionLensIdentify(user);
375
+ }
376
+ sessionLensReset() {
377
+ sessionLensReset();
378
+ }
379
+ }
380
+ // Create and export singleton instance
381
+ const sessionLens = new SessionLens();
382
+
383
+ export { sessionLens as default, useSessionLens, useSessionLensIdentify, useSessionLensTrack };
384
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/core/config.ts","../src/core/tracker.ts","../src/integrations/react.ts","../src/index.ts"],"sourcesContent":["export interface SessionLensConfig {\n sdk_key: string;\n user_id: string;\n org_id: string;\n project_id?: string; // Optional: extracted from SDK key if not provided\n debug?: boolean;\n}\n\n// Production-ready session management interface\ninterface SessionInfo {\n session_id: string;\n client_id: string;\n org_id: string;\n project_id: string;\n user_id: string;\n started_at: number;\n last_activity: number;\n}\n\n// Session timeout (30 minutes of inactivity)\nconst SESSION_TIMEOUT = 30 * 60 * 1000;\n\n// Store the config and session info\nlet currentConfig: SessionLensConfig | null = null;\nlet currentSession: SessionInfo | null = null;\n\n// Extract project ID from SDK key pattern: sdk_prod_0000_684f15_5e0e72ac_35d2\nconst extractProjectFromSDKKey = (sdk_key: string): string => {\n const parts = sdk_key.split('_');\n return parts.length >= 4 ? `proj_${parts[3]}` : 'default';\n};\n\n// Generate crypto-grade unique IDs with hierarchical structure\nconst generateUniqueId = (config: SessionLensConfig, prefix: string): string => {\n const timestamp = Date.now();\n const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);\n \n // Use crypto.randomUUID() for true uniqueness, fallback to secure random\n const uuid = (() => {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID().replace(/-/g, '').substring(0, 12);\n }\n // Fallback: combine multiple random values for better entropy\n const random1 = Math.random().toString(36).substring(2, 15);\n const random2 = Math.random().toString(36).substring(2, 15);\n return (random1 + random2).substring(0, 12);\n })();\n \n // Format: {org_id}_{project_id}_{prefix}_{timestamp}_{uuid}\n return `${config.org_id}_${project_id}_${prefix}_${timestamp}_${uuid}`;\n};\n\n// Get or create persistent client ID (per project)\nconst getOrCreateClientId = (config: SessionLensConfig): string => {\n const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);\n const storageKey = `sessionlens_client_${config.org_id}_${project_id}`;\n \n if (typeof window !== 'undefined' && window.localStorage) {\n try {\n let clientId = localStorage.getItem(storageKey);\n if (!clientId) {\n clientId = generateUniqueId(config, 'client');\n localStorage.setItem(storageKey, clientId);\n }\n return clientId;\n } catch (error) {\n // localStorage might be disabled, fallback to session-only ID\n return generateUniqueId(config, 'client');\n }\n }\n \n // Fallback for non-browser environments\n return generateUniqueId(config, 'client');\n};\n\n// Start new session with collision-proof IDs\nconst startNewSession = (config: SessionLensConfig): void => {\n const now = Date.now();\n const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);\n \n currentSession = {\n session_id: generateUniqueId(config, 'sess'),\n client_id: getOrCreateClientId(config),\n org_id: config.org_id,\n project_id: project_id,\n user_id: config.user_id,\n started_at: now,\n last_activity: now\n };\n \n if (config.debug) {\n console.log('SessionLens: New session started', {\n session_id: currentSession.session_id,\n client_id: currentSession.client_id,\n project_id: currentSession.project_id\n });\n }\n};\n\n// Check if session is expired\nconst isSessionExpired = (): boolean => {\n if (!currentSession) return true;\n return Date.now() - currentSession.last_activity > SESSION_TIMEOUT;\n};\n\n// Update session activity timestamp\nconst updateSessionActivity = (): void => {\n if (currentSession) {\n currentSession.last_activity = Date.now();\n }\n};\n\n// Get API base URL from environment variable or use default\nconst getApiBaseUrl = (): string => {\n // Check for environment variable (works in Node.js and bundlers like Webpack/Vite)\n if (typeof process !== 'undefined' && process.env) {\n return process.env.SESSIONLENS_API_BASE_URL || process.env.REACT_APP_SESSIONLENS_API_BASE_URL || 'https://api.sessionlens.com/v1';\n }\n \n // Fallback for browser environments without build-time env vars\n return 'https://api.sessionlens.com/v1';\n};\n\n// `sessionLensInit()` sets the config and validates with backend\nexport async function sessionLensInit(config: SessionLensConfig): Promise<void> {\n // Validate required fields\n if (!config.sdk_key) {\n throw new Error('[SessionLens] sdk_key is required');\n }\n if (!config.user_id) {\n throw new Error('[SessionLens] user_id is required');\n }\n if (!config.org_id) {\n throw new Error('[SessionLens] org_id is required');\n }\n\n // Store the configuration\n currentConfig = config;\n\n // Start new session with scalable ID generation\n startNewSession(config);\n\n // Validate configuration with backend using GET (more RESTful)\n const apiBaseUrl = getApiBaseUrl();\n \n try {\n // Use GET with query parameters for org_id and user_id validation\n const validationUrl = new URL(`${apiBaseUrl}/org/validate`);\n validationUrl.searchParams.set('org_id', config.org_id);\n validationUrl.searchParams.set('user_id', config.user_id);\n \n const response = await fetch(validationUrl.toString(), {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${config.sdk_key}`\n }\n });\n\n if (!response.ok) {\n switch (response.status) {\n case 401:\n throw new Error('Invalid SDK key. Please check your credentials.');\n case 403:\n throw new Error('Access denied. Please verify your organization permissions.');\n case 404:\n throw new Error('Organization not found. Please check your org_id.');\n case 429:\n throw new Error('Rate limit exceeded. Please try again later.');\n default:\n throw new Error(`Validation failed with status ${response.status}`);\n }\n }\n\n const result = await response.json();\n if (config.debug) {\n console.log('SessionLens SDK initialized successfully:', result);\n console.log('Using API base URL:', apiBaseUrl);\n console.log('Validation endpoint:', validationUrl.toString());\n console.log('Session Info:', currentSession);\n }\n } catch (error) {\n if (error instanceof TypeError && error.message.includes('fetch')) {\n // Network error - allow offline mode\n if (config.debug) {\n console.warn('SessionLens SDK: Running in offline mode due to network error');\n }\n return;\n }\n // Re-throw validation errors\n throw error;\n }\n}\n\n// `sessionLensGetConfig()` returns it later (for use in tracker, etc)\nexport function sessionLensGetConfig(): SessionLensConfig {\n if (!currentConfig) {\n throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');\n }\n return currentConfig;\n}\n\n// Get current session info with auto-renewal and activity tracking\nexport function getSessionInfo(): SessionInfo {\n if (!currentConfig) {\n throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');\n }\n\n // Check if session expired or doesn't exist\n if (!currentSession || isSessionExpired()) {\n startNewSession(currentConfig);\n } else {\n // Update activity timestamp\n updateSessionActivity();\n }\n\n return currentSession!;\n}\n\n// Export function to get API base URL for use in other modules\nexport function getSessionLensApiBaseUrl(): string {\n return getApiBaseUrl();\n} ","import { sessionLensGetConfig, getSessionLensApiBaseUrl, getSessionInfo } from './config';\nimport { SessionLensEvent, SessionLensUser } from '../types';\n\nexport function sessionLensTrack(event: SessionLensEvent): void {\n const config = sessionLensGetConfig();\n const sessionInfo = getSessionInfo(); // Get current session with activity update\n \n // Add timestamp if not provided\n const eventWithTimestamp: SessionLensEvent = {\n ...event,\n timestamp: event.timestamp || Date.now()\n };\n\n if (config.debug) {\n console.log('SessionLens Track:', eventWithTimestamp);\n console.log('Session Context:', {\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n project_id: sessionInfo.project_id\n });\n }\n\n // Send event to backend with session context\n sendEventToBackend(eventWithTimestamp, config, sessionInfo);\n}\n\nexport function sessionLensIdentify(user: SessionLensUser): void {\n const config = sessionLensGetConfig();\n const sessionInfo = getSessionInfo(); // Get current session with activity update\n \n if (config.debug) {\n console.log('SessionLens Identify:', user);\n console.log('Session Context:', {\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n project_id: sessionInfo.project_id\n });\n }\n\n // Send identify event to backend with session context\n sendIdentifyToBackend(user, config, sessionInfo);\n}\n\nexport function sessionLensReset(): void {\n const config = sessionLensGetConfig();\n const sessionInfo = getSessionInfo(); // Get current session with activity update\n \n if (config.debug) {\n console.log('SessionLens Reset');\n console.log('Session Context:', {\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n project_id: sessionInfo.project_id\n });\n }\n\n // Clear any stored user data and send reset event to backend\n sendResetToBackend(config, sessionInfo);\n}\n\n// Helper functions for backend communication with session context\nasync function sendEventToBackend(event: SessionLensEvent, config: any, sessionInfo: any): Promise<void> {\n const apiBaseUrl = getSessionLensApiBaseUrl();\n \n try {\n const response = await fetch(`${apiBaseUrl}/events/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sdk_key}`\n },\n body: JSON.stringify({\n org_id: config.org_id,\n project_id: sessionInfo.project_id,\n user_id: config.user_id,\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n session_started_at: sessionInfo.started_at,\n event: event\n })\n });\n\n if (!response.ok && config.debug) {\n console.warn('SessionLens: Failed to send event:', response.status);\n } else if (config.debug) {\n console.log('SessionLens: Event sent successfully with session context');\n }\n } catch (error) {\n if (config.debug) {\n console.warn('SessionLens: Network error sending event:', error);\n }\n }\n}\n\nasync function sendIdentifyToBackend(user: SessionLensUser, config: any, sessionInfo: any): Promise<void> {\n const apiBaseUrl = getSessionLensApiBaseUrl();\n \n try {\n const response = await fetch(`${apiBaseUrl}/identify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sdk_key}`\n },\n body: JSON.stringify({\n org_id: config.org_id,\n project_id: sessionInfo.project_id,\n user_id: user.user_id,\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n session_started_at: sessionInfo.started_at,\n properties: user.properties\n })\n });\n\n if (!response.ok && config.debug) {\n console.warn('SessionLens: Failed to send identify:', response.status);\n } else if (config.debug) {\n console.log('SessionLens: Identify sent successfully with session context');\n }\n } catch (error) {\n if (config.debug) {\n console.warn('SessionLens: Network error sending identify:', error);\n }\n }\n}\n\nasync function sendResetToBackend(config: any, sessionInfo: any): Promise<void> {\n const apiBaseUrl = getSessionLensApiBaseUrl();\n \n try {\n const response = await fetch(`${apiBaseUrl}/reset`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sdk_key}`\n },\n body: JSON.stringify({\n org_id: config.org_id,\n project_id: sessionInfo.project_id,\n user_id: config.user_id,\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n session_started_at: sessionInfo.started_at\n })\n });\n\n if (!response.ok && config.debug) {\n console.warn('SessionLens: Failed to send reset:', response.status);\n } else if (config.debug) {\n console.log('SessionLens: Reset sent successfully with session context');\n }\n } catch (error) {\n if (config.debug) {\n console.warn('SessionLens: Network error sending reset:', error);\n }\n }\n} ","import { useEffect } from 'react';\nimport { SessionLensEvent, SessionLensUser } from '../types';\nimport { sessionLensInit, SessionLensConfig } from '../core/config';\nimport { sessionLensTrack, sessionLensIdentify, sessionLensReset } from '../core/tracker';\n\nexport const useSessionLens = (config: SessionLensConfig) => {\n useEffect(() => {\n // Initialize SDK asynchronously\n const initializeSDK = async () => {\n try {\n await sessionLensInit(config);\n } catch (error) {\n console.error('[SessionLens] Initialization failed:', error);\n }\n };\n\n initializeSDK();\n\n // Cleanup on unmount\n return () => {\n sessionLensReset();\n };\n }, [config]);\n};\n\nexport const useSessionLensTrack = () => {\n return (event: SessionLensEvent) => {\n try {\n sessionLensTrack(event);\n } catch (error) {\n console.error('[SessionLens] Track failed:', error);\n }\n };\n};\n\nexport const useSessionLensIdentify = () => {\n return (user: SessionLensUser) => {\n try {\n sessionLensIdentify(user);\n } catch (error) {\n console.error('[SessionLens] Identify failed:', error);\n }\n };\n}; ","import { sessionLensInit, SessionLensConfig } from './core/config';\nimport { sessionLensTrack, sessionLensIdentify, sessionLensReset } from './core/tracker';\nimport { SessionLensEvent, SessionLensUser, SessionLensInstance } from './types';\n\n// Export types\nexport * from './types';\nexport { SessionLensConfig } from './core/config';\n\n// Export React hooks\nexport * from './integrations/react';\n\nclass SessionLens implements SessionLensInstance {\n public async sessionLensInit(config: SessionLensConfig): Promise<void> {\n await sessionLensInit(config);\n }\n\n public sessionLensTrack(event: SessionLensEvent): void {\n sessionLensTrack(event);\n }\n\n public sessionLensIdentify(user: SessionLensUser): void {\n sessionLensIdentify(user);\n }\n\n public sessionLensReset(): void {\n sessionLensReset();\n }\n}\n\n// Create and export singleton instance\nconst sessionLens = new SessionLens();\nexport default sessionLens; "],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,391 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var react = require('react');
6
+
7
+ // Session timeout (30 minutes of inactivity)
8
+ const SESSION_TIMEOUT = 30 * 60 * 1000;
9
+ // Store the config and session info
10
+ let currentConfig = null;
11
+ let currentSession = null;
12
+ // Extract project ID from SDK key pattern: sdk_prod_0000_684f15_5e0e72ac_35d2
13
+ const extractProjectFromSDKKey = (sdk_key) => {
14
+ const parts = sdk_key.split('_');
15
+ return parts.length >= 4 ? `proj_${parts[3]}` : 'default';
16
+ };
17
+ // Generate crypto-grade unique IDs with hierarchical structure
18
+ const generateUniqueId = (config, prefix) => {
19
+ const timestamp = Date.now();
20
+ const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);
21
+ // Use crypto.randomUUID() for true uniqueness, fallback to secure random
22
+ const uuid = (() => {
23
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
24
+ return crypto.randomUUID().replace(/-/g, '').substring(0, 12);
25
+ }
26
+ // Fallback: combine multiple random values for better entropy
27
+ const random1 = Math.random().toString(36).substring(2, 15);
28
+ const random2 = Math.random().toString(36).substring(2, 15);
29
+ return (random1 + random2).substring(0, 12);
30
+ })();
31
+ // Format: {org_id}_{project_id}_{prefix}_{timestamp}_{uuid}
32
+ return `${config.org_id}_${project_id}_${prefix}_${timestamp}_${uuid}`;
33
+ };
34
+ // Get or create persistent client ID (per project)
35
+ const getOrCreateClientId = (config) => {
36
+ const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);
37
+ const storageKey = `sessionlens_client_${config.org_id}_${project_id}`;
38
+ if (typeof window !== 'undefined' && window.localStorage) {
39
+ try {
40
+ let clientId = localStorage.getItem(storageKey);
41
+ if (!clientId) {
42
+ clientId = generateUniqueId(config, 'client');
43
+ localStorage.setItem(storageKey, clientId);
44
+ }
45
+ return clientId;
46
+ }
47
+ catch (error) {
48
+ // localStorage might be disabled, fallback to session-only ID
49
+ return generateUniqueId(config, 'client');
50
+ }
51
+ }
52
+ // Fallback for non-browser environments
53
+ return generateUniqueId(config, 'client');
54
+ };
55
+ // Start new session with collision-proof IDs
56
+ const startNewSession = (config) => {
57
+ const now = Date.now();
58
+ const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);
59
+ currentSession = {
60
+ session_id: generateUniqueId(config, 'sess'),
61
+ client_id: getOrCreateClientId(config),
62
+ org_id: config.org_id,
63
+ project_id: project_id,
64
+ user_id: config.user_id,
65
+ started_at: now,
66
+ last_activity: now
67
+ };
68
+ if (config.debug) {
69
+ console.log('SessionLens: New session started', {
70
+ session_id: currentSession.session_id,
71
+ client_id: currentSession.client_id,
72
+ project_id: currentSession.project_id
73
+ });
74
+ }
75
+ };
76
+ // Check if session is expired
77
+ const isSessionExpired = () => {
78
+ if (!currentSession)
79
+ return true;
80
+ return Date.now() - currentSession.last_activity > SESSION_TIMEOUT;
81
+ };
82
+ // Update session activity timestamp
83
+ const updateSessionActivity = () => {
84
+ if (currentSession) {
85
+ currentSession.last_activity = Date.now();
86
+ }
87
+ };
88
+ // Get API base URL from environment variable or use default
89
+ const getApiBaseUrl = () => {
90
+ // Check for environment variable (works in Node.js and bundlers like Webpack/Vite)
91
+ if (typeof process !== 'undefined' && process.env) {
92
+ return process.env.SESSIONLENS_API_BASE_URL || process.env.REACT_APP_SESSIONLENS_API_BASE_URL || 'https://api.sessionlens.com/v1';
93
+ }
94
+ // Fallback for browser environments without build-time env vars
95
+ return 'https://api.sessionlens.com/v1';
96
+ };
97
+ // `sessionLensInit()` sets the config and validates with backend
98
+ async function sessionLensInit(config) {
99
+ // Validate required fields
100
+ if (!config.sdk_key) {
101
+ throw new Error('[SessionLens] sdk_key is required');
102
+ }
103
+ if (!config.user_id) {
104
+ throw new Error('[SessionLens] user_id is required');
105
+ }
106
+ if (!config.org_id) {
107
+ throw new Error('[SessionLens] org_id is required');
108
+ }
109
+ // Store the configuration
110
+ currentConfig = config;
111
+ // Start new session with scalable ID generation
112
+ startNewSession(config);
113
+ // Validate configuration with backend using GET (more RESTful)
114
+ const apiBaseUrl = getApiBaseUrl();
115
+ try {
116
+ // Use GET with query parameters for org_id and user_id validation
117
+ const validationUrl = new URL(`${apiBaseUrl}/org/validate`);
118
+ validationUrl.searchParams.set('org_id', config.org_id);
119
+ validationUrl.searchParams.set('user_id', config.user_id);
120
+ const response = await fetch(validationUrl.toString(), {
121
+ method: 'GET',
122
+ headers: {
123
+ 'Authorization': `Bearer ${config.sdk_key}`
124
+ }
125
+ });
126
+ if (!response.ok) {
127
+ switch (response.status) {
128
+ case 401:
129
+ throw new Error('Invalid SDK key. Please check your credentials.');
130
+ case 403:
131
+ throw new Error('Access denied. Please verify your organization permissions.');
132
+ case 404:
133
+ throw new Error('Organization not found. Please check your org_id.');
134
+ case 429:
135
+ throw new Error('Rate limit exceeded. Please try again later.');
136
+ default:
137
+ throw new Error(`Validation failed with status ${response.status}`);
138
+ }
139
+ }
140
+ const result = await response.json();
141
+ if (config.debug) {
142
+ console.log('SessionLens SDK initialized successfully:', result);
143
+ console.log('Using API base URL:', apiBaseUrl);
144
+ console.log('Validation endpoint:', validationUrl.toString());
145
+ console.log('Session Info:', currentSession);
146
+ }
147
+ }
148
+ catch (error) {
149
+ if (error instanceof TypeError && error.message.includes('fetch')) {
150
+ // Network error - allow offline mode
151
+ if (config.debug) {
152
+ console.warn('SessionLens SDK: Running in offline mode due to network error');
153
+ }
154
+ return;
155
+ }
156
+ // Re-throw validation errors
157
+ throw error;
158
+ }
159
+ }
160
+ // `sessionLensGetConfig()` returns it later (for use in tracker, etc)
161
+ function sessionLensGetConfig() {
162
+ if (!currentConfig) {
163
+ throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');
164
+ }
165
+ return currentConfig;
166
+ }
167
+ // Get current session info with auto-renewal and activity tracking
168
+ function getSessionInfo() {
169
+ if (!currentConfig) {
170
+ throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');
171
+ }
172
+ // Check if session expired or doesn't exist
173
+ if (!currentSession || isSessionExpired()) {
174
+ startNewSession(currentConfig);
175
+ }
176
+ else {
177
+ // Update activity timestamp
178
+ updateSessionActivity();
179
+ }
180
+ return currentSession;
181
+ }
182
+ // Export function to get API base URL for use in other modules
183
+ function getSessionLensApiBaseUrl() {
184
+ return getApiBaseUrl();
185
+ }
186
+
187
+ function sessionLensTrack(event) {
188
+ const config = sessionLensGetConfig();
189
+ const sessionInfo = getSessionInfo(); // Get current session with activity update
190
+ // Add timestamp if not provided
191
+ const eventWithTimestamp = {
192
+ ...event,
193
+ timestamp: event.timestamp || Date.now()
194
+ };
195
+ if (config.debug) {
196
+ console.log('SessionLens Track:', eventWithTimestamp);
197
+ console.log('Session Context:', {
198
+ session_id: sessionInfo.session_id,
199
+ client_id: sessionInfo.client_id,
200
+ project_id: sessionInfo.project_id
201
+ });
202
+ }
203
+ // Send event to backend with session context
204
+ sendEventToBackend(eventWithTimestamp, config, sessionInfo);
205
+ }
206
+ function sessionLensIdentify(user) {
207
+ const config = sessionLensGetConfig();
208
+ const sessionInfo = getSessionInfo(); // Get current session with activity update
209
+ if (config.debug) {
210
+ console.log('SessionLens Identify:', user);
211
+ console.log('Session Context:', {
212
+ session_id: sessionInfo.session_id,
213
+ client_id: sessionInfo.client_id,
214
+ project_id: sessionInfo.project_id
215
+ });
216
+ }
217
+ // Send identify event to backend with session context
218
+ sendIdentifyToBackend(user, config, sessionInfo);
219
+ }
220
+ function sessionLensReset() {
221
+ const config = sessionLensGetConfig();
222
+ const sessionInfo = getSessionInfo(); // Get current session with activity update
223
+ if (config.debug) {
224
+ console.log('SessionLens Reset');
225
+ console.log('Session Context:', {
226
+ session_id: sessionInfo.session_id,
227
+ client_id: sessionInfo.client_id,
228
+ project_id: sessionInfo.project_id
229
+ });
230
+ }
231
+ // Clear any stored user data and send reset event to backend
232
+ sendResetToBackend(config, sessionInfo);
233
+ }
234
+ // Helper functions for backend communication with session context
235
+ async function sendEventToBackend(event, config, sessionInfo) {
236
+ const apiBaseUrl = getSessionLensApiBaseUrl();
237
+ try {
238
+ const response = await fetch(`${apiBaseUrl}/events/ingest`, {
239
+ method: 'POST',
240
+ headers: {
241
+ 'Content-Type': 'application/json',
242
+ 'Authorization': `Bearer ${config.sdk_key}`
243
+ },
244
+ body: JSON.stringify({
245
+ org_id: config.org_id,
246
+ project_id: sessionInfo.project_id,
247
+ user_id: config.user_id,
248
+ session_id: sessionInfo.session_id,
249
+ client_id: sessionInfo.client_id,
250
+ session_started_at: sessionInfo.started_at,
251
+ event: event
252
+ })
253
+ });
254
+ if (!response.ok && config.debug) {
255
+ console.warn('SessionLens: Failed to send event:', response.status);
256
+ }
257
+ else if (config.debug) {
258
+ console.log('SessionLens: Event sent successfully with session context');
259
+ }
260
+ }
261
+ catch (error) {
262
+ if (config.debug) {
263
+ console.warn('SessionLens: Network error sending event:', error);
264
+ }
265
+ }
266
+ }
267
+ async function sendIdentifyToBackend(user, config, sessionInfo) {
268
+ const apiBaseUrl = getSessionLensApiBaseUrl();
269
+ try {
270
+ const response = await fetch(`${apiBaseUrl}/identify`, {
271
+ method: 'POST',
272
+ headers: {
273
+ 'Content-Type': 'application/json',
274
+ 'Authorization': `Bearer ${config.sdk_key}`
275
+ },
276
+ body: JSON.stringify({
277
+ org_id: config.org_id,
278
+ project_id: sessionInfo.project_id,
279
+ user_id: user.user_id,
280
+ session_id: sessionInfo.session_id,
281
+ client_id: sessionInfo.client_id,
282
+ session_started_at: sessionInfo.started_at,
283
+ properties: user.properties
284
+ })
285
+ });
286
+ if (!response.ok && config.debug) {
287
+ console.warn('SessionLens: Failed to send identify:', response.status);
288
+ }
289
+ else if (config.debug) {
290
+ console.log('SessionLens: Identify sent successfully with session context');
291
+ }
292
+ }
293
+ catch (error) {
294
+ if (config.debug) {
295
+ console.warn('SessionLens: Network error sending identify:', error);
296
+ }
297
+ }
298
+ }
299
+ async function sendResetToBackend(config, sessionInfo) {
300
+ const apiBaseUrl = getSessionLensApiBaseUrl();
301
+ try {
302
+ const response = await fetch(`${apiBaseUrl}/reset`, {
303
+ method: 'POST',
304
+ headers: {
305
+ 'Content-Type': 'application/json',
306
+ 'Authorization': `Bearer ${config.sdk_key}`
307
+ },
308
+ body: JSON.stringify({
309
+ org_id: config.org_id,
310
+ project_id: sessionInfo.project_id,
311
+ user_id: config.user_id,
312
+ session_id: sessionInfo.session_id,
313
+ client_id: sessionInfo.client_id,
314
+ session_started_at: sessionInfo.started_at
315
+ })
316
+ });
317
+ if (!response.ok && config.debug) {
318
+ console.warn('SessionLens: Failed to send reset:', response.status);
319
+ }
320
+ else if (config.debug) {
321
+ console.log('SessionLens: Reset sent successfully with session context');
322
+ }
323
+ }
324
+ catch (error) {
325
+ if (config.debug) {
326
+ console.warn('SessionLens: Network error sending reset:', error);
327
+ }
328
+ }
329
+ }
330
+
331
+ const useSessionLens = (config) => {
332
+ react.useEffect(() => {
333
+ // Initialize SDK asynchronously
334
+ const initializeSDK = async () => {
335
+ try {
336
+ await sessionLensInit(config);
337
+ }
338
+ catch (error) {
339
+ console.error('[SessionLens] Initialization failed:', error);
340
+ }
341
+ };
342
+ initializeSDK();
343
+ // Cleanup on unmount
344
+ return () => {
345
+ sessionLensReset();
346
+ };
347
+ }, [config]);
348
+ };
349
+ const useSessionLensTrack = () => {
350
+ return (event) => {
351
+ try {
352
+ sessionLensTrack(event);
353
+ }
354
+ catch (error) {
355
+ console.error('[SessionLens] Track failed:', error);
356
+ }
357
+ };
358
+ };
359
+ const useSessionLensIdentify = () => {
360
+ return (user) => {
361
+ try {
362
+ sessionLensIdentify(user);
363
+ }
364
+ catch (error) {
365
+ console.error('[SessionLens] Identify failed:', error);
366
+ }
367
+ };
368
+ };
369
+
370
+ class SessionLens {
371
+ async sessionLensInit(config) {
372
+ await sessionLensInit(config);
373
+ }
374
+ sessionLensTrack(event) {
375
+ sessionLensTrack(event);
376
+ }
377
+ sessionLensIdentify(user) {
378
+ sessionLensIdentify(user);
379
+ }
380
+ sessionLensReset() {
381
+ sessionLensReset();
382
+ }
383
+ }
384
+ // Create and export singleton instance
385
+ const sessionLens = new SessionLens();
386
+
387
+ exports["default"] = sessionLens;
388
+ exports.useSessionLens = useSessionLens;
389
+ exports.useSessionLensIdentify = useSessionLensIdentify;
390
+ exports.useSessionLensTrack = useSessionLensTrack;
391
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/core/config.ts","../src/core/tracker.ts","../src/integrations/react.ts","../src/index.ts"],"sourcesContent":["export interface SessionLensConfig {\n sdk_key: string;\n user_id: string;\n org_id: string;\n project_id?: string; // Optional: extracted from SDK key if not provided\n debug?: boolean;\n}\n\n// Production-ready session management interface\ninterface SessionInfo {\n session_id: string;\n client_id: string;\n org_id: string;\n project_id: string;\n user_id: string;\n started_at: number;\n last_activity: number;\n}\n\n// Session timeout (30 minutes of inactivity)\nconst SESSION_TIMEOUT = 30 * 60 * 1000;\n\n// Store the config and session info\nlet currentConfig: SessionLensConfig | null = null;\nlet currentSession: SessionInfo | null = null;\n\n// Extract project ID from SDK key pattern: sdk_prod_0000_684f15_5e0e72ac_35d2\nconst extractProjectFromSDKKey = (sdk_key: string): string => {\n const parts = sdk_key.split('_');\n return parts.length >= 4 ? `proj_${parts[3]}` : 'default';\n};\n\n// Generate crypto-grade unique IDs with hierarchical structure\nconst generateUniqueId = (config: SessionLensConfig, prefix: string): string => {\n const timestamp = Date.now();\n const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);\n \n // Use crypto.randomUUID() for true uniqueness, fallback to secure random\n const uuid = (() => {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID().replace(/-/g, '').substring(0, 12);\n }\n // Fallback: combine multiple random values for better entropy\n const random1 = Math.random().toString(36).substring(2, 15);\n const random2 = Math.random().toString(36).substring(2, 15);\n return (random1 + random2).substring(0, 12);\n })();\n \n // Format: {org_id}_{project_id}_{prefix}_{timestamp}_{uuid}\n return `${config.org_id}_${project_id}_${prefix}_${timestamp}_${uuid}`;\n};\n\n// Get or create persistent client ID (per project)\nconst getOrCreateClientId = (config: SessionLensConfig): string => {\n const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);\n const storageKey = `sessionlens_client_${config.org_id}_${project_id}`;\n \n if (typeof window !== 'undefined' && window.localStorage) {\n try {\n let clientId = localStorage.getItem(storageKey);\n if (!clientId) {\n clientId = generateUniqueId(config, 'client');\n localStorage.setItem(storageKey, clientId);\n }\n return clientId;\n } catch (error) {\n // localStorage might be disabled, fallback to session-only ID\n return generateUniqueId(config, 'client');\n }\n }\n \n // Fallback for non-browser environments\n return generateUniqueId(config, 'client');\n};\n\n// Start new session with collision-proof IDs\nconst startNewSession = (config: SessionLensConfig): void => {\n const now = Date.now();\n const project_id = config.project_id || extractProjectFromSDKKey(config.sdk_key);\n \n currentSession = {\n session_id: generateUniqueId(config, 'sess'),\n client_id: getOrCreateClientId(config),\n org_id: config.org_id,\n project_id: project_id,\n user_id: config.user_id,\n started_at: now,\n last_activity: now\n };\n \n if (config.debug) {\n console.log('SessionLens: New session started', {\n session_id: currentSession.session_id,\n client_id: currentSession.client_id,\n project_id: currentSession.project_id\n });\n }\n};\n\n// Check if session is expired\nconst isSessionExpired = (): boolean => {\n if (!currentSession) return true;\n return Date.now() - currentSession.last_activity > SESSION_TIMEOUT;\n};\n\n// Update session activity timestamp\nconst updateSessionActivity = (): void => {\n if (currentSession) {\n currentSession.last_activity = Date.now();\n }\n};\n\n// Get API base URL from environment variable or use default\nconst getApiBaseUrl = (): string => {\n // Check for environment variable (works in Node.js and bundlers like Webpack/Vite)\n if (typeof process !== 'undefined' && process.env) {\n return process.env.SESSIONLENS_API_BASE_URL || process.env.REACT_APP_SESSIONLENS_API_BASE_URL || 'https://api.sessionlens.com/v1';\n }\n \n // Fallback for browser environments without build-time env vars\n return 'https://api.sessionlens.com/v1';\n};\n\n// `sessionLensInit()` sets the config and validates with backend\nexport async function sessionLensInit(config: SessionLensConfig): Promise<void> {\n // Validate required fields\n if (!config.sdk_key) {\n throw new Error('[SessionLens] sdk_key is required');\n }\n if (!config.user_id) {\n throw new Error('[SessionLens] user_id is required');\n }\n if (!config.org_id) {\n throw new Error('[SessionLens] org_id is required');\n }\n\n // Store the configuration\n currentConfig = config;\n\n // Start new session with scalable ID generation\n startNewSession(config);\n\n // Validate configuration with backend using GET (more RESTful)\n const apiBaseUrl = getApiBaseUrl();\n \n try {\n // Use GET with query parameters for org_id and user_id validation\n const validationUrl = new URL(`${apiBaseUrl}/org/validate`);\n validationUrl.searchParams.set('org_id', config.org_id);\n validationUrl.searchParams.set('user_id', config.user_id);\n \n const response = await fetch(validationUrl.toString(), {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${config.sdk_key}`\n }\n });\n\n if (!response.ok) {\n switch (response.status) {\n case 401:\n throw new Error('Invalid SDK key. Please check your credentials.');\n case 403:\n throw new Error('Access denied. Please verify your organization permissions.');\n case 404:\n throw new Error('Organization not found. Please check your org_id.');\n case 429:\n throw new Error('Rate limit exceeded. Please try again later.');\n default:\n throw new Error(`Validation failed with status ${response.status}`);\n }\n }\n\n const result = await response.json();\n if (config.debug) {\n console.log('SessionLens SDK initialized successfully:', result);\n console.log('Using API base URL:', apiBaseUrl);\n console.log('Validation endpoint:', validationUrl.toString());\n console.log('Session Info:', currentSession);\n }\n } catch (error) {\n if (error instanceof TypeError && error.message.includes('fetch')) {\n // Network error - allow offline mode\n if (config.debug) {\n console.warn('SessionLens SDK: Running in offline mode due to network error');\n }\n return;\n }\n // Re-throw validation errors\n throw error;\n }\n}\n\n// `sessionLensGetConfig()` returns it later (for use in tracker, etc)\nexport function sessionLensGetConfig(): SessionLensConfig {\n if (!currentConfig) {\n throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');\n }\n return currentConfig;\n}\n\n// Get current session info with auto-renewal and activity tracking\nexport function getSessionInfo(): SessionInfo {\n if (!currentConfig) {\n throw new Error('[SessionLens] SDK not initialized. Call `sessionLensInit()` first.');\n }\n\n // Check if session expired or doesn't exist\n if (!currentSession || isSessionExpired()) {\n startNewSession(currentConfig);\n } else {\n // Update activity timestamp\n updateSessionActivity();\n }\n\n return currentSession!;\n}\n\n// Export function to get API base URL for use in other modules\nexport function getSessionLensApiBaseUrl(): string {\n return getApiBaseUrl();\n} ","import { sessionLensGetConfig, getSessionLensApiBaseUrl, getSessionInfo } from './config';\nimport { SessionLensEvent, SessionLensUser } from '../types';\n\nexport function sessionLensTrack(event: SessionLensEvent): void {\n const config = sessionLensGetConfig();\n const sessionInfo = getSessionInfo(); // Get current session with activity update\n \n // Add timestamp if not provided\n const eventWithTimestamp: SessionLensEvent = {\n ...event,\n timestamp: event.timestamp || Date.now()\n };\n\n if (config.debug) {\n console.log('SessionLens Track:', eventWithTimestamp);\n console.log('Session Context:', {\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n project_id: sessionInfo.project_id\n });\n }\n\n // Send event to backend with session context\n sendEventToBackend(eventWithTimestamp, config, sessionInfo);\n}\n\nexport function sessionLensIdentify(user: SessionLensUser): void {\n const config = sessionLensGetConfig();\n const sessionInfo = getSessionInfo(); // Get current session with activity update\n \n if (config.debug) {\n console.log('SessionLens Identify:', user);\n console.log('Session Context:', {\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n project_id: sessionInfo.project_id\n });\n }\n\n // Send identify event to backend with session context\n sendIdentifyToBackend(user, config, sessionInfo);\n}\n\nexport function sessionLensReset(): void {\n const config = sessionLensGetConfig();\n const sessionInfo = getSessionInfo(); // Get current session with activity update\n \n if (config.debug) {\n console.log('SessionLens Reset');\n console.log('Session Context:', {\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n project_id: sessionInfo.project_id\n });\n }\n\n // Clear any stored user data and send reset event to backend\n sendResetToBackend(config, sessionInfo);\n}\n\n// Helper functions for backend communication with session context\nasync function sendEventToBackend(event: SessionLensEvent, config: any, sessionInfo: any): Promise<void> {\n const apiBaseUrl = getSessionLensApiBaseUrl();\n \n try {\n const response = await fetch(`${apiBaseUrl}/events/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sdk_key}`\n },\n body: JSON.stringify({\n org_id: config.org_id,\n project_id: sessionInfo.project_id,\n user_id: config.user_id,\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n session_started_at: sessionInfo.started_at,\n event: event\n })\n });\n\n if (!response.ok && config.debug) {\n console.warn('SessionLens: Failed to send event:', response.status);\n } else if (config.debug) {\n console.log('SessionLens: Event sent successfully with session context');\n }\n } catch (error) {\n if (config.debug) {\n console.warn('SessionLens: Network error sending event:', error);\n }\n }\n}\n\nasync function sendIdentifyToBackend(user: SessionLensUser, config: any, sessionInfo: any): Promise<void> {\n const apiBaseUrl = getSessionLensApiBaseUrl();\n \n try {\n const response = await fetch(`${apiBaseUrl}/identify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sdk_key}`\n },\n body: JSON.stringify({\n org_id: config.org_id,\n project_id: sessionInfo.project_id,\n user_id: user.user_id,\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n session_started_at: sessionInfo.started_at,\n properties: user.properties\n })\n });\n\n if (!response.ok && config.debug) {\n console.warn('SessionLens: Failed to send identify:', response.status);\n } else if (config.debug) {\n console.log('SessionLens: Identify sent successfully with session context');\n }\n } catch (error) {\n if (config.debug) {\n console.warn('SessionLens: Network error sending identify:', error);\n }\n }\n}\n\nasync function sendResetToBackend(config: any, sessionInfo: any): Promise<void> {\n const apiBaseUrl = getSessionLensApiBaseUrl();\n \n try {\n const response = await fetch(`${apiBaseUrl}/reset`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sdk_key}`\n },\n body: JSON.stringify({\n org_id: config.org_id,\n project_id: sessionInfo.project_id,\n user_id: config.user_id,\n session_id: sessionInfo.session_id,\n client_id: sessionInfo.client_id,\n session_started_at: sessionInfo.started_at\n })\n });\n\n if (!response.ok && config.debug) {\n console.warn('SessionLens: Failed to send reset:', response.status);\n } else if (config.debug) {\n console.log('SessionLens: Reset sent successfully with session context');\n }\n } catch (error) {\n if (config.debug) {\n console.warn('SessionLens: Network error sending reset:', error);\n }\n }\n} ","import { useEffect } from 'react';\nimport { SessionLensEvent, SessionLensUser } from '../types';\nimport { sessionLensInit, SessionLensConfig } from '../core/config';\nimport { sessionLensTrack, sessionLensIdentify, sessionLensReset } from '../core/tracker';\n\nexport const useSessionLens = (config: SessionLensConfig) => {\n useEffect(() => {\n // Initialize SDK asynchronously\n const initializeSDK = async () => {\n try {\n await sessionLensInit(config);\n } catch (error) {\n console.error('[SessionLens] Initialization failed:', error);\n }\n };\n\n initializeSDK();\n\n // Cleanup on unmount\n return () => {\n sessionLensReset();\n };\n }, [config]);\n};\n\nexport const useSessionLensTrack = () => {\n return (event: SessionLensEvent) => {\n try {\n sessionLensTrack(event);\n } catch (error) {\n console.error('[SessionLens] Track failed:', error);\n }\n };\n};\n\nexport const useSessionLensIdentify = () => {\n return (user: SessionLensUser) => {\n try {\n sessionLensIdentify(user);\n } catch (error) {\n console.error('[SessionLens] Identify failed:', error);\n }\n };\n}; ","import { sessionLensInit, SessionLensConfig } from './core/config';\nimport { sessionLensTrack, sessionLensIdentify, sessionLensReset } from './core/tracker';\nimport { SessionLensEvent, SessionLensUser, SessionLensInstance } from './types';\n\n// Export types\nexport * from './types';\nexport { SessionLensConfig } from './core/config';\n\n// Export React hooks\nexport * from './integrations/react';\n\nclass SessionLens implements SessionLensInstance {\n public async sessionLensInit(config: SessionLensConfig): Promise<void> {\n await sessionLensInit(config);\n }\n\n public sessionLensTrack(event: SessionLensEvent): void {\n sessionLensTrack(event);\n }\n\n public sessionLensIdentify(user: SessionLensUser): void {\n sessionLensIdentify(user);\n }\n\n public sessionLensReset(): void {\n sessionLensReset();\n }\n}\n\n// Create and export singleton instance\nconst sessionLens = new SessionLens();\nexport default sessionLens; "],"names":["useEffect"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { SessionLensEvent, SessionLensUser } from '../types';
2
+ import { SessionLensConfig } from '../core/config';
3
+ export declare const useSessionLens: (config: SessionLensConfig) => void;
4
+ export declare const useSessionLensTrack: () => (event: SessionLensEvent) => void;
5
+ export declare const useSessionLensIdentify: () => (user: SessionLensUser) => void;
@@ -0,0 +1,15 @@
1
+ export interface SessionLensEvent {
2
+ event_name: string;
3
+ properties?: Record<string, any>;
4
+ timestamp?: number;
5
+ }
6
+ export interface SessionLensUser {
7
+ user_id: string;
8
+ properties?: Record<string, any>;
9
+ }
10
+ export interface SessionLensInstance {
11
+ sessionLensInit: (config: import('./core/config').SessionLensConfig) => Promise<void>;
12
+ sessionLensTrack: (event: SessionLensEvent) => void;
13
+ sessionLensIdentify: (user: SessionLensUser) => void;
14
+ sessionLensReset: () => void;
15
+ }
@@ -0,0 +1,9 @@
1
+ export declare class Logger {
2
+ private static instance;
3
+ private constructor();
4
+ static getInstance(): Logger;
5
+ debug(message: string, ...args: any[]): void;
6
+ info(message: string, ...args: any[]): void;
7
+ warn(message: string, ...args: any[]): void;
8
+ error(message: string, ...args: any[]): void;
9
+ }
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@sessionlens/sdk",
3
+ "version": "0.1.0",
4
+ "description": "SessionLens SDK for analytics and event tracking",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "rollup -c",
13
+ "test": "jest",
14
+ "lint": "eslint src --ext .ts",
15
+ "format": "prettier --write \"src/**/*.ts\"",
16
+ "prepare": "npm run build"
17
+ },
18
+ "keywords": [
19
+ "analytics",
20
+ "tracking",
21
+ "events"
22
+ ],
23
+ "author": "SessionLens",
24
+ "license": "MIT",
25
+ "devDependencies": {
26
+ "@types/jest": "^29.5.0",
27
+ "@types/react": "^18.3.14",
28
+ "@typescript-eslint/eslint-plugin": "^5.59.0",
29
+ "@typescript-eslint/parser": "^5.59.0",
30
+ "eslint": "^8.38.0",
31
+ "jest": "^29.5.0",
32
+ "prettier": "^2.8.7",
33
+ "react": "^19.1.0",
34
+ "rollup": "^2.79.1",
35
+ "rollup-plugin-typescript2": "^0.31.2",
36
+ "ts-jest": "^29.1.0",
37
+ "typescript": "^5.0.4"
38
+ },
39
+ "peerDependencies": {
40
+ "react": ">=16.8.0"
41
+ }
42
+ }