@affogatosoftware/recorder 1.3.0 → 1.4.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/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { Recorder, type RecorderSettings } from './recorder/recorder';
1
+ export { Recorder, type RecorderSettings, type CapturedUserIdentity } from './recorder/recorder';
2
2
  export { NetworkRecorder, type NetworkRequest } from './recorder/networkRecorder';
@@ -9,6 +9,7 @@ export declare class Recorder {
9
9
  private capturedSessionId;
10
10
  private pingIntervalMs;
11
11
  private pingTimeout;
12
+ private userIdentity;
12
13
  constructor(window: Window, publicToken: string, userSettings?: Partial<RecorderSettings>);
13
14
  private schedulePing;
14
15
  private ping;
@@ -20,6 +21,15 @@ export declare class Recorder {
20
21
  * Stop all recorders
21
22
  */
22
23
  stop(): void;
24
+ /**
25
+ * Identify the current user with a unique ID
26
+ * @param userId - Unique identifier for the user (e.g., database ID, email)
27
+ * @example
28
+ * recorder.identify('user_123');
29
+ */
30
+ identify(userId: string): void;
31
+ clearUserIdentity(): void;
32
+ private sendUserIdentification;
23
33
  private collectCapturedUserMetadata;
24
34
  }
25
35
  export interface RecorderSettings {
@@ -59,3 +69,6 @@ export interface CapturedUserMetadata {
59
69
  utmContent?: string;
60
70
  utmTerm?: string;
61
71
  }
72
+ export interface CapturedUserIdentity {
73
+ userId: string;
74
+ }
@@ -2,7 +2,7 @@ import { SessionRecorder } from "./sessionRecorder";
2
2
  import { EventRecorder } from "./eventRecorder";
3
3
  import { ErrorRecorder } from "./errorRecorder";
4
4
  import { NetworkRecorder } from "./networkRecorder";
5
- import { post, put } from "../requests";
5
+ import { post, put, patch } from "../requests";
6
6
  import { UAParser } from "ua-parser-js";
7
7
  export class Recorder {
8
8
  window;
@@ -15,6 +15,7 @@ export class Recorder {
15
15
  capturedSessionId = null;
16
16
  pingIntervalMs = 20000;
17
17
  pingTimeout = null;
18
+ userIdentity = null;
18
19
  constructor(window, publicToken, userSettings = {}) {
19
20
  this.window = window;
20
21
  this.publicToken = publicToken;
@@ -61,6 +62,8 @@ export class Recorder {
61
62
  this.schedulePing();
62
63
  const capturedUserMetadata = this.collectCapturedUserMetadata();
63
64
  post(`public/captured-sessions/${this.capturedSessionId}/captured-session/metadata`, capturedUserMetadata, { withCredentials: false });
65
+ // Send user identification if it was set before session creation
66
+ this.sendUserIdentification(this.capturedSessionId, this.userIdentity);
64
67
  })
65
68
  .catch(error => {
66
69
  console.error(error);
@@ -98,6 +101,42 @@ export class Recorder {
98
101
  this.errorRecorder.stop();
99
102
  this.networkRecorder.stop();
100
103
  }
104
+ /**
105
+ * Identify the current user with a unique ID
106
+ * @param userId - Unique identifier for the user (e.g., database ID, email)
107
+ * @example
108
+ * recorder.identify('user_123');
109
+ */
110
+ identify(userId) {
111
+ if (!userId || userId.trim() === '') {
112
+ console.error('Recorder.identify: userId must be a non-empty string');
113
+ return;
114
+ }
115
+ this.userIdentity = {
116
+ userId: userId.trim()
117
+ };
118
+ // If session is already created, send identification immediately
119
+ this.sendUserIdentification(this.capturedSessionId, this.userIdentity);
120
+ // If not, identification will be sent when session is created
121
+ }
122
+ clearUserIdentity() {
123
+ this.userIdentity = null;
124
+ }
125
+ async sendUserIdentification(capturedSessionId, userIdentity) {
126
+ if (!capturedSessionId || !userIdentity) {
127
+ return;
128
+ }
129
+ try {
130
+ const response = await patch(`public/captured-sessions/${capturedSessionId}/identify`, userIdentity.userId, { withCredentials: false });
131
+ if (response.status >= 400) {
132
+ console.error(`Failed to identify user: HTTP ${response.status}`, response.data);
133
+ }
134
+ }
135
+ catch (error) {
136
+ console.error("Error sending user identification:", error);
137
+ // Identification failure is non-critical - recording should continue
138
+ }
139
+ }
101
140
  collectCapturedUserMetadata = () => {
102
141
  const ua = new UAParser();
103
142
  const browserName = ua.getBrowser().name;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@affogatosoftware/recorder",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "license": "MIT",
5
5
  "author": "Chris Ryan",
6
6
  "main": "./dist/index.js",