humanbehavior-js 0.0.5 → 0.0.8

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.
@@ -1,3 +1,85 @@
1
+ interface RedactionOptions {
2
+ redactedText?: string;
3
+ excludeSelectors?: string[];
4
+ userFields?: string[];
5
+ }
6
+ declare class RedactionManager {
7
+ private redactedText;
8
+ private userSelectedFields;
9
+ private excludeSelectors;
10
+ constructor(options?: RedactionOptions);
11
+ /**
12
+ * Set specific fields to be redacted
13
+ * @param fields Array of CSS selectors for fields to redact
14
+ */
15
+ setFieldsToRedact(fields: string[]): void;
16
+ /**
17
+ * Check if redaction is currently active (has fields selected)
18
+ */
19
+ isActive(): boolean;
20
+ /**
21
+ * Get the currently selected fields for redaction
22
+ */
23
+ getSelectedFields(): string[];
24
+ /**
25
+ * Process an event and redact sensitive data if needed
26
+ */
27
+ processEvent(event: any): any;
28
+ /**
29
+ * Redact sensitive data in input events
30
+ */
31
+ private redactInputEvent;
32
+ /**
33
+ * Redact sensitive data in DOM mutation events
34
+ */
35
+ private redactDOMEvent;
36
+ /**
37
+ * Check if a DOM change should be redacted based on its ID
38
+ */
39
+ private shouldRedactDOMChange;
40
+ /**
41
+ * Redact sensitive data in mouse/touch interaction events
42
+ */
43
+ private redactMouseEvent;
44
+ /**
45
+ * Redact sensitive data in full snapshot events
46
+ */
47
+ private redactFullSnapshot;
48
+ /**
49
+ * Recursively redact sensitive data in DOM nodes
50
+ */
51
+ private redactNode;
52
+ /**
53
+ * Check if a node should be redacted based on its attributes
54
+ */
55
+ private shouldRedactNode;
56
+ /**
57
+ * Check if a CSS selector would match a node based on its attributes
58
+ */
59
+ private selectorMatchesNode;
60
+ /**
61
+ * Basic selector matching for environments where matches() is not available
62
+ */
63
+ private basicSelectorMatch;
64
+ /**
65
+ * Check if an event is from a field that should be redacted
66
+ */
67
+ private isFieldSelected;
68
+ /**
69
+ * Check if an element should be redacted based on user-selected fields
70
+ */
71
+ private shouldRedactElement;
72
+ /**
73
+ * Get the original value of a redacted element (for debugging)
74
+ */
75
+ getOriginalValue(element: HTMLElement): string | undefined;
76
+ /**
77
+ * Check if an element is currently being redacted
78
+ */
79
+ isElementRedacted(element: HTMLElement): boolean;
80
+ }
81
+ declare const redactionManager: RedactionManager;
82
+
1
83
  declare global {
2
84
  interface Window {
3
85
  HumanBehaviorTracker: typeof HumanBehaviorTracker;
@@ -18,13 +100,19 @@ declare class HumanBehaviorTracker {
18
100
  private apiKey;
19
101
  private initialized;
20
102
  initializationPromise: Promise<void> | null;
21
- constructor(apiKey: string | undefined, ingestionUrl: string | undefined);
103
+ private redactionManager;
104
+ constructor(apiKey: string | undefined, ingestionUrl?: string);
22
105
  private init;
23
106
  private ensureInitialized;
24
107
  static logToStorage(message: string): void;
25
108
  private setupPageUnloadHandler;
26
109
  viewLogs(): void;
27
- identifyUser(userProperties: Record<string, any>): Promise<void>;
110
+ addUserInfo(userProperties: Record<string, any>): Promise<void>;
111
+ /**
112
+ * Authenticate user using existing userInfo data
113
+ * @param authFields Array of field names to check for existing users (e.g., ['email', 'phoneNumber'])
114
+ */
115
+ auth(authFields: string[]): Promise<void>;
28
116
  customEvent(eventName: string, eventProperties?: Record<string, any>): Promise<void>;
29
117
  start(): Promise<void>;
30
118
  stop(): Promise<void>;
@@ -33,6 +121,24 @@ declare class HumanBehaviorTracker {
33
121
  private flush;
34
122
  private setCookie;
35
123
  private getCookie;
124
+ /**
125
+ * Start redaction functionality for sensitive input fields
126
+ * @param options Optional configuration for redaction behavior
127
+ */
128
+ redact(options?: RedactionOptions): Promise<void>;
129
+ /**
130
+ * Set specific fields to be redacted during session recording
131
+ * @param fields Array of CSS selectors for fields to redact (e.g., ['input[type="password"]', '#email-field'])
132
+ */
133
+ setRedactedFields(fields: string[]): void;
134
+ /**
135
+ * Check if redaction is currently active
136
+ */
137
+ isRedactionActive(): boolean;
138
+ /**
139
+ * Get the currently selected fields for redaction
140
+ */
141
+ getRedactedFields(): string[];
36
142
  }
37
143
 
38
144
  declare const MAX_CHUNK_SIZE_BYTES: number;
@@ -52,6 +158,7 @@ declare class HumanBehaviorAPI {
52
158
  sendEvents(events: any[], sessionId: string, userId: string): Promise<void>;
53
159
  sendEventsChunked(events: any[], sessionId: string): Promise<any[]>;
54
160
  sendUserData(userId: string, userData: Record<string, any>, sessionId: string): Promise<any>;
161
+ sendUserAuth(userId: string, userData: Record<string, any>, sessionId: string, authFields: string[]): Promise<any>;
55
162
  sendSessionComplete(sessionId: string): Promise<void>;
56
163
  sendCustomEvent(eventName: string, eventProperties: Record<string, any>, sessionId: string): Promise<any>;
57
164
  sendCustomEvents(events: any[], sessionId: string): Promise<any>;
@@ -61,4 +168,5 @@ declare class HumanBehaviorAPI {
61
168
  sendBeaconCustomEvents(events: any[], sessionId: string): boolean;
62
169
  }
63
170
 
64
- export { HumanBehaviorAPI, HumanBehaviorTracker, MAX_CHUNK_SIZE_BYTES, HumanBehaviorTracker as default, isChunkSizeExceeded, validateSingleEventSize };
171
+ export { HumanBehaviorAPI, HumanBehaviorTracker, MAX_CHUNK_SIZE_BYTES, RedactionManager, HumanBehaviorTracker as default, isChunkSizeExceeded, redactionManager, validateSingleEventSize };
172
+ export type { RedactionOptions };
@@ -3,7 +3,7 @@ import { HumanBehaviorTracker } from '..';
3
3
 
4
4
  interface HumanBehaviorInterface {
5
5
  addEvent: (event: any) => void;
6
- identifyUser: (userProperties: Record<string, any>) => Promise<void>;
6
+ addUserInfo: (userProperties: Record<string, any>) => Promise<void>;
7
7
  start: () => void;
8
8
  stop: () => void;
9
9
  viewLogs: () => void;
package/package.json CHANGED
@@ -1,19 +1,12 @@
1
1
  {
2
2
  "name": "humanbehavior-js",
3
- "version": "0.0.5",
3
+ "version": "0.0.8",
4
4
  "description": "SDK for HumanBehavior session and event recording",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
7
7
  "module": "./dist/esm/index.js",
8
8
  "types": "./dist/types/index.d.ts",
9
9
  "unpkg": "dist/index.min.js",
10
- "files": [
11
- "dist",
12
- "react.js",
13
- "react.d.ts",
14
- "index.js",
15
- "index.d.ts"
16
- ],
17
10
  "exports": {
18
11
  ".": {
19
12
  "import": "./dist/esm/index.js",
@@ -45,15 +38,11 @@
45
38
  "@rollup/plugin-node-resolve": "^16.0.1",
46
39
  "@rollup/plugin-terser": "^0.4.4",
47
40
  "@rollup/plugin-typescript": "^12.1.2",
48
- "@types/cors": "^2.8.17",
49
- "@types/express": "^5.0.1",
41
+ "@types/node": "^24.0.3",
50
42
  "rollup": "^4.36.0",
51
43
  "rollup-plugin-dts": "^6.2.1",
52
- "ts-loader": "^9.5.2",
53
44
  "tslib": "^2.8.1",
54
- "typescript": "^5.8.2",
55
- "webpack": "^5.98.0",
56
- "webpack-cli": "^6.0.1"
45
+ "typescript": "^5.8.2"
57
46
  },
58
47
  "publishConfig": {
59
48
  "access": "public"
package/readme.md CHANGED
@@ -1,57 +1,145 @@
1
- To build, run `npm run build`
1
+ # HumanBehavior SDK
2
2
 
3
+ A JavaScript SDK for session recording and user behavior analytics.
3
4
 
4
- Usage:
5
+ ## Installation
5
6
 
6
- NextJS
7
+ ```bash
8
+ npm install humanbehavior-js
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Vanilla JavaScript
14
+
15
+ ```html
16
+ <script src="https://unpkg.com/humanbehavior-js@0.0.7/dist/index.min.js"></script>
17
+ <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"]']);
23
+ </script>
24
+ ```
7
25
 
8
- Add the following to your `providers.tsx` file.
9
- ```ts
26
+ ### Next.js
27
+
28
+ Add the following to your `providers.tsx` file:
29
+
30
+ ```tsx
10
31
  "use client"
11
32
 
12
- import { KoalawareTracker } from "koalaware-js";
13
- import { KoalawareProvider as KoalawareProviderJS } from "koalaware-js/react";
33
+ import { HumanBehaviorTracker } from "humanbehavior-js";
34
+ import { HumanBehaviorProvider } from "humanbehavior-js/react";
14
35
  import { useEffect, useState } from "react";
15
36
 
16
- export function KoalawareProvider({ children }: { children: React.ReactNode }) {
17
- const [koalaware, setKoalaware] = useState<KoalawareTracker | null>(null);
37
+ export function HumanBehaviorProviderWrapper({ children }: { children: React.ReactNode }) {
38
+ const [tracker, setTracker] = useState<HumanBehaviorTracker | null>(null);
18
39
 
19
40
  useEffect(() => {
20
- const apiKey = "kw_1c8969a408ea2eb333fd174a7684c7c943e82ea1df8349b43640e4b608f35e68";
21
- const koalaware = new KoalawareTracker(apiKey);
22
- setKoalaware(koalaware);
41
+ const apiKey = process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY;
42
+ if (apiKey) {
43
+ const tracker = new HumanBehaviorTracker(apiKey);
44
+ setTracker(tracker);
45
+ }
23
46
  }, []);
24
47
 
25
48
  return (
26
- <KoalawareProviderJS client={koalaware}>
49
+ <HumanBehaviorProvider client={tracker}>
50
+ {children}
51
+ </HumanBehaviorProvider>
52
+ )
53
+ }
54
+ ```
55
+
56
+ Or use the simpler approach with just an API key:
57
+
58
+ ```tsx
59
+ "use client"
60
+
61
+ import { HumanBehaviorProvider } from "humanbehavior-js/react";
62
+
63
+ export function HumanBehaviorProviderWrapper({ children }: { children: React.ReactNode }) {
64
+ return (
65
+ <HumanBehaviorProvider apiKey={process.env.NEXT_PUBLIC_HUMANBEHAVIOR_API_KEY}>
27
66
  {children}
28
- </KoalawareProviderJS>
67
+ </HumanBehaviorProvider>
29
68
  )
30
69
  }
31
70
  ```
32
71
 
33
- Next, add the provider to your root app layout.
34
- ```ts
72
+ Next, add the provider to your root app layout:
73
+
74
+ ```tsx
35
75
  export default async function RootLayout({
36
76
  children
37
77
  }: {
38
78
  children: React.ReactNode;
39
79
  }) {
40
- const session = await auth();
41
80
  return (
42
- <html lang='en' className={`${lato.className}`} suppressHydrationWarning>
43
- <body className={'overflow-hidden'}>
44
- <NextTopLoader showSpinner={false} />
45
- <KoalawareProvider>
46
- <NuqsAdapter>
47
- <Providers session={session}>
48
- <Toaster />
49
- {children}
50
- </Providers>
51
- </NuqsAdapter>
52
- </KoalawareProvider>
81
+ <html lang='en' suppressHydrationWarning>
82
+ <body>
83
+ <HumanBehaviorProviderWrapper>
84
+ {children}
85
+ </HumanBehaviorProviderWrapper>
53
86
  </body>
54
87
  </html>
55
88
  );
56
89
  }
90
+ ```
91
+
92
+ ### Using the Hook
93
+
94
+ In any component within the provider:
95
+
96
+ ```tsx
97
+ import { useHumanBehavior } from "humanbehavior-js/react";
98
+
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
+ }
119
+ ```
120
+
121
+ ## Environment Variables
122
+
123
+ For security, store your API key in environment variables:
124
+
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
+ ```
130
+
131
+ ## Features
132
+
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
138
+
139
+ ## Build
140
+
141
+ To build the SDK locally:
142
+
143
+ ```bash
144
+ npm run build
57
145
  ```
@@ -0,0 +1,106 @@
1
+ import typescript from '@rollup/plugin-typescript';
2
+ import resolve from '@rollup/plugin-node-resolve';
3
+ import commonjs from '@rollup/plugin-commonjs';
4
+ import terser from '@rollup/plugin-terser';
5
+ import dts from 'rollup-plugin-dts';
6
+
7
+ // Only React should be external since it's typically provided by the host application
8
+ const external = ['react', 'react-dom'];
9
+
10
+ // Global variables for UMD build
11
+ const globals = {
12
+ react: 'React',
13
+ 'react-dom': 'ReactDOM'
14
+ };
15
+
16
+ export default [
17
+ // Main SDK bundle
18
+ {
19
+ input: 'src/index.ts',
20
+ output: [
21
+ {
22
+ file: 'dist/cjs/index.js',
23
+ format: 'cjs',
24
+ name: 'HumanBehaviorTracker',
25
+ globals,
26
+ exports: 'named',
27
+ sourcemap: true
28
+ },
29
+ {
30
+ file: 'dist/esm/index.js',
31
+ format: 'es',
32
+ sourcemap: true
33
+ },
34
+ {
35
+ file: 'dist/index.min.js',
36
+ format: 'umd',
37
+ name: 'HumanBehaviorTracker',
38
+ globals,
39
+ exports: 'auto',
40
+ sourcemap: true,
41
+ plugins: [terser()]
42
+ }
43
+ ],
44
+ plugins: [
45
+ resolve(),
46
+ commonjs(),
47
+ typescript({
48
+ tsconfig: './tsconfig.json',
49
+ declaration: false
50
+ })
51
+ ],
52
+ external
53
+ },
54
+
55
+ // React component bundle
56
+ {
57
+ input: './src/react/index.tsx',
58
+ output: [
59
+ {
60
+ file: 'dist/cjs/react/index.js',
61
+ format: 'cjs',
62
+ name: 'HumanBehaviorReact',
63
+ globals: {
64
+ ...globals,
65
+ '..': 'HumanBehaviorTracker'
66
+ },
67
+ exports: 'named',
68
+ sourcemap: true
69
+ },
70
+ {
71
+ file: 'dist/esm/react/index.js',
72
+ format: 'es',
73
+ sourcemap: true
74
+ }
75
+ ],
76
+ plugins: [
77
+ resolve(),
78
+ commonjs(),
79
+ typescript({
80
+ tsconfig: './tsconfig.json',
81
+ declaration: false
82
+ })
83
+ ],
84
+ external: [...external, '..']
85
+ },
86
+
87
+ // Type definition bundles - generate these separately
88
+ {
89
+ input: 'src/index.ts',
90
+ output: {
91
+ file: 'dist/types/index.d.ts',
92
+ format: 'es'
93
+ },
94
+ plugins: [dts()],
95
+ external
96
+ },
97
+ {
98
+ input: 'src/react/index.tsx',
99
+ output: {
100
+ file: 'dist/types/react/index.d.ts',
101
+ format: 'es'
102
+ },
103
+ plugins: [dts()],
104
+ external: [...external, '..']
105
+ }
106
+ ];