cryptique-sdk 1.2.20 → 1.2.21

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/lib/cjs/index.js CHANGED
@@ -92,8 +92,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
92
92
 
93
93
  // Geolocation API
94
94
  GEOLOCATION: {
95
- PRIMARY_URL: "https://ipinfo.io/json?token=8fc6409059aa39",
96
- BACKUP_URL: "https://ipinfo.io/json?token=8fc6409059aa39&http=1.1",
95
+ PRIMARY_URL: "https://ipinfo.io/json?token=3a0c034aefbef8",
96
+ BACKUP_URL: "https://ipinfo.io/json?token=3a0c034aefbef8&http=1.1",
97
97
  TIMEOUT_MS: 5000 // 5 second timeout
98
98
  },
99
99
 
@@ -1139,7 +1139,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
1139
1139
  isFirstPage: true,
1140
1140
 
1141
1141
  // JSONB fields
1142
- interactions: {},
1143
1142
  visited_pages: [],
1144
1143
 
1145
1144
  // Also stored in locationData object for structured access (backward compatibility)
@@ -2084,7 +2083,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
2084
2083
  if (sessionData.utm_id === undefined) sessionData.utm_id = null;
2085
2084
 
2086
2085
  // JSONB fields
2087
- if (!sessionData.interactions) sessionData.interactions = {};
2088
2086
  if (!sessionData.visited_pages) sessionData.visited_pages = [];
2089
2087
 
2090
2088
  // Internal tracking
@@ -2149,8 +2147,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
2149
2147
  // UTM fields (already snake_case, no mapping needed)
2150
2148
 
2151
2149
  // JSONB fields
2152
- 'visited_pages': 'visited_pages', // Already snake_case
2153
- 'interactions': 'interactions' // Already snake_case
2150
+ 'visited_pages': 'visited_pages' // Already snake_case
2154
2151
  };
2155
2152
 
2156
2153
  return fieldMap[internalName] || this.toSnakeCase(internalName);
@@ -3194,333 +3191,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
3194
3191
  }
3195
3192
  };
3196
3193
 
3197
- // ============================================================================
3198
- // SECTION 10: INTERACTION MANAGEMENT
3199
- // ============================================================================
3200
- // PURPOSE: Single source of truth for interaction tracking and management.
3201
- // Handles all user interactions (clicks, forms, scroll, hover, etc.)
3202
- //
3203
- // KEY PRINCIPLES:
3204
- // 1. All interactions stored in categorized structure
3205
- // 2. Automatic timestamp addition
3206
- // 3. Total interactions count maintained
3207
- // 4. Chronological sorting for backend
3208
- // 5. Immediate session storage updates
3209
- // 6. Prevents duplicate interactions
3210
- //
3211
- // BENEFITS:
3212
- // - Centralized interaction tracking
3213
- // - Consistent data structure
3214
- // - Single place to fix interaction bugs
3215
- // - Prevents repeating interactions
3216
- // ============================================================================
3194
+ // SECTION 10: INTERACTION MANAGEMENT — REMOVED
3195
+ // Interactions JSONB tracking has been removed from sessions.
3196
+ // Important signals (clicks, errors, etc.) are captured as individual
3197
+ // queryable auto events in the events table instead.
3217
3198
 
