@jaak.ai/stamps 2.1.0-dev.7 → 2.1.0-dev.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +364 -11
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/my-component/my-component.js +254 -6
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/DetectionService.js +146 -7
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/collection/services/interfaces/IDetectionService.js.map +1 -1
- package/dist/components/jaak-stamps.js +367 -12
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps-webcomponent.js +1 -1
- package/dist/esm/jaak-stamps.entry.js +364 -11
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-8e25497e.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-8e25497e.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +27 -0
- package/dist/types/components.d.ts +3 -1
- package/dist/types/services/DetectionService.d.ts +9 -1
- package/dist/types/services/interfaces/IDetectionService.d.ts +6 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-be6b6ca3.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-be6b6ca3.entry.js.map +0 -1
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -5,7 +5,7 @@ var index = require('./index-BfhtOB0D.js');
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await index.globalScripts();
|
|
8
|
-
return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"useDocumentDetector":[4,"use-document-detector"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[32],"performanceDegradedMode":[32],"showPerformanceMessage":[32],"captureStateVersion":[32],"processingButton":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64]}]]]], options);
|
|
8
|
+
return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"useDocumentDetector":[4,"use-document-detector"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[32],"performanceDegradedMode":[32],"showPerformanceMessage":[32],"captureStateVersion":[32],"processingButton":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64],"getResourceReport":[64],"forceResourceCleanup":[64]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
exports.setNonce = index.setNonce;
|
|
@@ -411,7 +411,13 @@ export class JaakStamps {
|
|
|
411
411
|
}
|
|
412
412
|
try {
|
|
413
413
|
this.exitSession();
|
|
414
|
-
|
|
414
|
+
// Aggressive cleanup when stopping capture
|
|
415
|
+
const cleanupResult = await this.aggressiveResourceCleanup();
|
|
416
|
+
return {
|
|
417
|
+
success: true,
|
|
418
|
+
resourcesFreed: cleanupResult.freed,
|
|
419
|
+
cleanupErrors: cleanupResult.errors
|
|
420
|
+
};
|
|
415
421
|
}
|
|
416
422
|
catch (error) {
|
|
417
423
|
return { success: false, error: error.message };
|
|
@@ -636,6 +642,29 @@ export class JaakStamps {
|
|
|
636
642
|
// Always allow getting capture delay, even during initialization
|
|
637
643
|
return this.captureDelay;
|
|
638
644
|
}
|
|
645
|
+
async getResourceReport() {
|
|
646
|
+
// Public method to get resource usage report
|
|
647
|
+
return this.getResourceReportInternal();
|
|
648
|
+
}
|
|
649
|
+
async forceResourceCleanup() {
|
|
650
|
+
// Public method to force aggressive resource cleanup
|
|
651
|
+
const readyCheck = this.isComponentReady();
|
|
652
|
+
if (!readyCheck.ready) {
|
|
653
|
+
return { success: false, error: readyCheck.message };
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
const cleanupResult = await this.aggressiveResourceCleanup();
|
|
657
|
+
return {
|
|
658
|
+
success: true,
|
|
659
|
+
resourcesFreed: cleanupResult.freed,
|
|
660
|
+
errors: cleanupResult.errors,
|
|
661
|
+
timestamp: new Date().toISOString()
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
catch (error) {
|
|
665
|
+
return { success: false, error: error.message };
|
|
666
|
+
}
|
|
667
|
+
}
|
|
639
668
|
// Memory and device capability detection
|
|
640
669
|
checkDeviceCapabilities() {
|
|
641
670
|
const deviceMemory = navigator.deviceMemory;
|
|
@@ -971,11 +1000,182 @@ export class JaakStamps {
|
|
|
971
1000
|
}
|
|
972
1001
|
// Clear canvas pool
|
|
973
1002
|
this.canvasPool = [];
|
|
1003
|
+
// Clean DOM references and memory leaks
|
|
1004
|
+
this.cleanupDOMReferences();
|
|
974
1005
|
this.detectionBoxes = [];
|
|
975
1006
|
this.alignmentStartTime = undefined;
|
|
976
1007
|
this.hasDocumentDetected = false;
|
|
977
1008
|
this.serviceContainer?.cleanup();
|
|
978
1009
|
}
|
|
1010
|
+
// AGGRESSIVE RESOURCE CLEANUP METHODS
|
|
1011
|
+
// Clean DOM references and memory leaks
|
|
1012
|
+
cleanupDOMReferences() {
|
|
1013
|
+
// Remove event listeners that could maintain references
|
|
1014
|
+
if (this.videoRef) {
|
|
1015
|
+
// Remove common event listeners (if any were added)
|
|
1016
|
+
this.videoRef.srcObject = null;
|
|
1017
|
+
this.videoRef = undefined;
|
|
1018
|
+
}
|
|
1019
|
+
// Clean detection container
|
|
1020
|
+
if (this.detectionContainer) {
|
|
1021
|
+
this.detectionContainer = undefined;
|
|
1022
|
+
}
|
|
1023
|
+
// Clean references to images in the DOM and revoke blob URLs
|
|
1024
|
+
const images = this.el.shadowRoot?.querySelectorAll('img');
|
|
1025
|
+
images?.forEach(img => {
|
|
1026
|
+
if (img.src.startsWith('blob:')) {
|
|
1027
|
+
URL.revokeObjectURL(img.src);
|
|
1028
|
+
}
|
|
1029
|
+
img.src = '';
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
// Clear browser cache and storage
|
|
1033
|
+
async clearBrowserCache() {
|
|
1034
|
+
try {
|
|
1035
|
+
// 1. Clear Service Worker cache if exists
|
|
1036
|
+
if ('serviceWorker' in navigator) {
|
|
1037
|
+
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
1038
|
+
await Promise.all(registrations.map(registration => registration.unregister()));
|
|
1039
|
+
}
|
|
1040
|
+
// 2. Clear Cache API specific to the component
|
|
1041
|
+
const cacheNames = await caches.keys();
|
|
1042
|
+
const componentCaches = cacheNames.filter(name => name.includes('jaak') || name.includes('stamps'));
|
|
1043
|
+
await Promise.all(componentCaches.map(cacheName => caches.delete(cacheName)));
|
|
1044
|
+
// 3. Force garbage collection if available (only in dev)
|
|
1045
|
+
if (this.debug && window.gc) {
|
|
1046
|
+
window.gc();
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
catch (error) {
|
|
1050
|
+
console.warn('Error clearing browser cache:', error);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
// Clear local storage specific to the component
|
|
1054
|
+
async clearLocalStorage() {
|
|
1055
|
+
try {
|
|
1056
|
+
// Clear localStorage specific to the component
|
|
1057
|
+
const keysToRemove = [];
|
|
1058
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
1059
|
+
const key = localStorage.key(i);
|
|
1060
|
+
if (key && (key.includes('jaak') || key.includes('onnx') || key.includes('stamps'))) {
|
|
1061
|
+
keysToRemove.push(key);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
keysToRemove.forEach(key => localStorage.removeItem(key));
|
|
1065
|
+
// Clear sessionStorage
|
|
1066
|
+
const sessionKeysToRemove = [];
|
|
1067
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
1068
|
+
const key = sessionStorage.key(i);
|
|
1069
|
+
if (key && (key.includes('jaak') || key.includes('onnx'))) {
|
|
1070
|
+
sessionKeysToRemove.push(key);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
sessionKeysToRemove.forEach(key => sessionStorage.removeItem(key));
|
|
1074
|
+
}
|
|
1075
|
+
catch (error) {
|
|
1076
|
+
console.warn('Error clearing local storage:', error);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
// Aggressive resource cleanup combining all strategies
|
|
1080
|
+
async aggressiveResourceCleanup() {
|
|
1081
|
+
const freed = [];
|
|
1082
|
+
const errors = [];
|
|
1083
|
+
try {
|
|
1084
|
+
// 1. Release ONNX resources
|
|
1085
|
+
this.releaseOnnxResources();
|
|
1086
|
+
freed.push('ONNX models');
|
|
1087
|
+
// 2. Clear model cache in detection service
|
|
1088
|
+
if (this.detectionService) {
|
|
1089
|
+
await this.detectionService.clearModelCache();
|
|
1090
|
+
freed.push('Model cache');
|
|
1091
|
+
}
|
|
1092
|
+
// 3. Clear browser cache
|
|
1093
|
+
await this.clearBrowserCache();
|
|
1094
|
+
freed.push('Browser cache');
|
|
1095
|
+
// 4. Clear local storage
|
|
1096
|
+
await this.clearLocalStorage();
|
|
1097
|
+
freed.push('Local storage');
|
|
1098
|
+
// 5. Clean DOM references
|
|
1099
|
+
this.cleanupDOMReferences();
|
|
1100
|
+
freed.push('DOM references');
|
|
1101
|
+
// 6. Optimize canvas pools
|
|
1102
|
+
if (this.detectionService) {
|
|
1103
|
+
this.detectionService.optimizeCanvasPool(0);
|
|
1104
|
+
freed.push('Canvas pools');
|
|
1105
|
+
}
|
|
1106
|
+
// 7. Clear component canvas pool
|
|
1107
|
+
this.canvasPool = [];
|
|
1108
|
+
freed.push('Component canvas pool');
|
|
1109
|
+
// 8. Force garbage collection (if available)
|
|
1110
|
+
if (this.debug && window.gc) {
|
|
1111
|
+
window.gc();
|
|
1112
|
+
freed.push('Garbage collection');
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
catch (error) {
|
|
1116
|
+
errors.push(error.message);
|
|
1117
|
+
}
|
|
1118
|
+
return { freed, errors };
|
|
1119
|
+
}
|
|
1120
|
+
// Progressive resource release after front capture
|
|
1121
|
+
async onFrontCaptureComplete() {
|
|
1122
|
+
try {
|
|
1123
|
+
// Release classification model if not needed for back
|
|
1124
|
+
if (this.detectionService && !this.useDocumentClassification) {
|
|
1125
|
+
await this.detectionService.releaseMobileNetResources();
|
|
1126
|
+
}
|
|
1127
|
+
// Optimize canvas pool to minimum needed for back capture
|
|
1128
|
+
if (this.detectionService) {
|
|
1129
|
+
this.detectionService.optimizeCanvasPool(1);
|
|
1130
|
+
}
|
|
1131
|
+
// Reduce component canvas pool
|
|
1132
|
+
while (this.canvasPool.length > 1) {
|
|
1133
|
+
const canvas = this.canvasPool.pop();
|
|
1134
|
+
if (canvas) {
|
|
1135
|
+
const ctx = canvas.getContext('2d');
|
|
1136
|
+
if (ctx) {
|
|
1137
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (this.debug) {
|
|
1142
|
+
console.log('🧹 Progressive cleanup after front capture completed');
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
catch (error) {
|
|
1146
|
+
console.warn('Error in progressive cleanup:', error);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// Resource reporting for debugging
|
|
1150
|
+
getResourceReportInternal() {
|
|
1151
|
+
const report = {
|
|
1152
|
+
timestamp: new Date().toISOString(),
|
|
1153
|
+
component: {
|
|
1154
|
+
hasVideoStream: !!this.videoStream,
|
|
1155
|
+
hasAnimationFrame: !!this.animationId,
|
|
1156
|
+
canvasPoolSize: this.canvasPool.length,
|
|
1157
|
+
detectionBoxesCount: this.detectionBoxes.length,
|
|
1158
|
+
performanceMonitorActive: !!this.performanceUpdateInterval
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
// Add detection service stats if available
|
|
1162
|
+
if (this.detectionService) {
|
|
1163
|
+
report.detectionService = {
|
|
1164
|
+
isModelLoaded: this.detectionService.isModelLoaded(),
|
|
1165
|
+
canvasPoolStats: this.detectionService.getPoolStats()
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
// Add memory info if available
|
|
1169
|
+
if ('memory' in performance) {
|
|
1170
|
+
const memInfo = performance.memory;
|
|
1171
|
+
report.memory = {
|
|
1172
|
+
usedJSHeapSize: Math.round(memInfo.usedJSHeapSize / 1048576), // MB
|
|
1173
|
+
totalJSHeapSize: Math.round(memInfo.totalJSHeapSize / 1048576), // MB
|
|
1174
|
+
jsHeapSizeLimit: Math.round(memInfo.jsHeapSizeLimit / 1048576) // MB
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
return report;
|
|
1178
|
+
}
|
|
979
1179
|
render() {
|
|
980
1180
|
const captureState = this.stateManager?.getCaptureState() || {
|
|
981
1181
|
isVideoActive: false,
|
|
@@ -986,7 +1186,7 @@ export class JaakStamps {
|
|
|
986
1186
|
isCapturing: false
|
|
987
1187
|
};
|
|
988
1188
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
989
|
-
return (h("div", { key: '
|
|
1189
|
+
return (h("div", { key: 'ca44b9eacbde9f688f2c41aa21ad35a2b882002b', class: "detector-container" }, h("div", { key: '86c7b5d31ed69276b62fa43e01c92b0c0b9f298d', class: "video-container" }, h("video", { key: 'bb310544c17ae734d8b42ed2617748c2f69743ff', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: '078a79a0c6386ca6c040e629acbf4f52f12d8e29', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
|
|
990
1190
|
position: 'absolute',
|
|
991
1191
|
left: `${box.x}px`,
|
|
992
1192
|
top: `${box.y}px`,
|
|
@@ -995,9 +1195,9 @@ export class JaakStamps {
|
|
|
995
1195
|
border: '2px solid #32406C',
|
|
996
1196
|
pointerEvents: 'none',
|
|
997
1197
|
boxSizing: 'border-box'
|
|
998
|
-
} })))), this.isMaskReady && (h("div", { key: '
|
|
1198
|
+
} })))), this.isMaskReady && (h("div", { key: '990015ff5b2ded89405dd2b891c027aad8788f3e', class: "overlay-mask" }, h("div", { key: 'dd9145140987addb1b6e4cc2119b8e9f89003726', class: "card-outline" }, h("div", { key: 'e8f4ec692a8b80c7a98075e4f708b79a272db67b', class: "side side-top" }), h("div", { key: '2577253b40425ecdcb3dd51b2f4a43c15c83ca79', class: "side side-right" }), h("div", { key: '30f4454020c00cf4fb92308af5ecf1843ec24005', class: "side side-bottom" }), h("div", { key: '3459f634987b8396106fff23fa1c99b295ee7d0a', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '84f4d70947e211a9c6b296531d53420223d2ca34', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '7c28e86e8de6c33bf7d7baab3083c5f6a0ab060f', class: "back-capture-section" }, h("div", { key: '27bdcf9cfe9790c4bbad484423f6f4c353ccf0b3', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode) && (h("button", { key: 'ed0320b1df412bf53cbe4e4119f6d769926eb2c5', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '0bba706c8ebda59c33faca8e97b7536146462d21', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'b072c46b25d16a04c5e0a8f3975d8aa8d24576d5', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'efd0827d0f19c9072d49d1b3c0046ef6c95a842c', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
999
1199
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
1000
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '
|
|
1200
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: 'bd0303e8ce85211e4c68fc3cd79545db7c74288b', class: "camera-controls" }, h("button", { key: 'e4327d260b988b67e0de3654c72f24455cd3bbbd', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: '35da16baf4c62466c2a66650209a1daf842c0db2', class: "camera-selector-dropdown" }, h("div", { key: '7035dd0e22f614cf239a015c6d59531b68fa74a9', class: "camera-selector-header" }, h("span", { key: 'ae026f31931f52ea0daf72391a9de4ff9e4b88f1' }, "Seleccionar C\u00E1mara"), h("button", { key: '40f2ba0770bafea71fedbf849938010e743be776', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '6f26927094a724a35ebb07ef701caf14f296a837', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '082236981c369f8fd487f036439b16e6560514be', class: "device-info" }, h("small", { key: 'ccbbfa0bca96395f574bda71103338ae9226f709' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '6baa487409503777e90453b39fd30649941cbbe4', class: "manual-capture-section" }, h("button", { key: '893f4715ca3315613f779603f178459955f686f0', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '7c30b680fe84f4c8227beba45d8416f1edb8348f', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: 'd8ef052cf67d7bda4b3534febf96efa2cdcc6bf7', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '3dae7634e770dda2655b1042ec8fb997b3cb2220', class: "flip-animation" }, h("div", { key: 'a977fc5e889369121bacc06cf5213dfee39d858d', class: "id-card-icon" }), h("div", { key: '4f052cdc8c7b493cddce90e108e976325c9bab8e', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '5117cd6e63e1e0763c1503f6f60f3c7ef60dd665', class: "success-animation" }, h("div", { key: 'd11128c45c7118915cc0dd9c25845bb55b4b3eb2', class: "check-icon" }), h("div", { key: '693e197bf8a4c91ac7ddedb457d15aa3aa46a5d5', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '89caaa9d78eb522e0fadfd1c0e844e05d29b8286', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '3f41d40b05b71e13e7e1d0c0e980b48308cba9d6', class: "status-spinner" })), h("div", { key: '8674480928f4f4a77099c0600ed84f0e27903379', class: "status-content" }, h("div", { key: 'e88f4044ab8115a6a5cbb78cc4030975eef9149a', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'ad581e42c30c304b837711549148c11b801dee5e', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '1b371c1b47f3ba699885db00fef52eb448f9e245', class: "performance-monitor" }, h("div", { key: '8b9ac60449a15e9fb966c329b2e6c9285c0228c0', class: "performance-expanded" }, h("div", { key: '760c11a3ed28e248a144d53a92fd8adee6822ff2', class: "metrics-row" }, h("div", { key: '858ab8b106f1d12210e4e15c423ab3bab11bdb60', class: "metric-compact" }, h("span", { key: '65fe2479c3822d99452e7e5faa93c25a80765024', class: "metric-label" }, "FPS"), h("span", { key: '9faf7763d1284a6f3c1e15fb0f3c99f1d45bb4dc', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'c95ed8fa8101f42bfba5cc8ca7debbad028caf42', class: "metric-compact" }, h("span", { key: '3555b3778cb71e959d132d6aa563f58f757915d8', class: "metric-label" }, "MEM"), h("span", { key: 'd72b0491147a6f80dcf33f5d72dd8dae5898f44a', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: 'cd4dc81f28f9e59a36a0295dde7bfee89f50d3e2', class: "metrics-row" }, h("div", { key: 'c43d8624c5da256ce3e97f67b022bdd98fb04e07', class: "metric-compact" }, h("span", { key: 'adb402d83809a90580b81544f31b5331bdff59dd', class: "metric-label" }, "INF"), h("span", { key: 'e48c9814c08acbe321460a29e42cb49b0eab38ff', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '71517f9279e9a6aa0d5b02e2169db868ca3fb676', class: "metric-compact" }, h("span", { key: '3ddbcc56b137aea702a40f900178e8e16efd146e', class: "metric-label" }, "FRAME"), h("span", { key: 'd3a70afb511d3f72b485b3a1cb922876faa62b11', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'a3b62cdbe830b1024ab96f7fb726825df24fecdc', class: "metrics-row" }, h("div", { key: '95471e5cdde748d1ce6bdee3540740dd3aa66865', class: "metric-compact" }, h("span", { key: 'c93e01c0bdc67621c3a666357d2477b7a5275d52', class: "metric-label" }, "DET"), h("span", { key: 'ef33c86a83101b0989b14c7f1ab0ce0b331b397f', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'e14d56128bf96337e4c3859f8e4003e001e8e953', class: "metric-compact" }, h("span", { key: '8aa828632f0a977a27ed377f103bb8d5e7e0ed1a', class: "metric-label" }, "RATE"), h("span", { key: '59035c473b5a747a27f774e2554322a084b6d19f', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '4d0c2de00954416faac30ab622fb21f36c932aca', class: "watermark" }, h("img", { key: 'd8f775428ebb3ba86a943ca73b074db2180d0c29', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
|
|
1001
1201
|
}
|
|
1002
1202
|
// Utility methods
|
|
1003
1203
|
updateDetectionBoxes(boxes) {
|
|
@@ -1221,6 +1421,8 @@ export class JaakStamps {
|
|
|
1221
1421
|
showFlipAnimation: true
|
|
1222
1422
|
});
|
|
1223
1423
|
this.triggerRerender();
|
|
1424
|
+
// Progressive resource cleanup after front capture
|
|
1425
|
+
await this.onFrontCaptureComplete();
|
|
1224
1426
|
setTimeout(() => {
|
|
1225
1427
|
this.stateManager.updateCaptureState({
|
|
1226
1428
|
showFlipAnimation: false,
|
|
@@ -1296,6 +1498,8 @@ export class JaakStamps {
|
|
|
1296
1498
|
isDetectionPaused: true,
|
|
1297
1499
|
showFlipAnimation: true
|
|
1298
1500
|
});
|
|
1501
|
+
// Progressive resource cleanup after front capture
|
|
1502
|
+
await this.onFrontCaptureComplete();
|
|
1299
1503
|
setTimeout(() => {
|
|
1300
1504
|
this.stateManager.updateCaptureState({
|
|
1301
1505
|
showFlipAnimation: false,
|
|
@@ -1473,6 +1677,16 @@ export class JaakStamps {
|
|
|
1473
1677
|
setTimeout(() => {
|
|
1474
1678
|
this.stateManager.updateCaptureState({ showSuccessAnimation: false });
|
|
1475
1679
|
}, 3000);
|
|
1680
|
+
// Aggressive cleanup after process completion with delay
|
|
1681
|
+
setTimeout(async () => {
|
|
1682
|
+
const cleanupResult = await this.aggressiveResourceCleanup();
|
|
1683
|
+
if (this.debug) {
|
|
1684
|
+
console.log('🧹 Post-completion cleanup:', cleanupResult.freed);
|
|
1685
|
+
if (cleanupResult.errors.length > 0) {
|
|
1686
|
+
console.warn('⚠️ Cleanup errors:', cleanupResult.errors);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
}, 1000); // Wait 1 second after completion
|
|
1476
1690
|
}
|
|
1477
1691
|
stopDetection() {
|
|
1478
1692
|
if (this.animationId) {
|
|
@@ -2054,7 +2268,7 @@ export class JaakStamps {
|
|
|
2054
2268
|
},
|
|
2055
2269
|
"stopCapture": {
|
|
2056
2270
|
"complexType": {
|
|
2057
|
-
"signature": "() => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>",
|
|
2271
|
+
"signature": "() => Promise<{ success: boolean; resourcesFreed: string[]; cleanupErrors: string[]; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; cleanupErrors?: undefined; }>",
|
|
2058
2272
|
"parameters": [],
|
|
2059
2273
|
"references": {
|
|
2060
2274
|
"Promise": {
|
|
@@ -2062,7 +2276,7 @@ export class JaakStamps {
|
|
|
2062
2276
|
"id": "global::Promise"
|
|
2063
2277
|
}
|
|
2064
2278
|
},
|
|
2065
|
-
"return": "Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>"
|
|
2279
|
+
"return": "Promise<{ success: boolean; resourcesFreed: string[]; cleanupErrors: string[]; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; cleanupErrors?: undefined; }>"
|
|
2066
2280
|
},
|
|
2067
2281
|
"docs": {
|
|
2068
2282
|
"text": "",
|
|
@@ -2222,6 +2436,40 @@ export class JaakStamps {
|
|
|
2222
2436
|
"text": "",
|
|
2223
2437
|
"tags": []
|
|
2224
2438
|
}
|
|
2439
|
+
},
|
|
2440
|
+
"getResourceReport": {
|
|
2441
|
+
"complexType": {
|
|
2442
|
+
"signature": "() => Promise<any>",
|
|
2443
|
+
"parameters": [],
|
|
2444
|
+
"references": {
|
|
2445
|
+
"Promise": {
|
|
2446
|
+
"location": "global",
|
|
2447
|
+
"id": "global::Promise"
|
|
2448
|
+
}
|
|
2449
|
+
},
|
|
2450
|
+
"return": "Promise<any>"
|
|
2451
|
+
},
|
|
2452
|
+
"docs": {
|
|
2453
|
+
"text": "",
|
|
2454
|
+
"tags": []
|
|
2455
|
+
}
|
|
2456
|
+
},
|
|
2457
|
+
"forceResourceCleanup": {
|
|
2458
|
+
"complexType": {
|
|
2459
|
+
"signature": "() => Promise<{ success: boolean; resourcesFreed: string[]; errors: string[]; timestamp: string; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; errors?: undefined; timestamp?: undefined; }>",
|
|
2460
|
+
"parameters": [],
|
|
2461
|
+
"references": {
|
|
2462
|
+
"Promise": {
|
|
2463
|
+
"location": "global",
|
|
2464
|
+
"id": "global::Promise"
|
|
2465
|
+
}
|
|
2466
|
+
},
|
|
2467
|
+
"return": "Promise<{ success: boolean; resourcesFreed: string[]; errors: string[]; timestamp: string; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; errors?: undefined; timestamp?: undefined; }>"
|
|
2468
|
+
},
|
|
2469
|
+
"docs": {
|
|
2470
|
+
"text": "",
|
|
2471
|
+
"tags": []
|
|
2472
|
+
}
|
|
2225
2473
|
}
|
|
2226
2474
|
};
|
|
2227
2475
|
}
|