humanbehavior-js 0.0.9 → 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.
@@ -83,6 +83,7 @@ declare const redactionManager: RedactionManager;
83
83
  declare global {
84
84
  interface Window {
85
85
  HumanBehaviorTracker: typeof HumanBehaviorTracker;
86
+ __humanBehaviorGlobalTracker?: HumanBehaviorTracker;
86
87
  }
87
88
  }
88
89
  declare class HumanBehaviorTracker {
@@ -102,11 +103,46 @@ declare class HumanBehaviorTracker {
102
103
  initializationPromise: Promise<void> | null;
103
104
  private redactionManager;
104
105
  private originalConsole;
105
- private originalLogger;
106
106
  private consoleTrackingEnabled;
107
+ navigationTrackingEnabled: boolean;
108
+ private currentUrl;
109
+ private previousUrl;
110
+ private originalPushState;
111
+ private originalReplaceState;
112
+ private navigationListeners;
113
+ private _connectionBlocked;
114
+ /**
115
+ * Initialize the HumanBehavior tracker
116
+ * This is the main entry point - call this once per page
117
+ */
118
+ static init(apiKey: string, options?: {
119
+ ingestionUrl?: string;
120
+ logLevel?: 'none' | 'error' | 'warn' | 'info' | 'debug';
121
+ redactFields?: string[];
122
+ }): HumanBehaviorTracker;
107
123
  constructor(apiKey: string | undefined, ingestionUrl?: string);
108
124
  private init;
109
125
  private ensureInitialized;
126
+ /**
127
+ * Setup navigation event tracking for SPA navigation
128
+ */
129
+ private setupNavigationTracking;
130
+ /**
131
+ * Track navigation events and send custom events
132
+ */
133
+ trackNavigationEvent(type: string, fromUrl: string, toUrl: string): Promise<void>;
134
+ /**
135
+ * Track a page view event (PostHog-style)
136
+ */
137
+ trackPageView(url?: string): Promise<void>;
138
+ /**
139
+ * Track a custom event (PostHog-style)
140
+ */
141
+ customEvent(eventName: string, properties?: Record<string, any>): Promise<void>;
142
+ /**
143
+ * Cleanup navigation tracking
144
+ */
145
+ private cleanupNavigationTracking;
110
146
  static logToStorage(message: string): void;
111
147
  /**
112
148
  * Configure logging behavior for the SDK
@@ -125,9 +161,6 @@ declare class HumanBehaviorTracker {
125
161
  * Disable console event tracking
126
162
  */
127
163
  disableConsoleTracking(): void;
128
- /**
129
- * Track console events
130
- */
131
164
  private trackConsoleEvent;
132
165
  private setupPageUnloadHandler;
133
166
  viewLogs(): void;
@@ -137,7 +170,6 @@ declare class HumanBehaviorTracker {
137
170
  * @param authFields Array of field names to check for existing users (e.g., ['email', 'phoneNumber'])
138
171
  */
139
172
  auth(authFields: string[]): Promise<void>;
140
- customEvent(eventName: string, eventProperties?: Record<string, any>): Promise<void>;
141
173
  start(): Promise<void>;
142
174
  stop(): Promise<void>;
143
175
  addEvent(event: any): Promise<void>;
@@ -163,6 +195,28 @@ declare class HumanBehaviorTracker {
163
195
  * Get the currently selected fields for redaction
164
196
  */
165
197
  getRedactedFields(): string[];
198
+ /**
199
+ * Get the current session ID
200
+ */
201
+ getSessionId(): string;
202
+ /**
203
+ * Get the current URL being tracked
204
+ */
205
+ getCurrentUrl(): string;
206
+ /**
207
+ * Test if the tracker can reach the ingestion server
208
+ */
209
+ testConnection(): Promise<{
210
+ success: boolean;
211
+ error?: string;
212
+ }>;
213
+ /**
214
+ * Get connection status and recommendations
215
+ */
216
+ getConnectionStatus(): {
217
+ blocked: boolean;
218
+ recommendations: string[];
219
+ };
166
220
  }
167
221
 
168
222
  declare const MAX_CHUNK_SIZE_BYTES: number;
@@ -183,13 +237,7 @@ declare class HumanBehaviorAPI {
183
237
  sendEventsChunked(events: any[], sessionId: string): Promise<any[]>;
184
238
  sendUserData(userId: string, userData: Record<string, any>, sessionId: string): Promise<any>;
185
239
  sendUserAuth(userId: string, userData: Record<string, any>, sessionId: string, authFields: string[]): Promise<any>;
186
- sendSessionComplete(sessionId: string): Promise<void>;
187
- sendCustomEvent(eventName: string, eventProperties: Record<string, any>, sessionId: string): Promise<any>;
188
- sendCustomEvents(events: any[], sessionId: string): Promise<any>;
189
- sendBeaconEvents(events: any[], sessionId: string, isSessionComplete?: boolean): void;
190
- sendBeaconSessionComplete(sessionId: string): void;
191
- sendBeaconCustomEvent(eventName: string, eventProperties: Record<string, any>, sessionId: string): boolean;
192
- sendBeaconCustomEvents(events: any[], sessionId: string): boolean;
240
+ sendBeaconEvents(events: any[], sessionId: string): void;
193
241
  }
194
242
 
195
243
  declare enum LogLevel {
@@ -1,19 +1,18 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { HumanBehaviorTracker } from '..';
3
+ export { HumanBehaviorTracker } from '..';
3
4
 
4
- interface HumanBehaviorInterface {
5
- addEvent: (event: any) => void;
6
- addUserInfo: (userProperties: Record<string, any>) => Promise<void>;
7
- start: () => void;
8
- stop: () => void;
9
- viewLogs: () => void;
10
- }
11
5
  interface HumanBehaviorProviderProps {
12
6
  apiKey?: string;
13
7
  client?: HumanBehaviorTracker;
14
8
  children: ReactNode;
9
+ options?: {
10
+ ingestionUrl?: string;
11
+ logLevel?: 'none' | 'error' | 'warn' | 'info' | 'debug';
12
+ redactFields?: string[];
13
+ };
15
14
  }
16
- declare const HumanBehaviorProvider: ({ apiKey, client, children }: HumanBehaviorProviderProps) => React.JSX.Element;
17
- declare const useHumanBehavior: () => HumanBehaviorInterface;
15
+ declare const HumanBehaviorProvider: ({ apiKey, client, children, options }: HumanBehaviorProviderProps) => React.JSX.Element;
16
+ declare const useHumanBehavior: () => HumanBehaviorTracker;
18
17
 
19
18
  export { HumanBehaviorProvider, useHumanBehavior };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanbehavior-js",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "description": "SDK for HumanBehavior session and event recording",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -29,6 +29,7 @@
29
29
  "license": "ISC",
30
30
  "dependencies": {
31
31
  "@types/react": "^19.0.12",
32
+ "humanbehavior-js": "^0.0.9",
32
33
  "react": "^19.0.0",
33
34
  "rrweb": "^2.0.0-alpha.4",
34
35
  "uuid": "^11.1.0"
package/readme.md CHANGED
@@ -1,145 +1,167 @@
1
1
  # HumanBehavior SDK
2
2
 
3
- A JavaScript SDK for session recording and user behavior analytics.
3
+ A simplified session recording and analytics SDK that maintains session continuity across page navigations.
4
4
 
5
- ## Installation
5
+ ## Quick Start
6
6
 
7
- ```bash
8
- npm install humanbehavior-js
7
+ ### Single Page Application (Recommended)
8
+
9
+ For the best session continuity experience, use the SPA approach:
10
+
11
+ ```html
12
+ <!DOCTYPE html>
13
+ <html>
14
+ <head>
15
+ <script src="dist/index.min.js"></script>
16
+ </head>
17
+ <body>
18
+ <script>
19
+ // Initialize once - session persists across all navigation
20
+ const tracker = HumanBehaviorTracker.init('your-api-key', {
21
+ logLevel: 'debug',
22
+ redactFields: ['password', 'credit_card']
23
+ });
24
+
25
+ // Your SPA navigation logic here
26
+ function navigateToPage(page) {
27
+ // Update content without page reload
28
+ loadPageContent(page);
29
+
30
+ // Track navigation
31
+ tracker.trackNavigationEvent('spa_navigation', currentPage, page);
32
+ }
33
+ </script>
34
+ </body>
35
+ </html>
9
36
  ```
10
37
 
11
- ## Usage
38
+ ### Traditional Multi-Page Setup
12
39
 
13
- ### Vanilla JavaScript
40
+ For traditional HTML pages, the tracker will automatically restore sessions:
14
41
 
15
42
  ```html
16
- <script src="https://unpkg.com/humanbehavior-js@0.0.7/dist/index.min.js"></script>
43
+ <!-- index.html -->
44
+ <script src="dist/index.min.js"></script>
17
45
  <script>
18
- const tracker = new HumanBehaviorTracker("your-api-key-here");
19
- tracker.start();
20
-
21
- // Set up redaction for sensitive fields
22
- tracker.setRedactedFields(['#password', 'input[type="password"]']);
46
+ const tracker = HumanBehaviorTracker.init('your-api-key');
47
+ </script>
48
+
49
+ <!-- about.html -->
50
+ <script src="dist/index.min.js"></script>
51
+ <script>
52
+ const tracker = HumanBehaviorTracker.init('your-api-key'); // Reuses existing session
23
53
  </script>
24
54
  ```
25
55
 
26
- ### Next.js
56
+ ## API Reference
57
+
58
+ ### Initialization
27
59
 
28
- Add the following to your `providers.tsx` file:
60
+ ```javascript
61
+ // Main initialization method
62
+ const tracker = HumanBehaviorTracker.init(apiKey, options);
63
+ ```
29
64
 
30
- ```tsx
31
- "use client"
65
+ **Options:**
66
+ - `ingestionUrl`: Custom ingestion server URL
67
+ - `logLevel`: 'none' | 'error' | 'warn' | 'info' | 'debug'
68
+ - `redactFields`: Array of CSS selectors to redact
32
69
 
33
- import { HumanBehaviorTracker } from "humanbehavior-js";
34
- import { HumanBehaviorProvider } from "humanbehavior-js/react";
35
- import { useEffect, useState } from "react";
70
+ ### Session Management
36
71
 
37
- export function HumanBehaviorProviderWrapper({ children }: { children: React.ReactNode }) {
38
- const [tracker, setTracker] = useState<HumanBehaviorTracker | null>(null);
72
+ ```javascript
73
+ // Get current session ID
74
+ const sessionId = tracker.getSessionId();
39
75
 
40
- useEffect(() => {
41
- const apiKey = process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY;
42
- if (apiKey) {
43
- const tracker = new HumanBehaviorTracker(apiKey);
44
- setTracker(tracker);
45
- }
46
- }, []);
47
-
48
- return (
49
- <HumanBehaviorProvider client={tracker}>
50
- {children}
51
- </HumanBehaviorProvider>
52
- )
53
- }
76
+ // Get current URL
77
+ const currentUrl = tracker.getCurrentUrl();
78
+
79
+ // Test connection to ingestion server
80
+ const result = await tracker.testConnection();
54
81
  ```
55
82
 
56
- Or use the simpler approach with just an API key:
83
+ ### Event Tracking
57
84
 
58
- ```tsx
59
- "use client"
85
+ ```javascript
86
+ // Track custom events
87
+ await tracker.customEvent('button_click', { button: 'submit' });
60
88
 
61
- import { HumanBehaviorProvider } from "humanbehavior-js/react";
89
+ // Track page views
90
+ await tracker.trackPageView();
62
91
 
63
- export function HumanBehaviorProviderWrapper({ children }: { children: React.ReactNode }) {
64
- return (
65
- <HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
66
- {children}
67
- </HumanBehaviorProvider>
68
- )
69
- }
92
+ // Track navigation (for SPAs)
93
+ await tracker.trackNavigationEvent('pushState', '/home', '/about');
70
94
  ```
71
95
 
72
- Next, add the provider to your root app layout:
73
-
74
- ```tsx
75
- export default async function RootLayout({
76
- children
77
- }: {
78
- children: React.ReactNode;
79
- }) {
80
- return (
81
- <html lang='en' suppressHydrationWarning>
82
- <body>
83
- <HumanBehaviorProviderWrapper>
84
- {children}
85
- </HumanBehaviorProviderWrapper>
86
- </body>
87
- </html>
88
- );
89
- }
90
- ```
96
+ ### Data Redaction
91
97
 
92
- ### Using the Hook
98
+ ```javascript
99
+ // Redact sensitive fields
100
+ tracker.setRedactedFields(['input[type="password"]', '#email']);
93
101
 
94
- In any component within the provider:
102
+ // Check if redaction is active
103
+ const isActive = tracker.isRedactedFields();
104
+ ```
95
105
 
96
- ```tsx
97
- import { useHumanBehavior } from "humanbehavior-js/react";
106
+ ### Debugging
98
107
 
99
- export function MyComponent() {
100
- const humanBehavior = useHumanBehavior();
101
-
102
- const handleUserAction = async () => {
103
- // Add user information
104
- await humanBehavior.addUserInfo({
105
- email: "user@example.com",
106
- name: "John Doe"
107
- });
108
-
109
- // Track custom events
110
- humanBehavior.addEvent({
111
- type: "custom",
112
- name: "button_clicked",
113
- data: { buttonId: "submit" }
114
- });
115
- };
116
-
117
- return <button onClick={handleUserAction}>Click me</button>;
118
- }
108
+ ```javascript
109
+ // View logs
110
+ tracker.viewLogs();
111
+
112
+ // Get connection status
113
+ const status = tracker.getConnectionStatus();
119
114
  ```
120
115
 
121
- ## Environment Variables
116
+ ## Session Continuity
122
117
 
123
- For security, store your API key in environment variables:
118
+ The SDK automatically handles session continuity:
124
119
 
125
- ```bash
126
- # .env.local
127
- NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY=your-api-key-here
128
- NEXT_PUBLIC_INGESTION_URL=https://ingestion.humanbehavior.ai
129
- ```
120
+ 1. **Session Restoration**: Automatically restores sessions within 30 minutes
121
+ 2. **Activity Tracking**: Updates activity timestamp on user interactions
122
+ 3. **Cross-Page Persistence**: Session persists across page navigations
123
+
124
+ ## Demo
125
+
126
+ Check out `simple-spa.html` for a complete single-page application demo that shows:
127
+
128
+ - True session continuity across navigation
129
+ - Interactive event tracking
130
+ - Real-time status updates
131
+ - Modern UI with smooth transitions
130
132
 
131
- ## Features
133
+ ## Troubleshooting
132
134
 
133
- - **Session Recording**: Automatic recording of user interactions
134
- - **Data Redaction**: Protect sensitive information in recordings
135
- - **User Identification**: Track users across sessions
136
- - **Custom Events**: Send custom analytics events
137
- - **React Integration**: Hooks and providers for React applications
135
+ ### Ad Blocker Issues
138
136
 
139
- ## Build
137
+ If you see `net::ERR_BLOCKED_BY_CLIENT` errors:
140
138
 
141
- To build the SDK locally:
139
+ 1. Check if ad blockers are active
140
+ 2. Use `tracker.getConnectionStatus()` to diagnose
141
+ 3. Consider whitelisting your domain
142
+
143
+ ### Session Issues
144
+
145
+ - Sessions automatically expire after 30 minutes of inactivity
146
+ - Each page load calls `/init` but reuses existing sessions when possible
147
+ - Check browser console for session restoration logs
148
+
149
+ ## Development
142
150
 
143
151
  ```bash
152
+ # Build the SDK
144
153
  npm run build
145
- ```
154
+
155
+ # Watch for changes
156
+ npm run dev
157
+
158
+ # Run tests
159
+ npm test
160
+ ```
161
+
162
+ ## Architecture
163
+
164
+ - **Frontend**: TypeScript SDK with session restoration
165
+ - **Backend**: Node.js ingestion server with Redis storage
166
+ - **Archiver**: Processes completed sessions to S3 and Prisma
167
+ - **Session Continuity**: localStorage + cookie-based session management