@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 +266 -0
- package/dist/core/config.d.ts +21 -0
- package/dist/core/tracker.d.ts +4 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.esm.js +384 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +391 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/react.d.ts +5 -0
- package/dist/types.d.ts +15 -0
- package/dist/utils/logger.d.ts +9 -0
- package/package.json +42 -0
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 {};
|
package/dist/index.d.ts
ADDED
|
@@ -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;
|
package/dist/types.d.ts
ADDED
|
@@ -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
|
+
}
|