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