3218
- /**
3219
- * InteractionManager - Interaction tracking and management
3220
- *
3221
- * This object handles all user interaction tracking, storage, and management
3222
- */
3199
+ // No-op stub — all methods removed with interactions feature.
3223
3200
  const InteractionManager = {
3224
- /**
3225
- * Interaction categories
3226
- *
3227
- * All supported interaction categories
3228
- */
3229
- CATEGORIES: [
3230
- 'clicks',
3231
- 'formInteractions',
3232
- 'mediaInteractions',
3233
- 'scrollEvents',
3234
- 'focusEvents',
3235
- 'hoverEvents',
3236
- 'formSubmissions',
3237
- 'fieldChanges',
3238
- 'validationErrors',
3239
- 'keyboardEvents',
3240
- 'copyPasteEvents',
3241
- 'contextMenuEvents',
3242
- 'dragDropEvents',
3243
- 'touchEvents',
3244
- 'windowEvents',
3245
- 'performanceEvents',
3246
- 'errorEvents',
3247
- 'networkEvents',
3248
- 'formAnalytics'
3249
- ],
3250
-
3251
- /**
3252
- * Initialize interactions structure
3253
- *
3254
- * Creates empty interactions object with all categories
3255
- */
3256
- initialize() {
3257
- if (!sessionData.interactions || Object.keys(sessionData.interactions).length === 0) {
3258
- sessionData.interactions = {
3259
- totalInteractions: 0,
3260
- clicks: [],
3261
- formInteractions: [],
3262
- mediaInteractions: [],
3263
- scrollEvents: [],
3264
- focusEvents: [],
3265
- hoverEvents: [],
3266
- formSubmissions: [],
3267
- fieldChanges: [],
3268
- validationErrors: [],
3269
- keyboardEvents: [],
3270
- copyPasteEvents: [],
3271
- contextMenuEvents: [],
3272
- dragDropEvents: [],
3273
- touchEvents: [],
3274
- windowEvents: [],
3275
- performanceEvents: [],
3276
- errorEvents: [],
3277
- networkEvents: [],
3278
- formAnalytics: []
3279
- };
3280
- }
3281
- },
3282
-
3283
- /**
3284
- * Add interaction to appropriate category
3285
- *
3286
- * Logic:
3287
- * 1. Ensures interactions are initialized
3288
- * 2. Adds timestamp if not provided
3289
- * 3. Adds to specific category array
3290
- * 4. Updates total interactions count
3291
- * 5. Updates session activity
3292
- * 6. Immediately updates session storage
3293
- *
3294
- * Parameters:
3295
- * - category: Interaction category (e.g., 'clicks', 'formInteractions')
3296
- * - interactionData: Interaction data object
3297
- */
3298
- add(category, interactionData) {
3299
- // Ensure interactions are initialized
3300
- this.initialize();
3301
-
3302
- // Validate category
3303
- if (!this.CATEGORIES.includes(category)) {
3304
- return;
3305
- }
3306
-
3307
- // Add timestamp if not provided
3308
- if (!interactionData.timestamp) {
3309
- interactionData.timestamp = nowIso();
3310
- }
3311
-
3312
- // Add to specific category
3313
- if (sessionData.interactions[category]) {
3314
- sessionData.interactions[category].push(interactionData);
3315
- }
3316
-
3317
- // Update total interactions count
3318
- this.updateTotalCount();
3319
-
3320
- // Update last activity
3321
- sessionData.lastActivity = Date.now();
3322
-
3323
- // Immediately update session storage
3324
- this.updateSessionStorage();
3325
- },
3326
-
3327
- /**
3328
- * Update total interactions count
3329
- *
3330
- * Calculates total from all category arrays
3331
- */
3332
- updateTotalCount() {
3333
- if (!sessionData.interactions) return;
3334
-
3335
- let total = 0;
3336
- for (const category of this.CATEGORIES) {
3337
- if (sessionData.interactions[category] && Array.isArray(sessionData.interactions[category])) {
3338
- total += sessionData.interactions[category].length;
3339
- }
3340
- }
3341
-
3342
- sessionData.interactions.totalInteractions = total;
3343
- },
3344
-
3345
- /**
3346
- * Update session storage with interactions
3347
- *
3348
- * Immediately syncs interactions to session storage
3349
- */
3350
- updateSessionStorage() {
3351
- try {
3352
- const storedSession = StorageManager.loadSession();
3353
- if (storedSession && storedSession.sessionData) {
3354
- storedSession.sessionData.interactions = sessionData.interactions;
3355
- StorageManager.saveSession(storedSession);
3356
- }
3357
- } catch (error) {
3358
- }
3359
- },
3360
-
3361
- /**
3362
- * Get all interactions sorted chronologically
3363
- *
3364
- * Collects all interactions from all categories, adds category identifiers,
3365
- * and sorts by timestamp
3366
- *
3367
- * Returns: Array of interactions sorted by timestamp
3368
- */
3369
- getChronological() {
3370
- if (!sessionData.interactions) {
3371
- return [];
3372
- }
3373
-
3374
- const allInteractions = [];
3375
-
3376
- // Map of category to category identifier
3377
- const categoryMap = {
3378
- 'clicks': { category: 'click', originalCategory: 'clicks' },
3379
- 'formInteractions': { category: 'formInteraction', originalCategory: 'formInteractions' },
3380
- 'mediaInteractions': { category: 'mediaInteraction', originalCategory: 'mediaInteractions' },
3381
- 'scrollEvents': { category: 'scrollEvent', originalCategory: 'scrollEvents' },
3382
- 'focusEvents': { category: 'focusEvent', originalCategory: 'focusEvents' },
3383
- 'hoverEvents': { category: 'hoverEvent', originalCategory: 'hoverEvents' },
3384
- 'formSubmissions': { category: 'formSubmission', originalCategory: 'formSubmissions' },
3385
- 'fieldChanges': { category: 'fieldChange', originalCategory: 'fieldChanges' },
3386
- 'validationErrors': { category: 'validationError', originalCategory: 'validationErrors' },
3387
- 'keyboardEvents': { category: 'keyboardEvent', originalCategory: 'keyboardEvents' },
3388
- 'copyPasteEvents': { category: 'copyPasteEvent', originalCategory: 'copyPasteEvents' },
3389
- 'contextMenuEvents': { category: 'contextMenuEvent', originalCategory: 'contextMenuEvents' },
3390
- 'dragDropEvents': { category: 'dragDropEvent', originalCategory: 'dragDropEvents' },
3391
- 'touchEvents': { category: 'touchEvent', originalCategory: 'touchEvents' },
3392
- 'windowEvents': { category: 'windowEvent', originalCategory: 'windowEvents' },
3393
- 'performanceEvents': { category: 'performanceEvent', originalCategory: 'performanceEvents' },
3394
- 'errorEvents': { category: 'errorEvent', originalCategory: 'errorEvents' },
3395
- 'networkEvents': { category: 'networkEvent', originalCategory: 'networkEvents' },
3396
- 'formAnalytics': { category: 'formAnalytic', originalCategory: 'formAnalytics' }
3397
- };
3398
-
3399
- // Collect all interactions from all categories
3400
- for (const category of this.CATEGORIES) {
3401
- if (sessionData.interactions[category] && Array.isArray(sessionData.interactions[category])) {
3402
- const categoryInfo = categoryMap[category];
3403
- sessionData.interactions[category].forEach(interaction => {
3404
- allInteractions.push({
3405
- ...interaction,
3406
- category: categoryInfo.category,
3407
- originalCategory: categoryInfo.originalCategory
3408
- });
3409
- });
3410
- }
3411
- }
3412
-
3413
- // Sort by timestamp (chronological order)
3414
- allInteractions.sort((a, b) => {
3415
- const timestampA = new Date(a.timestamp || 0);
3416
- const timestampB = new Date(b.timestamp || 0);
3417
- return timestampA - timestampB;
3418
- });
3419
-
3420
- return allInteractions;
3421
- },
3422
-
3423
- /**
3424
- * Get chronological interactions for backend
3425
- *
3426
- * Returns both chronological array and categorized structure
3427
- *
3428
- * Returns: Object with chronological and categorized interactions
3429
- */
3430
- getChronologicalForBackend() {
3431
- const chronological = this.getChronological();
3432
-
3433
- return {
3434
- chronological: chronological,
3435
- categorized: sessionData.interactions
3436
- };
3437
- },
3438
-
3439
- /**
3440
- * Deduplicate interactions
3441
- *
3442
- * Removes duplicate interactions based on timestamp, category, and key fields
3443
- *
3444
- * Logic:
3445
- * - Compares interactions by timestamp, category, and element identifier
3446
- * - Keeps first occurrence of duplicates
3447
- * - Updates total count after deduplication
3448
- */
3449
- deduplicate() {
3450
- if (!sessionData.interactions) return;
3451
-
3452
- const seen = new Set();
3453
-
3454
- for (const category of this.CATEGORIES) {
3455
- if (sessionData.interactions[category] && Array.isArray(sessionData.interactions[category])) {
3456
- sessionData.interactions[category] = sessionData.interactions[category].filter(interaction => {
3457
- // Create unique key from timestamp, category, and element identifier
3458
- const elementId = interaction.elementId || interaction.target || interaction.selector || '';
3459
- const key = `${interaction.timestamp}_${category}_${elementId}`;
3460
-
3461
- if (seen.has(key)) {
3462
- return false; // Duplicate, remove
3463
- }
3464
-
3465
- seen.add(key);
3466
- return true; // Keep
3467
- });
3468
- }
3469
- }
3470
-
3471
- // Update total count after deduplication
3472
- this.updateTotalCount();
3473
-
3474
- // Update session storage
3475
- this.updateSessionStorage();
3476
- },
3477
-
3478
- /**
3479
- * Get interactions by category
3480
- *
3481
- * Returns all interactions for a specific category
3482
- *
3483
- * Parameters: category - Interaction category name
3484
- * Returns: Array of interactions for that category
3485
- */
3486
- getByCategory(category) {
3487
- if (!sessionData.interactions) {
3488
- return [];
3489
- }
3490
-
3491
- if (!this.CATEGORIES.includes(category)) {
3492
- return [];
3493
- }
3494
-
3495
- return sessionData.interactions[category] || [];
3496
- },
3497
-
3498
- /**
3499
- * Get total interactions count
3500
- *
3501
- * Returns total number of interactions across all categories
3502
- */
3503
- getTotalCount() {
3504
- if (!sessionData.interactions) {
3505
- return 0;
3506
- }
3507
-
3508
- return sessionData.interactions.totalInteractions || 0;
3509
- },
3510
-
3511
- /**
3512
- * Clear all interactions
3513
- *
3514
- * Resets interactions object to empty state
3515
- */
3516
- clear() {
3517
- this.initialize();
3518
- for (const category of this.CATEGORIES) {
3519
- sessionData.interactions[category] = [];
3520
- }
3521
- sessionData.interactions.totalInteractions = 0;
3522
- this.updateSessionStorage();
3523
- }
3201
+ CATEGORIES: [],
3202
+ initialize() {},
3203
+ add() {},
3204
+ updateTotalCount() {},
3205
+ updateSessionStorage() {},
3206
+ getChronological() { return []; },
3207
+ getChronologicalForBackend() { return { chronological: [], categorized: {} }; },
3208
+ deduplicate() {},
3209
+ getByCategory() { return []; },
3210
+ getTotalCount() { return 0; },
3211
+ clear() {}
3524
3212
  };
