cuoral-ionic 0.0.6 → 0.0.7
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/android/build/.transforms/bb54161301273cf9b5b94a21c0fb3f23/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$1.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$2.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$3.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$4.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$5.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$6.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$InitiateCallback.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$UploadCallback.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/desugar_graph.bin +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$2.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$3.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$4.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$5.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$6.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$InitiateCallback.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$UploadCallback.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$2.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$3.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$4.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$5.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$6.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$InitiateCallback.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$UploadCallback.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/cuoral/ionic/CuoralPlugin.java +205 -5
- package/dist/cuoral.d.ts +15 -1
- package/dist/cuoral.d.ts.map +1 -1
- package/dist/cuoral.js +113 -9
- package/dist/index.esm.js +159 -19
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +159 -19
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +4 -0
- package/dist/intelligence.d.ts.map +1 -1
- package/dist/intelligence.js +19 -0
- package/dist/plugin.d.ts +15 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +23 -10
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -0
- package/ios/Plugin/CuoralPlugin.swift +249 -13
- package/package.json +1 -1
- package/src/cuoral.ts +128 -11
- package/src/intelligence.ts +23 -0
- package/src/plugin.ts +39 -11
- package/src/types.ts +4 -0
package/dist/index.esm.js
CHANGED
|
@@ -11,6 +11,7 @@ var CuoralMessageType;
|
|
|
11
11
|
CuoralMessageType["STOP_RECORDING"] = "CUORAL_STOP_RECORDING";
|
|
12
12
|
CuoralMessageType["RECORDING_STARTED"] = "CUORAL_RECORDING_STARTED";
|
|
13
13
|
CuoralMessageType["RECORDING_STOPPED"] = "CUORAL_RECORDING_STOPPED";
|
|
14
|
+
CuoralMessageType["RECORDING_UPLOADED"] = "CUORAL_RECORDING_UPLOADED";
|
|
14
15
|
CuoralMessageType["RECORDING_ERROR"] = "CUORAL_RECORDING_ERROR";
|
|
15
16
|
// Screenshot
|
|
16
17
|
CuoralMessageType["TAKE_SCREENSHOT"] = "CUORAL_TAKE_SCREENSHOT";
|
|
@@ -19,6 +20,9 @@ var CuoralMessageType;
|
|
|
19
20
|
// Widget Communication
|
|
20
21
|
CuoralMessageType["WIDGET_READY"] = "CUORAL_WIDGET_READY";
|
|
21
22
|
CuoralMessageType["WIDGET_CLOSED"] = "CUORAL_WIDGET_CLOSED";
|
|
23
|
+
CuoralMessageType["SESSION_UPDATED"] = "CUORAL_SESSION_UPDATED";
|
|
24
|
+
CuoralMessageType["REQUEST_SESSION_ID"] = "CUORAL_REQUEST_SESSION_ID";
|
|
25
|
+
CuoralMessageType["SESSION_ID_RESPONSE"] = "CUORAL_SESSION_ID_RESPONSE";
|
|
22
26
|
// File Upload
|
|
23
27
|
CuoralMessageType["UPLOAD_FILE"] = "CUORAL_UPLOAD_FILE";
|
|
24
28
|
CuoralMessageType["UPLOAD_PROGRESS"] = "CUORAL_UPLOAD_PROGRESS";
|
|
@@ -93,7 +97,7 @@ class CuoralRecorder {
|
|
|
93
97
|
/**
|
|
94
98
|
* Stop recording
|
|
95
99
|
*/
|
|
96
|
-
async stopRecording() {
|
|
100
|
+
async stopRecording(options) {
|
|
97
101
|
try {
|
|
98
102
|
if (!this.isRecording) {
|
|
99
103
|
// Send error message to widget so it can exit "stopping" state
|
|
@@ -103,23 +107,36 @@ class CuoralRecorder {
|
|
|
103
107
|
});
|
|
104
108
|
return null;
|
|
105
109
|
}
|
|
106
|
-
const result = await CuoralPlugin$1.stopRecording();
|
|
110
|
+
const result = await CuoralPlugin$1.stopRecording(options);
|
|
107
111
|
if (result.success) {
|
|
108
112
|
this.isRecording = false;
|
|
109
113
|
const duration = this.recordingStartTime
|
|
110
114
|
? Math.floor((Date.now() - this.recordingStartTime) / 1000)
|
|
111
115
|
: 0;
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
// If uploaded, notify widget differently
|
|
117
|
+
if (result.uploaded) {
|
|
118
|
+
this.postMessage({
|
|
119
|
+
type: CuoralMessageType.RECORDING_UPLOADED,
|
|
120
|
+
payload: {
|
|
121
|
+
duration: result.duration || duration,
|
|
122
|
+
uploaded: true
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Post message to widget (old behavior)
|
|
128
|
+
this.postMessage({
|
|
129
|
+
type: CuoralMessageType.RECORDING_STOPPED,
|
|
130
|
+
payload: {
|
|
131
|
+
filePath: result.filePath,
|
|
132
|
+
duration: result.duration || duration,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
120
136
|
return {
|
|
121
137
|
filePath: result.filePath,
|
|
122
138
|
duration: result.duration || duration,
|
|
139
|
+
uploaded: result.uploaded,
|
|
123
140
|
};
|
|
124
141
|
}
|
|
125
142
|
// If result.success is false, send error to widget
|
|
@@ -636,6 +653,24 @@ class CuoralIntelligence {
|
|
|
636
653
|
this.rageClickWindowMs = 2000; // Within 2 seconds
|
|
637
654
|
this.sessionId = sessionId;
|
|
638
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Update the session ID (e.g., when user logs in)
|
|
658
|
+
*/
|
|
659
|
+
updateSessionId(newSessionId) {
|
|
660
|
+
console.log('[Cuoral Intelligence] Updating session ID from', this.sessionId, 'to', newSessionId);
|
|
661
|
+
this.sessionId = newSessionId;
|
|
662
|
+
// Flush any pending events with the old session before switching
|
|
663
|
+
this.flush();
|
|
664
|
+
// Update native error capture with new session ID
|
|
665
|
+
if (Capacitor.isNativePlatform()) {
|
|
666
|
+
CuoralPlugin.setupNativeErrorCapture({
|
|
667
|
+
backendUrl: this.config.consoleErrorBackendUrl,
|
|
668
|
+
sessionId: newSessionId
|
|
669
|
+
}).catch(error => {
|
|
670
|
+
console.warn('[Cuoral Intelligence] Failed to update native error capture:', error);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
}
|
|
639
674
|
/**
|
|
640
675
|
* Initialize intelligence tracking
|
|
641
676
|
*/
|
|
@@ -965,6 +1000,7 @@ class CuoralIntelligence {
|
|
|
965
1000
|
url: window.location.href,
|
|
966
1001
|
data,
|
|
967
1002
|
};
|
|
1003
|
+
console.log(`[Intelligence] Enqueuing ${type} event with session:`, this.sessionId);
|
|
968
1004
|
queue.push(event);
|
|
969
1005
|
// Flush immediately for critical errors
|
|
970
1006
|
const shouldFlushImmediately = type === 'api_call' && (data.status_code === 0 || data.status_code >= 400);
|
|
@@ -1410,6 +1446,11 @@ class Cuoral {
|
|
|
1410
1446
|
key: options.publicKey,
|
|
1411
1447
|
_t: Date.now().toString(),
|
|
1412
1448
|
});
|
|
1449
|
+
// Add session_id if available (for widget to use existing session)
|
|
1450
|
+
const existingSessionId = localStorage.getItem('__x_loadID');
|
|
1451
|
+
if (existingSessionId) {
|
|
1452
|
+
params.set('cuoral_mobile_session_id', existingSessionId);
|
|
1453
|
+
}
|
|
1413
1454
|
if (options.email)
|
|
1414
1455
|
params.set('email', options.email);
|
|
1415
1456
|
if (options.firstName)
|
|
@@ -1434,18 +1475,23 @@ class Cuoral {
|
|
|
1434
1475
|
* Initialize Cuoral
|
|
1435
1476
|
*/
|
|
1436
1477
|
async initialize() {
|
|
1478
|
+
// Fetch session configuration and initialize intelligence if enabled by backend
|
|
1479
|
+
await this.initializeIntelligence();
|
|
1480
|
+
console.log('[Cuoral] Initialize - Session ID:', localStorage.getItem('__x_loadID'));
|
|
1481
|
+
// Setup localStorage listener to detect when widget changes session
|
|
1482
|
+
this.setupStorageListener();
|
|
1437
1483
|
this.bridge.initialize();
|
|
1438
1484
|
// Recreate modal if it was destroyed (e.g., after clearSession)
|
|
1439
1485
|
if (this.options.useModal && !this.modal) {
|
|
1440
1486
|
const widgetUrl = this.getWidgetUrl();
|
|
1441
1487
|
this.modal = new CuoralModal(widgetUrl, this.options.showFloatingButton);
|
|
1442
1488
|
}
|
|
1443
|
-
//
|
|
1489
|
+
// Update modal URL with session ID
|
|
1444
1490
|
if (this.modal) {
|
|
1491
|
+
const widgetUrl = this.getWidgetUrl();
|
|
1492
|
+
this.modal.updateWidgetUrl(widgetUrl);
|
|
1445
1493
|
this.modal.initialize();
|
|
1446
1494
|
}
|
|
1447
|
-
// Fetch session configuration and initialize intelligence if enabled by backend
|
|
1448
|
-
await this.initializeIntelligence();
|
|
1449
1495
|
}
|
|
1450
1496
|
/**
|
|
1451
1497
|
* Initialize intelligence based on backend configuration
|
|
@@ -1477,9 +1523,13 @@ class Cuoral {
|
|
|
1477
1523
|
}
|
|
1478
1524
|
// Only initialize intelligence if customer_intelligence is enabled in backend
|
|
1479
1525
|
if (config && config.customer_intelligence === true) {
|
|
1526
|
+
console.log('[Cuoral] Initializing intelligence with session:', sessionId);
|
|
1480
1527
|
this.intelligence = new CuoralIntelligence(sessionId);
|
|
1481
1528
|
this.intelligence.init();
|
|
1482
1529
|
}
|
|
1530
|
+
else {
|
|
1531
|
+
console.log('[Cuoral] Intelligence not enabled or no config for session:', sessionId);
|
|
1532
|
+
}
|
|
1483
1533
|
}
|
|
1484
1534
|
catch (error) {
|
|
1485
1535
|
console.warn('[Cuoral] Failed to initialize intelligence:', error);
|
|
@@ -1536,6 +1586,48 @@ class Cuoral {
|
|
|
1536
1586
|
this.intelligence.trackError(message, stackTrace, metadata);
|
|
1537
1587
|
}
|
|
1538
1588
|
}
|
|
1589
|
+
/**
|
|
1590
|
+
* Update user profile for the current session
|
|
1591
|
+
* Call this after user logs in to update the intelligence session with their profile
|
|
1592
|
+
* @param email - User's email address
|
|
1593
|
+
* @param name - User's full name
|
|
1594
|
+
*/
|
|
1595
|
+
async updateUserProfile(email, name) {
|
|
1596
|
+
try {
|
|
1597
|
+
const sessionId = localStorage.getItem('__x_loadID');
|
|
1598
|
+
if (!sessionId) {
|
|
1599
|
+
console.warn('[Cuoral] No session ID found, cannot update profile');
|
|
1600
|
+
return false;
|
|
1601
|
+
}
|
|
1602
|
+
console.log('[Cuoral] Updating user profile for session:', sessionId);
|
|
1603
|
+
const response = await fetch('https://api.cuoral.com/conversation/set-profile', {
|
|
1604
|
+
method: 'POST',
|
|
1605
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1606
|
+
body: JSON.stringify({
|
|
1607
|
+
session_id: sessionId,
|
|
1608
|
+
email: email,
|
|
1609
|
+
name: name,
|
|
1610
|
+
}),
|
|
1611
|
+
});
|
|
1612
|
+
if (!response.ok) {
|
|
1613
|
+
console.error('[Cuoral] Failed to update profile:', response.statusText);
|
|
1614
|
+
return false;
|
|
1615
|
+
}
|
|
1616
|
+
console.log('[Cuoral] ✓ User profile updated successfully for session:', sessionId);
|
|
1617
|
+
// Store user info locally
|
|
1618
|
+
this.options.email = email;
|
|
1619
|
+
const nameParts = name.split(' ');
|
|
1620
|
+
if (nameParts.length > 0) {
|
|
1621
|
+
this.options.firstName = nameParts[0];
|
|
1622
|
+
this.options.lastName = nameParts.slice(1).join(' ');
|
|
1623
|
+
}
|
|
1624
|
+
return true;
|
|
1625
|
+
}
|
|
1626
|
+
catch (error) {
|
|
1627
|
+
console.error('[Cuoral] Error updating user profile:', error);
|
|
1628
|
+
return false;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1539
1631
|
/**
|
|
1540
1632
|
* Start native screen recording programmatically
|
|
1541
1633
|
* @returns Promise<boolean> - true if recording started successfully
|
|
@@ -1551,11 +1643,19 @@ class Cuoral {
|
|
|
1551
1643
|
}
|
|
1552
1644
|
/**
|
|
1553
1645
|
* Stop native screen recording programmatically
|
|
1554
|
-
*
|
|
1646
|
+
* Recording will be automatically uploaded to the portal
|
|
1647
|
+
* @returns Promise<{filePath?: string; duration?: number; uploaded?: boolean} | null> - Recording result or null if failed
|
|
1555
1648
|
*/
|
|
1556
1649
|
async stopRecording() {
|
|
1557
1650
|
try {
|
|
1558
|
-
|
|
1651
|
+
const sessionId = localStorage.getItem('__x_loadID');
|
|
1652
|
+
const customerId = localStorage.getItem('cuoralCustomerId');
|
|
1653
|
+
return await this.recorder.stopRecording({
|
|
1654
|
+
autoUpload: true,
|
|
1655
|
+
sessionId: sessionId || undefined,
|
|
1656
|
+
publicKey: this.options.publicKey,
|
|
1657
|
+
customerId: customerId || undefined,
|
|
1658
|
+
});
|
|
1559
1659
|
}
|
|
1560
1660
|
catch (error) {
|
|
1561
1661
|
console.error('[Cuoral] Failed to stop recording:', error);
|
|
@@ -1601,7 +1701,7 @@ class Cuoral {
|
|
|
1601
1701
|
// Add session_id if available
|
|
1602
1702
|
const sessionId = localStorage.getItem('__x_loadID');
|
|
1603
1703
|
if (sessionId) {
|
|
1604
|
-
params.set('
|
|
1704
|
+
params.set('cuoral_mobile_session_id', sessionId);
|
|
1605
1705
|
}
|
|
1606
1706
|
if (this.options.email)
|
|
1607
1707
|
params.set('email', this.options.email);
|
|
@@ -1655,6 +1755,28 @@ class Cuoral {
|
|
|
1655
1755
|
}
|
|
1656
1756
|
}
|
|
1657
1757
|
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Setup localStorage listener for session changes
|
|
1760
|
+
* Widget updates localStorage when creating new session, SDK detects and syncs
|
|
1761
|
+
*/
|
|
1762
|
+
setupStorageListener() {
|
|
1763
|
+
// Poll localStorage every 2 seconds to detect session changes
|
|
1764
|
+
// (storage event doesn't fire for same-window changes)
|
|
1765
|
+
let lastKnownSession = localStorage.getItem('__x_loadID');
|
|
1766
|
+
setInterval(() => {
|
|
1767
|
+
const currentSession = localStorage.getItem('__x_loadID');
|
|
1768
|
+
if (currentSession && currentSession !== lastKnownSession) {
|
|
1769
|
+
console.log('[Cuoral] 🔄 Session changed in localStorage');
|
|
1770
|
+
console.log('[Cuoral] Old session:', lastKnownSession);
|
|
1771
|
+
console.log('[Cuoral] New session:', currentSession);
|
|
1772
|
+
lastKnownSession = currentSession;
|
|
1773
|
+
// Update intelligence to use new session
|
|
1774
|
+
if (this.intelligence) {
|
|
1775
|
+
this.intelligence.updateSessionId(currentSession);
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
}, 2000);
|
|
1779
|
+
}
|
|
1658
1780
|
/**
|
|
1659
1781
|
* Clean up resources
|
|
1660
1782
|
*/
|
|
@@ -1746,9 +1868,27 @@ class Cuoral {
|
|
|
1746
1868
|
});
|
|
1747
1869
|
// Handle stop recording requests from widget
|
|
1748
1870
|
this.bridge.on(CuoralMessageType.STOP_RECORDING, async () => {
|
|
1749
|
-
const
|
|
1750
|
-
|
|
1751
|
-
|
|
1871
|
+
const sessionId = localStorage.getItem('__x_loadID');
|
|
1872
|
+
const customerId = localStorage.getItem('cuoralCustomerId');
|
|
1873
|
+
const result = await this.recorder.stopRecording({
|
|
1874
|
+
autoUpload: true,
|
|
1875
|
+
sessionId: sessionId || undefined,
|
|
1876
|
+
publicKey: this.options.publicKey,
|
|
1877
|
+
customerId: customerId || undefined,
|
|
1878
|
+
});
|
|
1879
|
+
if (result && result.uploaded) {
|
|
1880
|
+
// Video was automatically uploaded, just notify widget
|
|
1881
|
+
this.bridge.sendToWidget({
|
|
1882
|
+
type: CuoralMessageType.RECORDING_UPLOADED,
|
|
1883
|
+
payload: {
|
|
1884
|
+
duration: result.duration,
|
|
1885
|
+
uploaded: true,
|
|
1886
|
+
timestamp: Date.now()
|
|
1887
|
+
}
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
else if (result) {
|
|
1891
|
+
// Upload failed or was disabled, send video data to widget (old behavior)
|
|
1752
1892
|
const capacitorUrl = result.filePath ? Capacitor.convertFileSrc(result.filePath) : '';
|
|
1753
1893
|
try {
|
|
1754
1894
|
// Fetch the video blob from the capacitor URL
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ exports.CuoralMessageType = void 0;
|
|
|
32
32
|
CuoralMessageType["STOP_RECORDING"] = "CUORAL_STOP_RECORDING";
|
|
33
33
|
CuoralMessageType["RECORDING_STARTED"] = "CUORAL_RECORDING_STARTED";
|
|
34
34
|
CuoralMessageType["RECORDING_STOPPED"] = "CUORAL_RECORDING_STOPPED";
|
|
35
|
+
CuoralMessageType["RECORDING_UPLOADED"] = "CUORAL_RECORDING_UPLOADED";
|
|
35
36
|
CuoralMessageType["RECORDING_ERROR"] = "CUORAL_RECORDING_ERROR";
|
|
36
37
|
// Screenshot
|
|
37
38
|
CuoralMessageType["TAKE_SCREENSHOT"] = "CUORAL_TAKE_SCREENSHOT";
|
|
@@ -40,6 +41,9 @@ exports.CuoralMessageType = void 0;
|
|
|
40
41
|
// Widget Communication
|
|
41
42
|
CuoralMessageType["WIDGET_READY"] = "CUORAL_WIDGET_READY";
|
|
42
43
|
CuoralMessageType["WIDGET_CLOSED"] = "CUORAL_WIDGET_CLOSED";
|
|
44
|
+
CuoralMessageType["SESSION_UPDATED"] = "CUORAL_SESSION_UPDATED";
|
|
45
|
+
CuoralMessageType["REQUEST_SESSION_ID"] = "CUORAL_REQUEST_SESSION_ID";
|
|
46
|
+
CuoralMessageType["SESSION_ID_RESPONSE"] = "CUORAL_SESSION_ID_RESPONSE";
|
|
43
47
|
// File Upload
|
|
44
48
|
CuoralMessageType["UPLOAD_FILE"] = "CUORAL_UPLOAD_FILE";
|
|
45
49
|
CuoralMessageType["UPLOAD_PROGRESS"] = "CUORAL_UPLOAD_PROGRESS";
|
|
@@ -114,7 +118,7 @@ class CuoralRecorder {
|
|
|
114
118
|
/**
|
|
115
119
|
* Stop recording
|
|
116
120
|
*/
|
|
117
|
-
async stopRecording() {
|
|
121
|
+
async stopRecording(options) {
|
|
118
122
|
try {
|
|
119
123
|
if (!this.isRecording) {
|
|
120
124
|
// Send error message to widget so it can exit "stopping" state
|
|
@@ -124,23 +128,36 @@ class CuoralRecorder {
|
|
|
124
128
|
});
|
|
125
129
|
return null;
|
|
126
130
|
}
|
|
127
|
-
const result = await CuoralPlugin$1.stopRecording();
|
|
131
|
+
const result = await CuoralPlugin$1.stopRecording(options);
|
|
128
132
|
if (result.success) {
|
|
129
133
|
this.isRecording = false;
|
|
130
134
|
const duration = this.recordingStartTime
|
|
131
135
|
? Math.floor((Date.now() - this.recordingStartTime) / 1000)
|
|
132
136
|
: 0;
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
// If uploaded, notify widget differently
|
|
138
|
+
if (result.uploaded) {
|
|
139
|
+
this.postMessage({
|
|
140
|
+
type: exports.CuoralMessageType.RECORDING_UPLOADED,
|
|
141
|
+
payload: {
|
|
142
|
+
duration: result.duration || duration,
|
|
143
|
+
uploaded: true
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// Post message to widget (old behavior)
|
|
149
|
+
this.postMessage({
|
|
150
|
+
type: exports.CuoralMessageType.RECORDING_STOPPED,
|
|
151
|
+
payload: {
|
|
152
|
+
filePath: result.filePath,
|
|
153
|
+
duration: result.duration || duration,
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
141
157
|
return {
|
|
142
158
|
filePath: result.filePath,
|
|
143
159
|
duration: result.duration || duration,
|
|
160
|
+
uploaded: result.uploaded,
|
|
144
161
|
};
|
|
145
162
|
}
|
|
146
163
|
// If result.success is false, send error to widget
|
|
@@ -657,6 +674,24 @@ class CuoralIntelligence {
|
|
|
657
674
|
this.rageClickWindowMs = 2000; // Within 2 seconds
|
|
658
675
|
this.sessionId = sessionId;
|
|
659
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* Update the session ID (e.g., when user logs in)
|
|
679
|
+
*/
|
|
680
|
+
updateSessionId(newSessionId) {
|
|
681
|
+
console.log('[Cuoral Intelligence] Updating session ID from', this.sessionId, 'to', newSessionId);
|
|
682
|
+
this.sessionId = newSessionId;
|
|
683
|
+
// Flush any pending events with the old session before switching
|
|
684
|
+
this.flush();
|
|
685
|
+
// Update native error capture with new session ID
|
|
686
|
+
if (core.Capacitor.isNativePlatform()) {
|
|
687
|
+
CuoralPlugin.setupNativeErrorCapture({
|
|
688
|
+
backendUrl: this.config.consoleErrorBackendUrl,
|
|
689
|
+
sessionId: newSessionId
|
|
690
|
+
}).catch(error => {
|
|
691
|
+
console.warn('[Cuoral Intelligence] Failed to update native error capture:', error);
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
}
|
|
660
695
|
/**
|
|
661
696
|
* Initialize intelligence tracking
|
|
662
697
|
*/
|
|
@@ -986,6 +1021,7 @@ class CuoralIntelligence {
|
|
|
986
1021
|
url: window.location.href,
|
|
987
1022
|
data,
|
|
988
1023
|
};
|
|
1024
|
+
console.log(`[Intelligence] Enqueuing ${type} event with session:`, this.sessionId);
|
|
989
1025
|
queue.push(event);
|
|
990
1026
|
// Flush immediately for critical errors
|
|
991
1027
|
const shouldFlushImmediately = type === 'api_call' && (data.status_code === 0 || data.status_code >= 400);
|
|
@@ -1431,6 +1467,11 @@ class Cuoral {
|
|
|
1431
1467
|
key: options.publicKey,
|
|
1432
1468
|
_t: Date.now().toString(),
|
|
1433
1469
|
});
|
|
1470
|
+
// Add session_id if available (for widget to use existing session)
|
|
1471
|
+
const existingSessionId = localStorage.getItem('__x_loadID');
|
|
1472
|
+
if (existingSessionId) {
|
|
1473
|
+
params.set('cuoral_mobile_session_id', existingSessionId);
|
|
1474
|
+
}
|
|
1434
1475
|
if (options.email)
|
|
1435
1476
|
params.set('email', options.email);
|
|
1436
1477
|
if (options.firstName)
|
|
@@ -1455,18 +1496,23 @@ class Cuoral {
|
|
|
1455
1496
|
* Initialize Cuoral
|
|
1456
1497
|
*/
|
|
1457
1498
|
async initialize() {
|
|
1499
|
+
// Fetch session configuration and initialize intelligence if enabled by backend
|
|
1500
|
+
await this.initializeIntelligence();
|
|
1501
|
+
console.log('[Cuoral] Initialize - Session ID:', localStorage.getItem('__x_loadID'));
|
|
1502
|
+
// Setup localStorage listener to detect when widget changes session
|
|
1503
|
+
this.setupStorageListener();
|
|
1458
1504
|
this.bridge.initialize();
|
|
1459
1505
|
// Recreate modal if it was destroyed (e.g., after clearSession)
|
|
1460
1506
|
if (this.options.useModal && !this.modal) {
|
|
1461
1507
|
const widgetUrl = this.getWidgetUrl();
|
|
1462
1508
|
this.modal = new CuoralModal(widgetUrl, this.options.showFloatingButton);
|
|
1463
1509
|
}
|
|
1464
|
-
//
|
|
1510
|
+
// Update modal URL with session ID
|
|
1465
1511
|
if (this.modal) {
|
|
1512
|
+
const widgetUrl = this.getWidgetUrl();
|
|
1513
|
+
this.modal.updateWidgetUrl(widgetUrl);
|
|
1466
1514
|
this.modal.initialize();
|
|
1467
1515
|
}
|
|
1468
|
-
// Fetch session configuration and initialize intelligence if enabled by backend
|
|
1469
|
-
await this.initializeIntelligence();
|
|
1470
1516
|
}
|
|
1471
1517
|
/**
|
|
1472
1518
|
* Initialize intelligence based on backend configuration
|
|
@@ -1498,9 +1544,13 @@ class Cuoral {
|
|
|
1498
1544
|
}
|
|
1499
1545
|
// Only initialize intelligence if customer_intelligence is enabled in backend
|
|
1500
1546
|
if (config && config.customer_intelligence === true) {
|
|
1547
|
+
console.log('[Cuoral] Initializing intelligence with session:', sessionId);
|
|
1501
1548
|
this.intelligence = new CuoralIntelligence(sessionId);
|
|
1502
1549
|
this.intelligence.init();
|
|
1503
1550
|
}
|
|
1551
|
+
else {
|
|
1552
|
+
console.log('[Cuoral] Intelligence not enabled or no config for session:', sessionId);
|
|
1553
|
+
}
|
|
1504
1554
|
}
|
|
1505
1555
|
catch (error) {
|
|
1506
1556
|
console.warn('[Cuoral] Failed to initialize intelligence:', error);
|
|
@@ -1557,6 +1607,48 @@ class Cuoral {
|
|
|
1557
1607
|
this.intelligence.trackError(message, stackTrace, metadata);
|
|
1558
1608
|
}
|
|
1559
1609
|
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Update user profile for the current session
|
|
1612
|
+
* Call this after user logs in to update the intelligence session with their profile
|
|
1613
|
+
* @param email - User's email address
|
|
1614
|
+
* @param name - User's full name
|
|
1615
|
+
*/
|
|
1616
|
+
async updateUserProfile(email, name) {
|
|
1617
|
+
try {
|
|
1618
|
+
const sessionId = localStorage.getItem('__x_loadID');
|
|
1619
|
+
if (!sessionId) {
|
|
1620
|
+
console.warn('[Cuoral] No session ID found, cannot update profile');
|
|
1621
|
+
return false;
|
|
1622
|
+
}
|
|
1623
|
+
console.log('[Cuoral] Updating user profile for session:', sessionId);
|
|
1624
|
+
const response = await fetch('https://api.cuoral.com/conversation/set-profile', {
|
|
1625
|
+
method: 'POST',
|
|
1626
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1627
|
+
body: JSON.stringify({
|
|
1628
|
+
session_id: sessionId,
|
|
1629
|
+
email: email,
|
|
1630
|
+
name: name,
|
|
1631
|
+
}),
|
|
1632
|
+
});
|
|
1633
|
+
if (!response.ok) {
|
|
1634
|
+
console.error('[Cuoral] Failed to update profile:', response.statusText);
|
|
1635
|
+
return false;
|
|
1636
|
+
}
|
|
1637
|
+
console.log('[Cuoral] ✓ User profile updated successfully for session:', sessionId);
|
|
1638
|
+
// Store user info locally
|
|
1639
|
+
this.options.email = email;
|
|
1640
|
+
const nameParts = name.split(' ');
|
|
1641
|
+
if (nameParts.length > 0) {
|
|
1642
|
+
this.options.firstName = nameParts[0];
|
|
1643
|
+
this.options.lastName = nameParts.slice(1).join(' ');
|
|
1644
|
+
}
|
|
1645
|
+
return true;
|
|
1646
|
+
}
|
|
1647
|
+
catch (error) {
|
|
1648
|
+
console.error('[Cuoral] Error updating user profile:', error);
|
|
1649
|
+
return false;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1560
1652
|
/**
|
|
1561
1653
|
* Start native screen recording programmatically
|
|
1562
1654
|
* @returns Promise<boolean> - true if recording started successfully
|
|
@@ -1572,11 +1664,19 @@ class Cuoral {
|
|
|
1572
1664
|
}
|
|
1573
1665
|
/**
|
|
1574
1666
|
* Stop native screen recording programmatically
|
|
1575
|
-
*
|
|
1667
|
+
* Recording will be automatically uploaded to the portal
|
|
1668
|
+
* @returns Promise<{filePath?: string; duration?: number; uploaded?: boolean} | null> - Recording result or null if failed
|
|
1576
1669
|
*/
|
|
1577
1670
|
async stopRecording() {
|
|
1578
1671
|
try {
|
|
1579
|
-
|
|
1672
|
+
const sessionId = localStorage.getItem('__x_loadID');
|
|
1673
|
+
const customerId = localStorage.getItem('cuoralCustomerId');
|
|
1674
|
+
return await this.recorder.stopRecording({
|
|
1675
|
+
autoUpload: true,
|
|
1676
|
+
sessionId: sessionId || undefined,
|
|
1677
|
+
publicKey: this.options.publicKey,
|
|
1678
|
+
customerId: customerId || undefined,
|
|
1679
|
+
});
|
|
1580
1680
|
}
|
|
1581
1681
|
catch (error) {
|
|
1582
1682
|
console.error('[Cuoral] Failed to stop recording:', error);
|
|
@@ -1622,7 +1722,7 @@ class Cuoral {
|
|
|
1622
1722
|
// Add session_id if available
|
|
1623
1723
|
const sessionId = localStorage.getItem('__x_loadID');
|
|
1624
1724
|
if (sessionId) {
|
|
1625
|
-
params.set('
|
|
1725
|
+
params.set('cuoral_mobile_session_id', sessionId);
|
|
1626
1726
|
}
|
|
1627
1727
|
if (this.options.email)
|
|
1628
1728
|
params.set('email', this.options.email);
|
|
@@ -1676,6 +1776,28 @@ class Cuoral {
|
|
|
1676
1776
|
}
|
|
1677
1777
|
}
|
|
1678
1778
|
}
|
|
1779
|
+
/**
|
|
1780
|
+
* Setup localStorage listener for session changes
|
|
1781
|
+
* Widget updates localStorage when creating new session, SDK detects and syncs
|
|
1782
|
+
*/
|
|
1783
|
+
setupStorageListener() {
|
|
1784
|
+
// Poll localStorage every 2 seconds to detect session changes
|
|
1785
|
+
// (storage event doesn't fire for same-window changes)
|
|
1786
|
+
let lastKnownSession = localStorage.getItem('__x_loadID');
|
|
1787
|
+
setInterval(() => {
|
|
1788
|
+
const currentSession = localStorage.getItem('__x_loadID');
|
|
1789
|
+
if (currentSession && currentSession !== lastKnownSession) {
|
|
1790
|
+
console.log('[Cuoral] 🔄 Session changed in localStorage');
|
|
1791
|
+
console.log('[Cuoral] Old session:', lastKnownSession);
|
|
1792
|
+
console.log('[Cuoral] New session:', currentSession);
|
|
1793
|
+
lastKnownSession = currentSession;
|
|
1794
|
+
// Update intelligence to use new session
|
|
1795
|
+
if (this.intelligence) {
|
|
1796
|
+
this.intelligence.updateSessionId(currentSession);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
}, 2000);
|
|
1800
|
+
}
|
|
1679
1801
|
/**
|
|
1680
1802
|
* Clean up resources
|
|
1681
1803
|
*/
|
|
@@ -1767,9 +1889,27 @@ class Cuoral {
|
|
|
1767
1889
|
});
|
|
1768
1890
|
// Handle stop recording requests from widget
|
|
1769
1891
|
this.bridge.on(exports.CuoralMessageType.STOP_RECORDING, async () => {
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
|
|
1892
|
+
const sessionId = localStorage.getItem('__x_loadID');
|
|
1893
|
+
const customerId = localStorage.getItem('cuoralCustomerId');
|
|
1894
|
+
const result = await this.recorder.stopRecording({
|
|
1895
|
+
autoUpload: true,
|
|
1896
|
+
sessionId: sessionId || undefined,
|
|
1897
|
+
publicKey: this.options.publicKey,
|
|
1898
|
+
customerId: customerId || undefined,
|
|
1899
|
+
});
|
|
1900
|
+
if (result && result.uploaded) {
|
|
1901
|
+
// Video was automatically uploaded, just notify widget
|
|
1902
|
+
this.bridge.sendToWidget({
|
|
1903
|
+
type: exports.CuoralMessageType.RECORDING_UPLOADED,
|
|
1904
|
+
payload: {
|
|
1905
|
+
duration: result.duration,
|
|
1906
|
+
uploaded: true,
|
|
1907
|
+
timestamp: Date.now()
|
|
1908
|
+
}
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
else if (result) {
|
|
1912
|
+
// Upload failed or was disabled, send video data to widget (old behavior)
|
|
1773
1913
|
const capacitorUrl = result.filePath ? core.Capacitor.convertFileSrc(result.filePath) : '';
|
|
1774
1914
|
try {
|
|
1775
1915
|
// Fetch the video blob from the capacitor URL
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/intelligence.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export declare class CuoralIntelligence {
|
|
|
17
17
|
private rageClickThreshold;
|
|
18
18
|
private rageClickWindowMs;
|
|
19
19
|
constructor(sessionId: string);
|
|
20
|
+
/**
|
|
21
|
+
* Update the session ID (e.g., when user logs in)
|
|
22
|
+
*/
|
|
23
|
+
updateSessionId(newSessionId: string): void;
|
|
20
24
|
/**
|
|
21
25
|
* Initialize intelligence tracking
|
|
22
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../src/intelligence.ts"],"names":[],"mappings":"AA0EA,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAWZ;IAEF,OAAO,CAAC,MAAM,CAKZ;IAEF,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,qBAAqB,CAAc;IAC3C,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,aAAa,CAAa;IAGlC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,sBAAsB,CAAa;IAG3C,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,SAAS,EAAE,MAAM;IAI7B;;OAEG;IACI,IAAI,IAAI,IAAI;IAgBnB;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAc1D;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAS7E;;OAEG;IACI,KAAK,IAAI,IAAI;IAMpB;;OAEG;IACI,OAAO,IAAI,IAAI;IA0CtB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAoFjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA8H9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../src/intelligence.ts"],"names":[],"mappings":"AA0EA,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAWZ;IAEF,OAAO,CAAC,MAAM,CAKZ;IAEF,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,qBAAqB,CAAc;IAC3C,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,aAAa,CAAa;IAGlC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,sBAAsB,CAAa;IAG3C,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,SAAS,EAAE,MAAM;IAI7B;;OAEG;IACI,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAkBlD;;OAEG;IACI,IAAI,IAAI,IAAI;IAgBnB;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAc1D;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAS7E;;OAEG;IACI,KAAK,IAAI,IAAI;IAMpB;;OAEG;IACI,OAAO,IAAI,IAAI;IA0CtB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAoFjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA8H9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAyCpB;;OAEG;IACH,OAAO,CAAC,UAAU;IAqFlB;;OAEG;YACW,aAAa;IAiC3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiC1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoD1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAwC3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6DzB;;OAEG;IACI,gBAAgB,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EACpC,eAAe,CAAC,EAAE,MAAM,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI;IAgBP;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAwB/B;;OAEG;YACW,sBAAsB;IAkBpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,WAAW;CAOpB"}
|
package/dist/intelligence.js
CHANGED
|
@@ -42,6 +42,24 @@ export class CuoralIntelligence {
|
|
|
42
42
|
this.rageClickWindowMs = 2000; // Within 2 seconds
|
|
43
43
|
this.sessionId = sessionId;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Update the session ID (e.g., when user logs in)
|
|
47
|
+
*/
|
|
48
|
+
updateSessionId(newSessionId) {
|
|
49
|
+
console.log('[Cuoral Intelligence] Updating session ID from', this.sessionId, 'to', newSessionId);
|
|
50
|
+
this.sessionId = newSessionId;
|
|
51
|
+
// Flush any pending events with the old session before switching
|
|
52
|
+
this.flush();
|
|
53
|
+
// Update native error capture with new session ID
|
|
54
|
+
if (Capacitor.isNativePlatform()) {
|
|
55
|
+
CuoralPlugin.setupNativeErrorCapture({
|
|
56
|
+
backendUrl: this.config.consoleErrorBackendUrl,
|
|
57
|
+
sessionId: newSessionId
|
|
58
|
+
}).catch(error => {
|
|
59
|
+
console.warn('[Cuoral Intelligence] Failed to update native error capture:', error);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
45
63
|
/**
|
|
46
64
|
* Initialize intelligence tracking
|
|
47
65
|
*/
|
|
@@ -371,6 +389,7 @@ export class CuoralIntelligence {
|
|
|
371
389
|
url: window.location.href,
|
|
372
390
|
data,
|
|
373
391
|
};
|
|
392
|
+
console.log(`[Intelligence] Enqueuing ${type} event with session:`, this.sessionId);
|
|
374
393
|
queue.push(event);
|
|
375
394
|
// Flush immediately for critical errors
|
|
376
395
|
const shouldFlushImmediately = type === 'api_call' && (data.status_code === 0 || data.status_code >= 400);
|