humanbehavior-js 0.1.1 → 0.1.3

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/esm/index.js CHANGED
@@ -4364,6 +4364,57 @@ class HumanBehaviorAPI {
4364
4364
  data.append('apiKey', encodeURIComponent(this.apiKey));
4365
4365
  navigator.sendBeacon(`${this.baseUrl}/api/ingestion/events`, data);
4366
4366
  }
4367
+ sendCustomEvent(sessionId, eventName, eventProperties) {
4368
+ return __awaiter$1(this, void 0, void 0, function* () {
4369
+ try {
4370
+ const response = yield fetch(`${this.baseUrl}/api/ingestion/customEvent`, {
4371
+ method: 'POST',
4372
+ headers: {
4373
+ 'Content-Type': 'application/json',
4374
+ 'Authorization': `Bearer ${this.apiKey}`
4375
+ },
4376
+ body: JSON.stringify({
4377
+ sessionId: sessionId,
4378
+ eventName: eventName,
4379
+ eventProperties: eventProperties || {}
4380
+ })
4381
+ });
4382
+ if (!response.ok) {
4383
+ throw new Error(`Failed to send custom event: ${response.statusText}`);
4384
+ }
4385
+ return yield response.json();
4386
+ }
4387
+ catch (error) {
4388
+ logError('Error sending custom event:', error);
4389
+ throw error;
4390
+ }
4391
+ });
4392
+ }
4393
+ sendCustomEventBatch(sessionId, events) {
4394
+ return __awaiter$1(this, void 0, void 0, function* () {
4395
+ try {
4396
+ const response = yield fetch(`${this.baseUrl}/api/ingestion/customEvent/batch`, {
4397
+ method: 'POST',
4398
+ headers: {
4399
+ 'Content-Type': 'application/json',
4400
+ 'Authorization': `Bearer ${this.apiKey}`
4401
+ },
4402
+ body: JSON.stringify({
4403
+ sessionId: sessionId,
4404
+ events: events
4405
+ })
4406
+ });
4407
+ if (!response.ok) {
4408
+ throw new Error(`Failed to send custom event batch: ${response.statusText}`);
4409
+ }
4410
+ return yield response.json();
4411
+ }
4412
+ catch (error) {
4413
+ logError('Error sending custom event batch:', error);
4414
+ throw error;
4415
+ }
4416
+ });
4417
+ }
4367
4418
  }
4368
4419
 
4369
4420
  // Redaction functionality for sensitive input fields
@@ -4802,6 +4853,10 @@ class HumanBehaviorTracker {
4802
4853
  if (options === null || options === void 0 ? void 0 : options.redactFields) {
4803
4854
  tracker.setRedactedFields(options.redactFields);
4804
4855
  }
4856
+ // Setup automatic tracking if enabled
4857
+ if ((options === null || options === void 0 ? void 0 : options.enableAutomaticTracking) !== false) {
4858
+ tracker.setupAutomaticTracking(options === null || options === void 0 ? void 0 : options.automaticTrackingOptions);
4859
+ }
4805
4860
  // Test connection (non-blocking)
4806
4861
  if (isBrowser) {
4807
4862
  const testUrl = tracker.api['baseUrl'] + '/api/health';
@@ -5050,28 +5105,159 @@ class HumanBehaviorTracker {
5050
5105
  if (!this.initialized)
5051
5106
  return;
5052
5107
  try {
5053
- const customEventData = {
5054
- eventName: eventName,
5055
- properties: properties || {},
5056
- timestamp: new Date().toISOString(),
5057
- url: window.location.href,
5058
- pathname: window.location.pathname
5059
- };
5060
- // Add custom event to the main event stream
5061
- yield this.addEvent({
5062
- type: 5, // Custom event type
5063
- data: {
5064
- payload: Object.assign({ eventType: 'custom' }, customEventData)
5065
- },
5066
- timestamp: Date.now()
5067
- });
5108
+ // Send custom event directly to the API
5109
+ yield this.api.sendCustomEvent(this.sessionId, eventName, properties);
5068
5110
  logDebug(`Custom event tracked: ${eventName}`, properties);
5069
5111
  }
5070
5112
  catch (error) {
5071
5113
  logError('Failed to track custom event:', error);
5114
+ // Fallback: add to event stream if direct API call fails
5115
+ try {
5116
+ const customEventData = {
5117
+ eventName: eventName,
5118
+ properties: properties || {},
5119
+ timestamp: new Date().toISOString(),
5120
+ url: window.location.href,
5121
+ pathname: window.location.pathname
5122
+ };
5123
+ yield this.addEvent({
5124
+ type: 5, // Custom event type
5125
+ data: {
5126
+ payload: Object.assign({ eventType: 'custom' }, customEventData)
5127
+ },
5128
+ timestamp: Date.now()
5129
+ });
5130
+ logDebug(`Custom event added to event stream as fallback: ${eventName}`);
5131
+ }
5132
+ catch (fallbackError) {
5133
+ logError('Failed to add custom event to event stream as fallback:', fallbackError);
5134
+ }
5072
5135
  }
5073
5136
  });
5074
5137
  }