3525
3213
 
3526
3214
  // ============================================================================
@@ -3988,7 +3676,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
3988
3676
  // Ensure arrays exist
3989
3677
  s.pageVisits = s.pageVisits || [];
3990
3678
  s.visited_pages = s.visited_pages || [];
3991
- s.interactions = s.interactions || { totalInteractions: 0 };
3992
3679
 
3993
3680
  // Normalize timestamps to ISO strings
3994
3681
  if (s.startTime && !(typeof s.startTime === 'string')) {
@@ -4043,171 +3730,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4043
3730
  // First normalize the shape
4044
3731
  sourceData = this.normalizeShape(sourceData);
4045
3732
 
4046
- // Get chronological interactions
4047
- const chronologicalInteractions = InteractionManager.getChronologicalForBackend();
4048
-
4049
- // Get page visits and session-level interactions
3733
+ // Get page visits
4050
3734
  const pageVisits = sourceData.visited_pages || sourceData.pageVisits || sourceData.visitedPages || [];
4051
- const sessionInteractions = sourceData.interactions || {};
4052
-
4053
- // CRITICAL FIX: Distribute session-level interactions to appropriate pages based on path
4054
- const interactionTypes = [
4055
- 'clicks', 'mediaInteractions', 'contextMenuEvents', 'windowEvents',
4056
- 'formInteractions', 'scrollEvents', 'focusEvents', 'hoverEvents',
4057
- 'formSubmissions', 'fieldChanges',
4058
- 'keyboardEvents', 'copyPasteEvents', 'dragDropEvents',
4059
- 'touchEvents', 'formAnalytics'
4060
- // Note: validationErrors, performanceEvents, errorEvents, networkEvents are no longer
4061
- // stored in session interactions — they are emitted as individual queryable auto events
4062
- // (form_validation_error, page_performance, js_error, network_error)
4063
- ];
4064
-
4065
- // Helper to normalize path for matching
4066
- const normalizePathForMatching = (path) => {
4067
- if (!path) return '/';
4068
- // Remove query params and hash
4069
- const cleanPath = path.split('?')[0].split('#')[0];
4070
- return cleanPath || '/';
4071
- };
4072
-
4073
- // Get session start time in milliseconds for alignment
4074
- const sessionStartTime = sourceData.start_time || sourceData.startTime;
4075
- const sessionStartMs = sessionStartTime
4076
- ? (typeof sessionStartTime === 'string' ? new Date(sessionStartTime).getTime() : sessionStartTime)
4077
- : Date.now();
4078
-
4079
- // Distribute interactions to pages and fix mount/unmount times
4080
- // CRITICAL: Create copies to avoid mutating original objects
4081
- const pagesWithInteractions = pageVisits.map((pageVisit, index) => {
4082
- // Create a copy of the page visit to avoid mutating the original
4083
- const pageVisitCopy = { ...pageVisit };
4084
- const pagePath = normalizePathForMatching(pageVisitCopy.path || pageVisitCopy.url);
4085
- const isFirstPage = index === 0 || pageVisitCopy.isEntry === true;
4086
-
4087
- // CRITICAL FIX: If unmountTime is null, set it to next page's mountTime
4088
- if (!pageVisitCopy.unmountTime && index < pageVisits.length - 1) {
4089
- const nextPage = pageVisits[index + 1];
4090
- if (nextPage && nextPage.mountTime) {
4091
- pageVisitCopy.unmountTime = typeof nextPage.mountTime === 'number'
4092
- ? nextPage.mountTime
4093
- : new Date(nextPage.mountTime).getTime();
4094
- // Recalculate duration
4095
- if (pageVisitCopy.mountTime) {
4096
- const mountMs = typeof pageVisitCopy.mountTime === 'number'
4097
- ? pageVisitCopy.mountTime
4098
- : new Date(pageVisitCopy.mountTime).getTime();
4099
- pageVisitCopy.duration = Math.floor((pageVisitCopy.unmountTime - mountMs) / 1000);
4100
- }
4101
- }
4102
- }
4103
-
4104
- // If still no unmountTime and this is the last page, set to session endTime
4105
- if (!pageVisitCopy.unmountTime && index === pageVisits.length - 1) {
4106
- const endTime = sourceData.end_time || sourceData.endTime;
4107
- if (endTime) {
4108
- pageVisitCopy.unmountTime = typeof endTime === 'number'
4109
- ? endTime
4110
- : new Date(endTime).getTime();
4111
- // Recalculate duration
4112
- if (pageVisitCopy.mountTime) {
4113
- const mountMs = typeof pageVisitCopy.mountTime === 'number'
4114
- ? pageVisitCopy.mountTime
4115
- : new Date(pageVisitCopy.mountTime).getTime();
4116
- pageVisitCopy.duration = Math.floor((pageVisitCopy.unmountTime - mountMs) / 1000);
4117
- }
4118
- }
4119
- }
4120
-
4121
- // FIX: Align first page mountTime with session start_time (only in copy, not original)
4122
- if (isFirstPage && pageVisitCopy.mountTime) {
4123
- const mountTimeMs = typeof pageVisitCopy.mountTime === 'number'
4124
- ? pageVisitCopy.mountTime
4125
- : new Date(pageVisitCopy.mountTime).getTime();
4126
-
4127
- // If mountTime is more than 5 minutes off from session start, align it
4128
- const timeDiff = Math.abs(mountTimeMs - sessionStartMs);
4129
- if (timeDiff > 5 * 60 * 1000) { // More than 5 minutes difference
4130
- pageVisitCopy.mountTime = sessionStartMs;
4131
- // Recalculate duration if unmountTime exists
4132
- if (pageVisitCopy.unmountTime) {
4133
- const unmountTimeMs = typeof pageVisitCopy.unmountTime === 'number'
4134
- ? pageVisitCopy.unmountTime
4135
- : new Date(pageVisitCopy.unmountTime).getTime();
4136
- pageVisitCopy.duration = Math.floor((unmountTimeMs - sessionStartMs) / 1000);
4137
- }
4138
- }
4139
- }
4140
-
4141
- // Ensure mountTime and unmountTime are numbers (milliseconds) for consistency (in copy only)
4142
- if (pageVisitCopy.mountTime && typeof pageVisitCopy.mountTime !== 'number') {
4143
- pageVisitCopy.mountTime = new Date(pageVisitCopy.mountTime).getTime();
4144
- }
4145
- if (pageVisitCopy.unmountTime && typeof pageVisitCopy.unmountTime !== 'number') {
4146
- pageVisitCopy.unmountTime = new Date(pageVisitCopy.unmountTime).getTime();
4147
- }
4148
-
4149
- // Initialize interactions object for this page if it doesn't exist (in copy)
4150
- if (!pageVisitCopy.interactions) {
4151
- pageVisitCopy.interactions = {
4152
- totalInteractions: 0,
4153
- clicks: [],
4154
- mediaInteractions: [],
4155
- contextMenuEvents: [],
4156
- windowEvents: [],
4157
- formInteractions: [],
4158
- scrollEvents: [],
4159
- focusEvents: [],
4160
- hoverEvents: [],
4161
- formSubmissions: [],
4162
- fieldChanges: [],
4163
- validationErrors: [],
4164
- keyboardEvents: [],
4165
- copyPasteEvents: [],
4166
- dragDropEvents: [],
4167
- touchEvents: [],
4168
- performanceEvents: [],
4169
- errorEvents: [],
4170
- networkEvents: [],
4171
- formAnalytics: []
4172
- };
4173
- }
4174
-
4175
- // Distribute interactions from session-level to this page based on path matching (in copy)
4176
- interactionTypes.forEach(type => {
4177
- if (Array.isArray(sessionInteractions[type])) {
4178
- sessionInteractions[type].forEach(interaction => {
4179
- const interactionPath = normalizePathForMatching(interaction.path);
4180
- if (interactionPath === pagePath) {
4181
- // Add interaction to this page (avoid duplicates)
4182
- const exists = pageVisitCopy.interactions[type].some(existing => {
4183
- // Check for duplicates based on timestamp and key properties
4184
- if (existing.timestamp && interaction.timestamp) {
4185
- return existing.timestamp === interaction.timestamp;
4186
- }
4187
- // For clicks, check element properties
4188
- if (type === 'clicks' && existing.element && interaction.element) {
4189
- return existing.element.id === interaction.element.id &&
4190
- existing.element.tagName === interaction.element.tagName;
4191
- }
4192
- return false;
4193
- });
4194
-
4195
- if (!exists) {
4196
- pageVisitCopy.interactions[type].push(interaction);
4197
- }
4198
- }
4199
- });
4200
- }
4201
- });
4202
-
4203
- // Calculate totalInteractions for this page (in copy)
4204
- const total = interactionTypes.reduce((sum, type) => {
4205
- return sum + (pageVisitCopy.interactions[type]?.length || 0);
4206
- }, 0);
4207
- pageVisitCopy.interactions.totalInteractions = total;
4208
-
4209
- return pageVisitCopy;
4210
- });
4211
3735
 
4212
3736
  // Create transformed object - PostgreSQL snake_case format only
4213
3737
  const transformed = {
@@ -4272,12 +3796,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4272
3796
  utm_content: sourceData.utm_content || sourceData.utmData?.content || null,
4273
3797
  utm_id: sourceData.utm_id || sourceData.utmData?.utm_id || null,
4274
3798
 
4275
- // JSONB fields - NOW WITH INTERACTIONS DISTRIBUTED TO PAGES
4276
- visited_pages: pagesWithInteractions,
4277
- interactions: {
4278
- ...sessionInteractions,
4279
- chronological: chronologicalInteractions.chronological || []
4280
- },
3799
+ // JSONB fields
3800
+ visited_pages: pageVisits,
4281
3801
 
4282
3802
  // Active tab time in ms (tab foreground time only, for active_time_seconds in DB)
4283
3803
  active_time_ms: sourceData.active_time_ms || null
@@ -4945,12 +4465,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4945
4465
  if (hoveredElements.has(elementId)) {
4946
4466
  hoveredElements.delete(elementId);
4947
4467
 
4948
- // Update hover duration in the interaction
4949
- const interactions = InteractionManager.getByCategory('hoverEvents');
4950
- const hoverEvent = interactions.find(h => h.elementId === elementId);
4951
- if (hoverEvent) {
4952
- hoverEvent.hoverDuration = Date.now() - new Date(hoverEvent.timestamp).getTime();
4953
- }
4954
4468
  }
4955
4469
  }
4956
4470
  });
