cuoral-ionic 0.0.1 → 0.0.2
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/README.md +40 -4
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build/.transforms/2c48e1f34ca03014b78fcb3e0ab7197b/results.bin +1 -0
- package/android/build/.transforms/2c48e1f34ca03014b78fcb3e0ab7197b/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/980c51bd075f726f311ad662d5d20ba0/results.bin +1 -0
- package/android/build/.transforms/980c51bd075f726f311ad662d5d20ba0/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/bb54161301273cf9b5b94a21c0fb3f23/results.bin +1 -0
- package/android/build/.transforms/bb54161301273cf9b5b94a21c0fb3f23/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/results.bin +1 -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.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/ScreenRecordService.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/desugar_graph.bin +0 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +22 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_main_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
- package/android/build/intermediates/annotations_typedef_file/debug/typedefs.txt +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/debug-mergeJavaRes/merge-state +0 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -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.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/ScreenRecordService.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +2 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +38 -0
- package/android/build/intermediates/merged_java_res/debug/feature-cuoral-ionic.jar +0 -0
- package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +22 -0
- package/android/build/intermediates/navigation_json/debug/navigation.json +1 -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.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/ScreenRecordService.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +1 -0
- package/android/build/outputs/aar/cuoral-ionic-debug.aar +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +49 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$1.class.uniqueId1 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$2.class.uniqueId2 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin.class.uniqueId0 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +61 -0
- package/android/src/main/AndroidManifest.xml +9 -0
- package/android/src/main/java/com/cuoral/ionic/CuoralPlugin.java +290 -33
- package/android/src/main/java/com/cuoral/ionic/ScreenRecordService.java +59 -0
- package/dist/cuoral.d.ts +30 -1
- package/dist/cuoral.d.ts.map +1 -1
- package/dist/cuoral.js +168 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +706 -127
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +706 -126
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +66 -0
- package/dist/intelligence.d.ts.map +1 -0
- package/dist/intelligence.js +508 -0
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +24 -6
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +0 -3
- package/ios/Plugin/CuoralPlugin.swift +78 -1
- package/package.json +1 -1
- package/src/cuoral.ts +205 -1
- package/src/index.ts +1 -0
- package/src/intelligence.ts +609 -0
- package/src/plugin.ts +26 -6
- package/src/web.ts +0 -6
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export declare class CuoralIntelligence {
|
|
2
|
+
private config;
|
|
3
|
+
private queues;
|
|
4
|
+
private batchTimers;
|
|
5
|
+
private sessionId;
|
|
6
|
+
private isInitialized;
|
|
7
|
+
private lastPageViewTimestamp;
|
|
8
|
+
private lastPageViewScreen;
|
|
9
|
+
private pendingEvents;
|
|
10
|
+
private originalFetch;
|
|
11
|
+
private originalXMLHttpRequest;
|
|
12
|
+
constructor(sessionId: string);
|
|
13
|
+
/**
|
|
14
|
+
* Initialize intelligence tracking
|
|
15
|
+
*/
|
|
16
|
+
init(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Track a page/screen view
|
|
19
|
+
*/
|
|
20
|
+
trackPageView(screen: string, metadata?: any): void;
|
|
21
|
+
/**
|
|
22
|
+
* Track a console error manually
|
|
23
|
+
*/
|
|
24
|
+
trackError(message: string, stackTrace?: string, metadata?: any): void;
|
|
25
|
+
/**
|
|
26
|
+
* Flush all queued events immediately
|
|
27
|
+
*/
|
|
28
|
+
flush(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Destroy and cleanup
|
|
31
|
+
*/
|
|
32
|
+
destroy(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Setup console error listener
|
|
35
|
+
*/
|
|
36
|
+
private setupConsoleErrorListener;
|
|
37
|
+
/**
|
|
38
|
+
* Setup network monitoring
|
|
39
|
+
*/
|
|
40
|
+
private setupNetworkMonitoring;
|
|
41
|
+
/**
|
|
42
|
+
* Setup app state listener
|
|
43
|
+
*/
|
|
44
|
+
private setupAppStateListener;
|
|
45
|
+
/**
|
|
46
|
+
* Enqueue an event
|
|
47
|
+
*/
|
|
48
|
+
private enqueueEvent;
|
|
49
|
+
/**
|
|
50
|
+
* Flush a specific queue
|
|
51
|
+
*/
|
|
52
|
+
private flushQueue;
|
|
53
|
+
/**
|
|
54
|
+
* Send data to backend
|
|
55
|
+
*/
|
|
56
|
+
private sendToBackend;
|
|
57
|
+
/**
|
|
58
|
+
* Flush pending events
|
|
59
|
+
*/
|
|
60
|
+
private flushPendingEvents;
|
|
61
|
+
/**
|
|
62
|
+
* Setup native error capture for Android/iOS crashes
|
|
63
|
+
*/
|
|
64
|
+
private setupNativeErrorCapture;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=intelligence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../src/intelligence.ts"],"names":[],"mappings":"AAsDA,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CASZ;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;gBAE/B,SAAS,EAAE,MAAM;IAI7B;;OAEG;IACI,IAAI,IAAI,IAAI;IAenB;;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;IA4BtB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAoFjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA8H9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAwCpB;;OAEG;IACH,OAAO,CAAC,UAAU;IAoFlB;;OAEG;YACW,aAAa;IAiC3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAgBhC"}
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
import { Capacitor } from '@capacitor/core';
|
|
2
|
+
import { registerPlugin } from '@capacitor/core';
|
|
3
|
+
// Register the Cuoral plugin for native error capture
|
|
4
|
+
const CuoralPlugin = registerPlugin('CuoralPlugin');
|
|
5
|
+
export class CuoralIntelligence {
|
|
6
|
+
constructor(sessionId) {
|
|
7
|
+
this.config = {
|
|
8
|
+
consoleErrorBackendUrl: 'https://api.cuoral.com/customer-intelligence/console-error',
|
|
9
|
+
pageViewBackendUrl: 'https://api.cuoral.com/customer-intelligence/page-view',
|
|
10
|
+
apiResponseBackendUrl: 'https://api.cuoral.com/customer-intelligence/api-response',
|
|
11
|
+
batchSize: 10,
|
|
12
|
+
batchInterval: 2000,
|
|
13
|
+
maxQueueSize: 30,
|
|
14
|
+
retryAttempts: 1,
|
|
15
|
+
retryDelay: 2000,
|
|
16
|
+
};
|
|
17
|
+
this.queues = {
|
|
18
|
+
console_error: [],
|
|
19
|
+
unhandled_error: [],
|
|
20
|
+
page_view: [],
|
|
21
|
+
api_call: [],
|
|
22
|
+
};
|
|
23
|
+
this.batchTimers = {};
|
|
24
|
+
this.sessionId = null;
|
|
25
|
+
this.isInitialized = false;
|
|
26
|
+
this.lastPageViewTimestamp = Date.now();
|
|
27
|
+
this.lastPageViewScreen = '';
|
|
28
|
+
this.pendingEvents = [];
|
|
29
|
+
// Network monitoring state
|
|
30
|
+
this.originalFetch = null;
|
|
31
|
+
this.originalXMLHttpRequest = null;
|
|
32
|
+
this.sessionId = sessionId;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Initialize intelligence tracking
|
|
36
|
+
*/
|
|
37
|
+
init() {
|
|
38
|
+
if (this.isInitialized) {
|
|
39
|
+
console.warn('[Cuoral Intelligence] Already initialized');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.setupConsoleErrorListener();
|
|
43
|
+
this.setupNetworkMonitoring();
|
|
44
|
+
this.setupAppStateListener();
|
|
45
|
+
this.setupNativeErrorCapture();
|
|
46
|
+
this.isInitialized = true;
|
|
47
|
+
this.flushPendingEvents();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Track a page/screen view
|
|
51
|
+
*/
|
|
52
|
+
trackPageView(screen, metadata) {
|
|
53
|
+
const duration = Date.now() - this.lastPageViewTimestamp;
|
|
54
|
+
this.enqueueEvent('page_view', {
|
|
55
|
+
screen,
|
|
56
|
+
referrer: this.lastPageViewScreen,
|
|
57
|
+
duration,
|
|
58
|
+
metadata: metadata || {},
|
|
59
|
+
});
|
|
60
|
+
this.lastPageViewTimestamp = Date.now();
|
|
61
|
+
this.lastPageViewScreen = screen;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Track a console error manually
|
|
65
|
+
*/
|
|
66
|
+
trackError(message, stackTrace, metadata) {
|
|
67
|
+
this.enqueueEvent('console_error', {
|
|
68
|
+
message,
|
|
69
|
+
stack_trace: stackTrace || 'No stack trace available',
|
|
70
|
+
log_level: 'error',
|
|
71
|
+
metadata: metadata || {},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Flush all queued events immediately
|
|
76
|
+
*/
|
|
77
|
+
flush() {
|
|
78
|
+
Object.keys(this.queues).forEach((type) => {
|
|
79
|
+
this.flushQueue(type);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Destroy and cleanup
|
|
84
|
+
*/
|
|
85
|
+
destroy() {
|
|
86
|
+
// Clear all timers
|
|
87
|
+
Object.keys(this.batchTimers).forEach((type) => {
|
|
88
|
+
if (this.batchTimers[type]) {
|
|
89
|
+
clearTimeout(this.batchTimers[type]);
|
|
90
|
+
delete this.batchTimers[type];
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Restore original functions
|
|
94
|
+
if (this.originalFetch) {
|
|
95
|
+
window.fetch = this.originalFetch;
|
|
96
|
+
this.originalFetch = null;
|
|
97
|
+
}
|
|
98
|
+
if (this.originalXMLHttpRequest) {
|
|
99
|
+
window.XMLHttpRequest = this.originalXMLHttpRequest;
|
|
100
|
+
this.originalXMLHttpRequest = null;
|
|
101
|
+
}
|
|
102
|
+
// Clear queues
|
|
103
|
+
Object.keys(this.queues).forEach((type) => {
|
|
104
|
+
this.queues[type] = [];
|
|
105
|
+
});
|
|
106
|
+
this.isInitialized = false;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Setup console error listener
|
|
110
|
+
*/
|
|
111
|
+
setupConsoleErrorListener() {
|
|
112
|
+
// Override console.error
|
|
113
|
+
const originalConsoleError = console.error;
|
|
114
|
+
console.error = (...args) => {
|
|
115
|
+
originalConsoleError.apply(console, args);
|
|
116
|
+
try {
|
|
117
|
+
// Try to find an Error object in arguments to get real stack trace
|
|
118
|
+
let stack = '';
|
|
119
|
+
let message = '';
|
|
120
|
+
// Check each argument for error information
|
|
121
|
+
for (const arg of args) {
|
|
122
|
+
if (arg instanceof Error) {
|
|
123
|
+
stack = arg.stack || '';
|
|
124
|
+
message = arg.message;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
else if (arg && typeof arg === 'object') {
|
|
128
|
+
if (arg.stack && typeof arg.stack === 'string') {
|
|
129
|
+
stack = arg.stack;
|
|
130
|
+
message = arg.message || arg.toString();
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
if (arg.rejection && arg.rejection instanceof Error) {
|
|
134
|
+
stack = arg.rejection.stack || '';
|
|
135
|
+
message = arg.rejection.message;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
if (arg.error instanceof Error) {
|
|
139
|
+
stack = arg.error.stack || '';
|
|
140
|
+
message = arg.error.message;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// If no stack found, generate one from current context
|
|
146
|
+
// Note: Angular's ErrorHandler doesn't pass Error objects, so this will
|
|
147
|
+
// capture the console.error call stack, not the original error stack.
|
|
148
|
+
// For better error tracking, use source maps or test with unminified builds.
|
|
149
|
+
if (!stack) {
|
|
150
|
+
const error = new Error();
|
|
151
|
+
stack = error.stack || 'No stack trace available';
|
|
152
|
+
message = args.map((a) => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' ');
|
|
153
|
+
}
|
|
154
|
+
this.enqueueEvent('console_error', {
|
|
155
|
+
message: message || 'Console error',
|
|
156
|
+
stack_trace: stack,
|
|
157
|
+
log_level: 'error',
|
|
158
|
+
metadata: {},
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
// Silently fail
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
// Global error handler
|
|
166
|
+
window.onerror = (message, source, lineno, colno, error) => {
|
|
167
|
+
try {
|
|
168
|
+
this.enqueueEvent('unhandled_error', {
|
|
169
|
+
message: String(message),
|
|
170
|
+
source: source || 'unknown',
|
|
171
|
+
lineno: lineno || 0,
|
|
172
|
+
colno: colno || 0,
|
|
173
|
+
stack_trace: error?.stack || 'No stack trace available',
|
|
174
|
+
log_level: 'error',
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
// Silently fail
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
};
|
|
182
|
+
// Unhandled promise rejection
|
|
183
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
184
|
+
this.enqueueEvent('unhandled_error', {
|
|
185
|
+
message: event.reason instanceof Error ? event.reason.message : String(event.reason),
|
|
186
|
+
stack_trace: event.reason?.stack || 'No stack trace available',
|
|
187
|
+
log_level: 'error',
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Setup network monitoring
|
|
193
|
+
*/
|
|
194
|
+
setupNetworkMonitoring() {
|
|
195
|
+
// Store original fetch
|
|
196
|
+
if (!this.originalFetch) {
|
|
197
|
+
this.originalFetch = window.fetch;
|
|
198
|
+
}
|
|
199
|
+
// Override fetch
|
|
200
|
+
window.fetch = async (...args) => {
|
|
201
|
+
const url = args[0] instanceof Request ? args[0].url : args[0];
|
|
202
|
+
const method = args[0] instanceof Request && args[0].method
|
|
203
|
+
? args[0].method
|
|
204
|
+
: args[1]?.method || 'GET';
|
|
205
|
+
const startTime = Date.now();
|
|
206
|
+
try {
|
|
207
|
+
const response = await this.originalFetch.apply(window, args);
|
|
208
|
+
const duration = Date.now() - startTime;
|
|
209
|
+
const status = response.status;
|
|
210
|
+
// Only track errors (4xx, 5xx)
|
|
211
|
+
if (status >= 400) {
|
|
212
|
+
const responseClone = response.clone();
|
|
213
|
+
try {
|
|
214
|
+
const text = await responseClone.text();
|
|
215
|
+
let responseData = null;
|
|
216
|
+
try {
|
|
217
|
+
const truncated = text.length > 5000 ? text.substring(0, 5000) + '...' : text;
|
|
218
|
+
responseData = JSON.parse(truncated);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
responseData = text.length > 5000 ? text.substring(0, 5000) + '...' : text;
|
|
222
|
+
}
|
|
223
|
+
this.enqueueEvent('api_call', {
|
|
224
|
+
method,
|
|
225
|
+
url,
|
|
226
|
+
status_code: status,
|
|
227
|
+
response_data: responseData,
|
|
228
|
+
duration,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
this.enqueueEvent('api_call', {
|
|
233
|
+
method,
|
|
234
|
+
url,
|
|
235
|
+
status_code: status,
|
|
236
|
+
duration,
|
|
237
|
+
error: 'Failed to read response body',
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return response;
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
const duration = Date.now() - startTime;
|
|
245
|
+
this.enqueueEvent('api_call', {
|
|
246
|
+
method,
|
|
247
|
+
url,
|
|
248
|
+
status_code: 0,
|
|
249
|
+
response_data: error.message || 'Network Error',
|
|
250
|
+
duration,
|
|
251
|
+
error: error.message || 'Network Error',
|
|
252
|
+
});
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
// Store original XMLHttpRequest
|
|
257
|
+
if (!this.originalXMLHttpRequest && window.XMLHttpRequest) {
|
|
258
|
+
this.originalXMLHttpRequest = window.XMLHttpRequest;
|
|
259
|
+
}
|
|
260
|
+
// Override XMLHttpRequest
|
|
261
|
+
const originalOpen = XMLHttpRequest.prototype.open;
|
|
262
|
+
const originalSend = XMLHttpRequest.prototype.send;
|
|
263
|
+
XMLHttpRequest.prototype.open = function (method, url) {
|
|
264
|
+
this._cuoralMethod = method;
|
|
265
|
+
this._cuoralUrl = url;
|
|
266
|
+
return originalOpen.apply(this, arguments);
|
|
267
|
+
};
|
|
268
|
+
XMLHttpRequest.prototype.send = function () {
|
|
269
|
+
const startTime = Date.now();
|
|
270
|
+
const xhr = this;
|
|
271
|
+
const loadendHandler = () => {
|
|
272
|
+
try {
|
|
273
|
+
const status = xhr.status;
|
|
274
|
+
const duration = Date.now() - startTime;
|
|
275
|
+
// Only track errors (4xx, 5xx)
|
|
276
|
+
if (status >= 400) {
|
|
277
|
+
let responseData = null;
|
|
278
|
+
try {
|
|
279
|
+
const responseText = xhr.responseText || '';
|
|
280
|
+
const truncated = responseText.length > 5000
|
|
281
|
+
? responseText.substring(0, 5000) + '...'
|
|
282
|
+
: responseText;
|
|
283
|
+
responseData = truncated ? JSON.parse(truncated) : truncated;
|
|
284
|
+
}
|
|
285
|
+
catch (e) {
|
|
286
|
+
const responseText = xhr.responseText || '';
|
|
287
|
+
responseData = responseText.length > 5000
|
|
288
|
+
? responseText.substring(0, 5000) + '...'
|
|
289
|
+
: responseText;
|
|
290
|
+
}
|
|
291
|
+
window._cuoralIntelligence?.enqueueEvent('api_call', {
|
|
292
|
+
method: xhr._cuoralMethod,
|
|
293
|
+
url: xhr._cuoralUrl,
|
|
294
|
+
status_code: status,
|
|
295
|
+
response_data: responseData,
|
|
296
|
+
duration,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
// Silently fail
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
this.addEventListener('loadend', loadendHandler, { once: true });
|
|
305
|
+
return originalSend.apply(this, arguments);
|
|
306
|
+
};
|
|
307
|
+
// Store reference for XMLHttpRequest monitoring
|
|
308
|
+
window._cuoralIntelligence = this;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Setup app state listener
|
|
312
|
+
*/
|
|
313
|
+
setupAppStateListener() {
|
|
314
|
+
// Listen for app going to background
|
|
315
|
+
window.addEventListener('visibilitychange', () => {
|
|
316
|
+
if (document.visibilityState === 'hidden') {
|
|
317
|
+
this.flush();
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
// Listen for app pause (Capacitor)
|
|
321
|
+
if (Capacitor.isNativePlatform()) {
|
|
322
|
+
window.addEventListener('pause', () => {
|
|
323
|
+
this.flush();
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Enqueue an event
|
|
329
|
+
*/
|
|
330
|
+
enqueueEvent(type, data) {
|
|
331
|
+
const queue = this.queues[type];
|
|
332
|
+
if (!queue) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
// Don't track successful API calls (2xx, 3xx)
|
|
336
|
+
if (type === 'api_call' && data.status_code >= 200 && data.status_code < 400) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
// Limit queue size
|
|
340
|
+
if (queue.length >= this.config.maxQueueSize) {
|
|
341
|
+
queue.shift();
|
|
342
|
+
}
|
|
343
|
+
const event = {
|
|
344
|
+
event_type: type,
|
|
345
|
+
timestamp: Date.now(),
|
|
346
|
+
session_id: this.sessionId || '',
|
|
347
|
+
user_agent: navigator.userAgent,
|
|
348
|
+
url: window.location.href,
|
|
349
|
+
data,
|
|
350
|
+
};
|
|
351
|
+
queue.push(event);
|
|
352
|
+
// Flush immediately for critical errors
|
|
353
|
+
const shouldFlushImmediately = type === 'api_call' && (data.status_code === 0 || data.status_code >= 400);
|
|
354
|
+
if (shouldFlushImmediately || queue.length >= this.config.batchSize) {
|
|
355
|
+
this.flushQueue(type);
|
|
356
|
+
}
|
|
357
|
+
else if (!this.batchTimers[type]) {
|
|
358
|
+
this.batchTimers[type] = setTimeout(() => this.flushQueue(type), this.config.batchInterval);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Flush a specific queue
|
|
363
|
+
*/
|
|
364
|
+
flushQueue(eventType, useBeacon = false) {
|
|
365
|
+
const queue = this.queues[eventType];
|
|
366
|
+
if (!queue || queue.length === 0) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
// Clear timer
|
|
370
|
+
if (this.batchTimers[eventType]) {
|
|
371
|
+
clearTimeout(this.batchTimers[eventType]);
|
|
372
|
+
delete this.batchTimers[eventType];
|
|
373
|
+
}
|
|
374
|
+
const eventsToProcess = [...queue];
|
|
375
|
+
this.queues[eventType] = [];
|
|
376
|
+
let backendUrl;
|
|
377
|
+
let transformedPayload;
|
|
378
|
+
if (eventType === 'console_error' || eventType === 'unhandled_error') {
|
|
379
|
+
backendUrl = this.config.consoleErrorBackendUrl;
|
|
380
|
+
transformedPayload = eventsToProcess.map((event) => ({
|
|
381
|
+
message: event.data.message,
|
|
382
|
+
stack_trace: event.data.stack_trace,
|
|
383
|
+
log_level: 'error',
|
|
384
|
+
url: event.url,
|
|
385
|
+
session_id: event.session_id,
|
|
386
|
+
source: 'mobile',
|
|
387
|
+
console_metadata: event.data.metadata || {},
|
|
388
|
+
}));
|
|
389
|
+
}
|
|
390
|
+
else if (eventType === 'page_view') {
|
|
391
|
+
backendUrl = this.config.pageViewBackendUrl;
|
|
392
|
+
transformedPayload = eventsToProcess.map((event) => ({
|
|
393
|
+
session_id: event.session_id,
|
|
394
|
+
url: event.data.screen,
|
|
395
|
+
referrer: event.data.referrer,
|
|
396
|
+
user_agent: event.user_agent,
|
|
397
|
+
source: 'mobile',
|
|
398
|
+
page_metadata: {
|
|
399
|
+
duration: event.data.duration,
|
|
400
|
+
screen: event.data.screen,
|
|
401
|
+
...event.data.metadata,
|
|
402
|
+
},
|
|
403
|
+
timestamp: new Date(event.timestamp).toISOString(),
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
else if (eventType === 'api_call') {
|
|
407
|
+
backendUrl = this.config.apiResponseBackendUrl;
|
|
408
|
+
transformedPayload = eventsToProcess
|
|
409
|
+
.map((event) => {
|
|
410
|
+
let responseBody = event.data.response_data;
|
|
411
|
+
if (typeof responseBody === 'string') {
|
|
412
|
+
try {
|
|
413
|
+
responseBody = JSON.parse(responseBody);
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
responseBody = { raw_text: responseBody };
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else if (responseBody === null || typeof responseBody === 'undefined') {
|
|
420
|
+
responseBody = {};
|
|
421
|
+
}
|
|
422
|
+
return {
|
|
423
|
+
url: event.data.url,
|
|
424
|
+
method: event.data.method,
|
|
425
|
+
status_code: event.data.status_code,
|
|
426
|
+
response_body: responseBody,
|
|
427
|
+
session_id: event.session_id,
|
|
428
|
+
source: 'mobile',
|
|
429
|
+
api_metadata: {
|
|
430
|
+
duration: event.data.duration,
|
|
431
|
+
error: event.data.error || null,
|
|
432
|
+
},
|
|
433
|
+
};
|
|
434
|
+
})
|
|
435
|
+
.filter((item) => item !== null && item !== undefined);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const filteredPayload = transformedPayload.filter((item) => item !== null && item !== undefined);
|
|
441
|
+
if (backendUrl && filteredPayload.length > 0) {
|
|
442
|
+
this.sendToBackend(backendUrl, filteredPayload, useBeacon);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Send data to backend
|
|
447
|
+
*/
|
|
448
|
+
async sendToBackend(url, payload, useBeacon = false, retryCount = 0) {
|
|
449
|
+
if (!this.sessionId) {
|
|
450
|
+
this.pendingEvents.push({ url, payload, useBeacon });
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (!navigator.onLine) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const data = JSON.stringify(payload);
|
|
457
|
+
const headers = {
|
|
458
|
+
'Content-Type': 'application/json',
|
|
459
|
+
};
|
|
460
|
+
try {
|
|
461
|
+
const response = await fetch(url, {
|
|
462
|
+
method: 'POST',
|
|
463
|
+
headers,
|
|
464
|
+
body: data,
|
|
465
|
+
keepalive: useBeacon,
|
|
466
|
+
});
|
|
467
|
+
if (!response.ok && retryCount < this.config.retryAttempts) {
|
|
468
|
+
setTimeout(() => {
|
|
469
|
+
this.sendToBackend(url, payload, false, retryCount + 1);
|
|
470
|
+
}, this.config.retryDelay);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
// Silently fail
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Flush pending events
|
|
479
|
+
*/
|
|
480
|
+
flushPendingEvents() {
|
|
481
|
+
if (this.pendingEvents.length > 0) {
|
|
482
|
+
const pending = [...this.pendingEvents];
|
|
483
|
+
this.pendingEvents = [];
|
|
484
|
+
pending.forEach(({ url, payload, useBeacon }) => {
|
|
485
|
+
this.sendToBackend(url, payload, useBeacon);
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Setup native error capture for Android/iOS crashes
|
|
491
|
+
*/
|
|
492
|
+
setupNativeErrorCapture() {
|
|
493
|
+
try {
|
|
494
|
+
// Only run on native platforms and if we have a session ID
|
|
495
|
+
if (Capacitor.isNativePlatform() && this.sessionId) {
|
|
496
|
+
CuoralPlugin.setupNativeErrorCapture({
|
|
497
|
+
backendUrl: this.config.consoleErrorBackendUrl,
|
|
498
|
+
sessionId: this.sessionId,
|
|
499
|
+
}).catch(() => {
|
|
500
|
+
// Silently fail - native error capture optional
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
// Silently fail if plugin is not available
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
package/dist/plugin.d.ts
CHANGED
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAE1E;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAErF;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAE7C;;OAEG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAErE;;OAEG;IACH,oBAAoB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAExD;;OAEG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAE1E;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAErF;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAE7C;;OAEG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAErE;;OAEG;IACH,oBAAoB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAExD;;OAEG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,uBAAwD,CAAC;AAE3E,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,kBAAkB,CAAC,CAAS;IAEpC;;OAEG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAyDlE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAiD/E;;OAEG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAqBjF;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAIzC;;OAEG;IACH,OAAO,CAAC,WAAW;CAKpB"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { registerPlugin } from '@capacitor/core';
|
|
2
2
|
import { CuoralMessageType, } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* Register the Capacitor plugin
|
|
4
|
+
* Register the Capacitor plugin (mobile only - iOS and Android)
|
|
5
5
|
*/
|
|
6
|
-
const CuoralPlugin = registerPlugin('CuoralPlugin'
|
|
7
|
-
web: () => import('./web').then(m => new m.CuoralPluginWeb()),
|
|
8
|
-
});
|
|
6
|
+
const CuoralPlugin = registerPlugin('CuoralPlugin');
|
|
9
7
|
export { CuoralPlugin };
|
|
10
8
|
/**
|
|
11
9
|
* High-level API for easier integration
|
|
@@ -45,10 +43,21 @@ export class CuoralRecorder {
|
|
|
45
43
|
payload: { timestamp: this.recordingStartTime },
|
|
46
44
|
});
|
|
47
45
|
}
|
|
46
|
+
else {
|
|
47
|
+
// Recording failed - reset state and notify widget
|
|
48
|
+
this.isRecording = false;
|
|
49
|
+
this.recordingStartTime = undefined;
|
|
50
|
+
this.postMessage({
|
|
51
|
+
type: CuoralMessageType.RECORDING_ERROR,
|
|
52
|
+
payload: { error: 'Failed to start recording' },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
48
55
|
return result.success;
|
|
49
56
|
}
|
|
50
57
|
catch (error) {
|
|
51
|
-
|
|
58
|
+
// Exception occurred - reset state and notify widget
|
|
59
|
+
this.isRecording = false;
|
|
60
|
+
this.recordingStartTime = undefined;
|
|
52
61
|
this.postMessage({
|
|
53
62
|
type: CuoralMessageType.RECORDING_ERROR,
|
|
54
63
|
payload: { error: error.message },
|
|
@@ -62,7 +71,11 @@ export class CuoralRecorder {
|
|
|
62
71
|
async stopRecording() {
|
|
63
72
|
try {
|
|
64
73
|
if (!this.isRecording) {
|
|
65
|
-
|
|
74
|
+
// Send error message to widget so it can exit "stopping" state
|
|
75
|
+
this.postMessage({
|
|
76
|
+
type: CuoralMessageType.RECORDING_ERROR,
|
|
77
|
+
payload: { error: 'Not recording' },
|
|
78
|
+
});
|
|
66
79
|
return null;
|
|
67
80
|
}
|
|
68
81
|
const result = await CuoralPlugin.stopRecording();
|
|
@@ -84,6 +97,11 @@ export class CuoralRecorder {
|
|
|
84
97
|
duration: result.duration || duration,
|
|
85
98
|
};
|
|
86
99
|
}
|
|
100
|
+
// If result.success is false, send error to widget
|
|
101
|
+
this.postMessage({
|
|
102
|
+
type: CuoralMessageType.RECORDING_ERROR,
|
|
103
|
+
payload: { error: 'Failed to stop recording' },
|
|
104
|
+
});
|
|
87
105
|
return null;
|
|
88
106
|
}
|
|
89
107
|
catch (error) {
|
package/dist/web.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAU,YAAW,qBAAqB;IAC7E,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAS;IAE9B,cAAc,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAU,YAAW,qBAAqB;IAC7E,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAS;IAE9B,cAAc,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IA0BzE,aAAa,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAyBpF,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IAS5C,cAAc,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IA2CpE,oBAAoB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAKvD,kBAAkB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAI1D"}
|