5138
+ /**
5139
+ * Setup automatic tracking for buttons, links, and forms
5140
+ */
5141
+ setupAutomaticTracking(options) {
5142
+ if (!isBrowser)
5143
+ return;
5144
+ const config = {
5145
+ trackButtons: (options === null || options === void 0 ? void 0 : options.trackButtons) !== false,
5146
+ trackLinks: (options === null || options === void 0 ? void 0 : options.trackLinks) !== false,
5147
+ trackForms: (options === null || options === void 0 ? void 0 : options.trackForms) !== false,
5148
+ includeText: (options === null || options === void 0 ? void 0 : options.includeText) !== false,
5149
+ includeClasses: (options === null || options === void 0 ? void 0 : options.includeClasses) || false
5150
+ };
5151
+ logDebug('Setting up automatic tracking with config:', config);
5152
+ // Setup button tracking
5153
+ if (config.trackButtons) {
5154
+ this.setupAutomaticButtonTracking(config);
5155
+ }
5156
+ // Setup link tracking
5157
+ if (config.trackLinks) {
5158
+ this.setupAutomaticLinkTracking(config);
5159
+ }
5160
+ // Setup form tracking
5161
+ if (config.trackForms) {
5162
+ this.setupAutomaticFormTracking(config);
5163
+ }
5164
+ }
5165
+ /**
5166
+ * Setup automatic button tracking
5167
+ */
5168
+ setupAutomaticButtonTracking(config) {
5169
+ document.addEventListener('click', (event) => __awaiter$1(this, void 0, void 0, function* () {
5170
+ var _a;
5171
+ const target = event.target;
5172
+ // Track button clicks
5173
+ if (target.tagName === 'BUTTON' || target.closest('button')) {
5174
+ const button = target.tagName === 'BUTTON'
5175
+ ? target
5176
+ : target.closest('button');
5177
+ const properties = {
5178
+ buttonId: button.id || null,
5179
+ buttonType: button.type || 'button',
5180
+ page: window.location.pathname,
5181
+ timestamp: Date.now()
5182
+ };
5183
+ if (config.includeText) {
5184
+ properties.buttonText = ((_a = button.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || null;
5185
+ }
5186
+ if (config.includeClasses) {
5187
+ properties.buttonClass = button.className || null;
5188
+ }
5189
+ // Remove null values
5190
+ Object.keys(properties).forEach(key => {
5191
+ if (properties[key] === null) {
5192
+ delete properties[key];
5193
+ }
5194
+ });
5195
+ yield this.customEvent('button_clicked', properties);
5196
+ }
5197
+ }));
5198
+ }
5199
+ /**
5200
+ * Setup automatic link tracking
5201
+ */
5202
+ setupAutomaticLinkTracking(config) {
5203
+ document.addEventListener('click', (event) => __awaiter$1(this, void 0, void 0, function* () {
5204
+ var _a;
5205
+ const target = event.target;
5206
+ // Track link clicks
5207
+ if (target.tagName === 'A' || target.closest('a')) {
5208
+ const link = target.tagName === 'A'
5209
+ ? target
5210
+ : target.closest('a');
5211
+ const properties = {
5212
+ linkUrl: link.href || null,
5213
+ linkId: link.id || null,
5214
+ linkTarget: link.target || null,
5215
+ page: window.location.pathname,
5216
+ timestamp: Date.now()
5217
+ };
5218
+ if (config.includeText) {
5219
+ properties.linkText = ((_a = link.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || null;
5220
+ }
5221
+ if (config.includeClasses) {
5222
+ properties.linkClass = link.className || null;
5223
+ }
5224
+ // Remove null values
5225
+ Object.keys(properties).forEach(key => {
5226
+ if (properties[key] === null) {
5227
+ delete properties[key];
5228
+ }
5229
+ });
5230
+ yield this.customEvent('link_clicked', properties);
5231
+ }
5232
+ }));
5233
+ }
5234
+ /**
5235
+ * Setup automatic form tracking
5236
+ */
5237
+ setupAutomaticFormTracking(config) {
5238
+ document.addEventListener('submit', (event) => __awaiter$1(this, void 0, void 0, function* () {
5239
+ const form = event.target;
5240
+ const formData = new FormData(form);
5241
+ const properties = {
5242
+ formId: form.id || null,
5243
+ formAction: form.action || null,
5244
+ formMethod: form.method || 'get',
5245
+ fields: Array.from(formData.keys()),
5246
+ page: window.location.pathname,
5247
+ timestamp: Date.now()
5248
+ };
5249
+ if (config.includeClasses) {
5250
+ properties.formClass = form.className || null;
5251
+ }
5252
+ // Remove null values
5253
+ Object.keys(properties).forEach(key => {
5254
+ if (properties[key] === null) {
5255
+ delete properties[key];
5256
+ }
5257
+ });
5258
+ yield this.customEvent('form_submitted', properties);
5259
+ }));
5260
+ }
5075
5261
  /**
5076
5262
  * Cleanup navigation tracking
5077
5263
  */
@@ -5267,6 +5453,7 @@ class HumanBehaviorTracker {
5267
5453
  inlineStylesheet: true,
5268
5454
  recordCanvas: true,
5269
5455
  collectFonts: true,
5456
+ inlineImages: true,
5270
5457
  blockClass: 'rr-block',
5271
5458
  ignoreClass: 'rr-ignore',
5272
5459
  maskTextClass: 'rr-ignore'