@@ -6269,9 +5783,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6269
5783
  // Initialize session data structure
6270
5784
  SessionDataManager.initialize(sessionId, userId);
6271
5785
 
6272
- // Initialize interactions
6273
- InteractionManager.initialize();
6274
-
6275
5786
  // Initialize page visits
6276
5787
  PageVisitManager.initialize();
6277
5788
  } catch (error) {
@@ -6414,15 +5925,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6414
5925
  sessionData.pagesViewed = sessionData.visited_pages.length;
6415
5926
  }
6416
5927
 
6417
- // Sync interactions
6418
- if (storedSession.sessionData.interactions) {
6419
- const storedInteractions = storedSession.sessionData.interactions;
6420
- if (storedInteractions.totalInteractions >
6421
- (sessionData.interactions?.totalInteractions || 0)) {
6422
- // Update interactions from storage
6423
- sessionData.interactions = storedInteractions;
6424
- }
6425
- }
6426
5928
  }
6427
5929
 
6428
5930
  // Update endTime
@@ -6485,9 +5987,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6485
5987
  }));
6486
5988
  sessionData.pagesViewed = sessionData.visited_pages.length;
6487
5989
  }
6488
- if (storedSession.sessionData.interactions) {
6489
- sessionData.interactions = storedSession.sessionData.interactions;
6490
- }
6491
5990
  }
6492
5991
 
6493
5992
  // Track browser close (last page unmount)
@@ -8670,10 +8169,6 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
8670
8169
  return sessionData;
8671
8170
  },
8672
8171
 
8673
- // Interaction Functions
8674
- getChronologicalInteractions: InteractionManager.getChronological.bind(InteractionManager),
8675
- sortInteractionsChronologically: InteractionManager.getChronological.bind(InteractionManager),
8676
-
8677
8172
  // Auto Events Configuration
8678
8173
  enableAutoEvents: function() {
8679
8174
  CONFIG.AUTO_EVENTS.enabled = true;