@jaak.ai/stamps 2.1.0-dev.7 → 2.1.0-dev.9
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 +377 -17
- 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 +265 -12
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/DetectionService.js +148 -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 +380 -18
- 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 +377 -17
- 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-c115e01a.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-c115e01a.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;
|
|
@@ -659,13 +688,18 @@ export class JaakStamps {
|
|
|
659
688
|
memoryMB: null
|
|
660
689
|
};
|
|
661
690
|
}
|
|
662
|
-
// Safari
|
|
691
|
+
// Safari moderno soporta WASM, solo bloquearlo en versiones muy antiguas
|
|
663
692
|
if (isSafari) {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
693
|
+
const safariMatch = navigator.userAgent.match(/Version\/(\d+)/);
|
|
694
|
+
const safariVersion = safariMatch ? parseInt(safariMatch[1]) : 0;
|
|
695
|
+
// Solo bloquear Safari muy antiguo (< version 14)
|
|
696
|
+
if (safariVersion > 0 && safariVersion < 14) {
|
|
697
|
+
return {
|
|
698
|
+
canUseML: false,
|
|
699
|
+
reason: 'Safari antiguo detectado. Modo manual activado por compatibilidad.',
|
|
700
|
+
memoryMB: null
|
|
701
|
+
};
|
|
702
|
+
}
|
|
669
703
|
}
|
|
670
704
|
return {
|
|
671
705
|
canUseML: true,
|
|
@@ -971,11 +1005,182 @@ export class JaakStamps {
|
|
|
971
1005
|
}
|
|
972
1006
|
// Clear canvas pool
|
|
973
1007
|
this.canvasPool = [];
|
|
1008
|
+
// Clean DOM references and memory leaks
|
|
1009
|
+
this.cleanupDOMReferences();
|
|
974
1010
|
this.detectionBoxes = [];
|
|
975
1011
|
this.alignmentStartTime = undefined;
|
|
976
1012
|
this.hasDocumentDetected = false;
|
|
977
1013
|
this.serviceContainer?.cleanup();
|
|
978
1014
|
}
|
|
1015
|
+
// AGGRESSIVE RESOURCE CLEANUP METHODS
|
|
1016
|
+
// Clean DOM references and memory leaks
|
|
1017
|
+
cleanupDOMReferences() {
|
|
1018
|
+
// Remove event listeners that could maintain references
|
|
1019
|
+
if (this.videoRef) {
|
|
1020
|
+
// Remove common event listeners (if any were added)
|
|
1021
|
+
this.videoRef.srcObject = null;
|
|
1022
|
+
this.videoRef = undefined;
|
|
1023
|
+
}
|
|
1024
|
+
// Clean detection container
|
|
1025
|
+
if (this.detectionContainer) {
|
|
1026
|
+
this.detectionContainer = undefined;
|
|
1027
|
+
}
|
|
1028
|
+
// Clean references to images in the DOM and revoke blob URLs
|
|
1029
|
+
const images = this.el.shadowRoot?.querySelectorAll('img');
|
|
1030
|
+
images?.forEach(img => {
|
|
1031
|
+
if (img.src.startsWith('blob:')) {
|
|
1032
|
+
URL.revokeObjectURL(img.src);
|
|
1033
|
+
}
|
|
1034
|
+
img.src = '';
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
// Clear browser cache and storage
|
|
1038
|
+
async clearBrowserCache() {
|
|
1039
|
+
try {
|
|
1040
|
+
// 1. Clear Service Worker cache if exists
|
|
1041
|
+
if ('serviceWorker' in navigator) {
|
|
1042
|
+
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
1043
|
+
await Promise.all(registrations.map(registration => registration.unregister()));
|
|
1044
|
+
}
|
|
1045
|
+
// 2. Clear Cache API specific to the component
|
|
1046
|
+
const cacheNames = await caches.keys();
|
|
1047
|
+
const componentCaches = cacheNames.filter(name => name.includes('jaak') || name.includes('stamps'));
|
|
1048
|
+
await Promise.all(componentCaches.map(cacheName => caches.delete(cacheName)));
|
|
1049
|
+
// 3. Force garbage collection if available (only in dev)
|
|
1050
|
+
if (this.debug && window.gc) {
|
|
1051
|
+
window.gc();
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
catch (error) {
|
|
1055
|
+
console.warn('Error clearing browser cache:', error);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
// Clear local storage specific to the component
|
|
1059
|
+
async clearLocalStorage() {
|
|
1060
|
+
try {
|
|
1061
|
+
// Clear localStorage specific to the component
|
|
1062
|
+
const keysToRemove = [];
|
|
1063
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
1064
|
+
const key = localStorage.key(i);
|
|
1065
|
+
if (key && (key.includes('jaak') || key.includes('onnx') || key.includes('stamps'))) {
|
|
1066
|
+
keysToRemove.push(key);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
keysToRemove.forEach(key => localStorage.removeItem(key));
|
|
1070
|
+
// Clear sessionStorage
|
|
1071
|
+
const sessionKeysToRemove = [];
|
|
1072
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
1073
|
+
const key = sessionStorage.key(i);
|
|
1074
|
+
if (key && (key.includes('jaak') || key.includes('onnx'))) {
|
|
1075
|
+
sessionKeysToRemove.push(key);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
sessionKeysToRemove.forEach(key => sessionStorage.removeItem(key));
|
|
1079
|
+
}
|
|
1080
|
+
catch (error) {
|
|
1081
|
+
console.warn('Error clearing local storage:', error);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
// Aggressive resource cleanup combining all strategies
|
|
1085
|
+
async aggressiveResourceCleanup() {
|
|
1086
|
+
const freed = [];
|
|
1087
|
+
const errors = [];
|
|
1088
|
+
try {
|
|
1089
|
+
// 1. Release ONNX resources
|
|
1090
|
+
this.releaseOnnxResources();
|
|
1091
|
+
freed.push('ONNX models');
|
|
1092
|
+
// 2. Clear model cache in detection service
|
|
1093
|
+
if (this.detectionService) {
|
|
1094
|
+
await this.detectionService.clearModelCache();
|
|
1095
|
+
freed.push('Model cache');
|
|
1096
|
+
}
|
|
1097
|
+
// 3. Clear browser cache
|
|
1098
|
+
await this.clearBrowserCache();
|
|
1099
|
+
freed.push('Browser cache');
|
|
1100
|
+
// 4. Clear local storage
|
|
1101
|
+
await this.clearLocalStorage();
|
|
1102
|
+
freed.push('Local storage');
|
|
1103
|
+
// 5. Clean DOM references
|
|
1104
|
+
this.cleanupDOMReferences();
|
|
1105
|
+
freed.push('DOM references');
|
|
1106
|
+
// 6. Optimize canvas pools
|
|
1107
|
+
if (this.detectionService) {
|
|
1108
|
+
this.detectionService.optimizeCanvasPool(0);
|
|
1109
|
+
freed.push('Canvas pools');
|
|
1110
|
+
}
|
|
1111
|
+
// 7. Clear component canvas pool
|
|
1112
|
+
this.canvasPool = [];
|
|
1113
|
+
freed.push('Component canvas pool');
|
|
1114
|
+
// 8. Force garbage collection (if available)
|
|
1115
|
+
if (this.debug && window.gc) {
|
|
1116
|
+
window.gc();
|
|
1117
|
+
freed.push('Garbage collection');
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
catch (error) {
|
|
1121
|
+
errors.push(error.message);
|
|
1122
|
+
}
|
|
1123
|
+
return { freed, errors };
|
|
1124
|
+
}
|
|
1125
|
+
// Progressive resource release after front capture
|
|
1126
|
+
async onFrontCaptureComplete() {
|
|
1127
|
+
try {
|
|
1128
|
+
// Release classification model if not needed for back
|
|
1129
|
+
if (this.detectionService && !this.useDocumentClassification) {
|
|
1130
|
+
await this.detectionService.releaseMobileNetResources();
|
|
1131
|
+
}
|
|
1132
|
+
// Optimize canvas pool to minimum needed for back capture
|
|
1133
|
+
if (this.detectionService) {
|
|
1134
|
+
this.detectionService.optimizeCanvasPool(1);
|
|
1135
|
+
}
|
|
1136
|
+
// Reduce component canvas pool
|
|
1137
|
+
while (this.canvasPool.length > 1) {
|
|
1138
|
+
const canvas = this.canvasPool.pop();
|
|
1139
|
+
if (canvas) {
|
|
1140
|
+
const ctx = canvas.getContext('2d');
|
|
1141
|
+
if (ctx) {
|
|
1142
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (this.debug) {
|
|
1147
|
+
console.log('🧹 Progressive cleanup after front capture completed');
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
catch (error) {
|
|
1151
|
+
console.warn('Error in progressive cleanup:', error);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
// Resource reporting for debugging
|
|
1155
|
+
getResourceReportInternal() {
|
|
1156
|
+
const report = {
|
|
1157
|
+
timestamp: new Date().toISOString(),
|
|
1158
|
+
component: {
|
|
1159
|
+
hasVideoStream: !!this.videoStream,
|
|
1160
|
+
hasAnimationFrame: !!this.animationId,
|
|
1161
|
+
canvasPoolSize: this.canvasPool.length,
|
|
1162
|
+
detectionBoxesCount: this.detectionBoxes.length,
|
|
1163
|
+
performanceMonitorActive: !!this.performanceUpdateInterval
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
// Add detection service stats if available
|
|
1167
|
+
if (this.detectionService) {
|
|
1168
|
+
report.detectionService = {
|
|
1169
|
+
isModelLoaded: this.detectionService.isModelLoaded(),
|
|
1170
|
+
canvasPoolStats: this.detectionService.getPoolStats()
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
// Add memory info if available
|
|
1174
|
+
if ('memory' in performance) {
|
|
1175
|
+
const memInfo = performance.memory;
|
|
1176
|
+
report.memory = {
|
|
1177
|
+
usedJSHeapSize: Math.round(memInfo.usedJSHeapSize / 1048576), // MB
|
|
1178
|
+
totalJSHeapSize: Math.round(memInfo.totalJSHeapSize / 1048576), // MB
|
|
1179
|
+
jsHeapSizeLimit: Math.round(memInfo.jsHeapSizeLimit / 1048576) // MB
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
return report;
|
|
1183
|
+
}
|
|
979
1184
|
render() {
|
|
980
1185
|
const captureState = this.stateManager?.getCaptureState() || {
|
|
981
1186
|
isVideoActive: false,
|
|
@@ -986,7 +1191,7 @@ export class JaakStamps {
|
|
|
986
1191
|
isCapturing: false
|
|
987
1192
|
};
|
|
988
1193
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
989
|
-
return (h("div", { key: '
|
|
1194
|
+
return (h("div", { key: 'd32941c10b3b7193b2113691dae712a80315b430', class: "detector-container" }, h("div", { key: '7704c993cb9e6e3d29edf6b0adfe341dc1cc8e04', class: "video-container" }, h("video", { key: '2d0d46f1973c86e91f9fe9ede0aa938326c6071f', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: '9d62ea5221271a18938a9f80535ec7d960745ddb', 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
1195
|
position: 'absolute',
|
|
991
1196
|
left: `${box.x}px`,
|
|
992
1197
|
top: `${box.y}px`,
|
|
@@ -995,9 +1200,9 @@ export class JaakStamps {
|
|
|
995
1200
|
border: '2px solid #32406C',
|
|
996
1201
|
pointerEvents: 'none',
|
|
997
1202
|
boxSizing: 'border-box'
|
|
998
|
-
} })))), this.isMaskReady && (h("div", { key: '
|
|
1203
|
+
} })))), this.isMaskReady && (h("div", { key: '38ebb5be5c55a184644411f06fe20221bdbdf693', class: "overlay-mask" }, h("div", { key: '6200c59e7a1212267e7335e1495cf9d9db2bca62', class: "card-outline" }, h("div", { key: 'c5321d2b5c09734cbca69fc8bb7849eef465a0ce', class: "side side-top" }), h("div", { key: 'd73b5afcb6781307460b8827c491673ebbfc40ef', class: "side side-right" }), h("div", { key: '787dfa0792c5a00f8a83feaa423ca22092e0a8bf', class: "side side-bottom" }), h("div", { key: '50736a6b9c7c8847d1dabaa22464e26f284da11e', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'ec8cc90cd589e4f713becb57b6787ce4f57318d4', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'd9d391c02855ac754607cbf77c119153d1f6e56f', class: "back-capture-section" }, h("div", { key: 'a3ebe694f74958b7910fc355a66cbf1394fb5a2a', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode) && (h("button", { key: 'bc6baf4e00199dfdd50bbfbf8abbcede0fb719e9', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '3a56f9132fce454c792818925c8bed5557e69eed', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: '2fe7e44bc91b73581d6333b7c404ec018a390372', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'ebb2d40cbcb646c9bd70ebe278b0643f9335779b', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
999
1204
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
1000
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '
|
|
1205
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '4373e4f9ab73d93ce32ae52fbdc14f7bcb69e68e', class: "camera-controls" }, h("button", { key: '5d2afe5b71b02d379fe2ec82bd57a86f614fbea6', 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: '4fe5e10260a1299a0dc8517646bed8134fe38d9a', class: "camera-selector-dropdown" }, h("div", { key: 'b041acd0b0292864d20ad256301e7be714854424', class: "camera-selector-header" }, h("span", { key: '2769170dc9ce382b420a719cad6f9bb1f5e4420f' }, "Seleccionar C\u00E1mara"), h("button", { key: '0c54f73bb29041ba88e1838c5b1c8a54eafdc67d', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'd72ae015c5e89cc3396c14406591308eda4d4c4a', 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: '5933bb5c8345debf2eb78fc2cd3900cb09a29335', class: "device-info" }, h("small", { key: 'a126d886feaede4f9657abee9b45d1eff1910e25' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '62ab98c6afa629583ff13f1792422ef1c5012883', class: "manual-capture-section" }, h("button", { key: '93a42f7b0626a63ab795652eb9eb81657f4fec13', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '77b5aaf62edab4fe8eb68f37083121d9f8493797', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '399242238fd4a2a4985af0f30faed504d73a0adc', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '06add02bc244511dc0dc82bf206f41d9ce3cdcd3', class: "flip-animation" }, h("div", { key: 'e3949d8e41bc496bf503d1dcd34df53d2bf876aa', class: "id-card-icon" }), h("div", { key: 'e8ebdd9d29e0b33dcfc506b40e67e0d4af8cb0bb', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'f72f6fc4d42c7b10d98c8aff7541596afe131883', class: "success-animation" }, h("div", { key: '8d0d422b37caa97f695f62c0094c52c3c12c7bda', class: "check-icon" }), h("div", { key: 'd9d673dbfd2af4a1b8ca1a775e5b318326d70446', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'fdfa1239ddea40bbbabf032542a7160fae3f3c96', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '34bb9d5b83e4383c4f640ccf11189484514e4efd', class: "status-spinner" })), h("div", { key: '131bcd252fc7e1f6eb27332d64fd249b5889aa9d', class: "status-content" }, h("div", { key: '911b7324456e84842fa3c14c9a6fd3ba475804cf', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'e938b9294ee3c6125b133bf737caa4a33a016872', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'cab385a12f6ccf8579d2d073c1ed987bf815efeb', class: "performance-monitor" }, h("div", { key: '903f8a7005a98c4b99eb7d4c91662911cee8beae', class: "performance-expanded" }, h("div", { key: 'f1ba17573d53442a23212e2c8fdd132bd3ddf4f0', class: "metrics-row" }, h("div", { key: '71357107dcc19749e5af2d5668df535db65cb986', class: "metric-compact" }, h("span", { key: '9ad542fb9445340c669c3d18fc293e2364fc5dcc', class: "metric-label" }, "FPS"), h("span", { key: 'ab0fb401df5dc792c0a641a574851aec48093862', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'a650ab2a1af27829d4a63a264f00907dfba363c6', class: "metric-compact" }, h("span", { key: '56e195b0fd468f2a457a66b2342ed6a80fbef0a0', class: "metric-label" }, "MEM"), h("span", { key: '265445131d4492c6e2f7571d367f52c93e00b711', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '56023a82a1978c7c2f8f08edac729f39efcafa63', class: "metrics-row" }, h("div", { key: '6f1ceb668fc246ec11bfeee3f14c745f21d4986e', class: "metric-compact" }, h("span", { key: '92efba3ee31c5b9a382f1e205584950217482722', class: "metric-label" }, "INF"), h("span", { key: 'fc2baec34fd2f0696a216c487753b94b8bacaf7e', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '683eeb875e96c94cf36c403385c2764239fb5a4d', class: "metric-compact" }, h("span", { key: '33ba3f357868f7feaaeefab35e3ecc35d3b5b726', class: "metric-label" }, "FRAME"), h("span", { key: 'f496be674b0328556d27a9a9b2f24ffa50ff76ea', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '521f275481d35c2132dbcf138e4bbda84a0b97b2', class: "metrics-row" }, h("div", { key: '17acc0238696816077b80b66aee317ae9ab20e75', class: "metric-compact" }, h("span", { key: 'cac1a4ee661de14739623a1a6f0149ba72fa918c', class: "metric-label" }, "DET"), h("span", { key: '70071c404c5e50001d813f1f3e0d1002776ed887', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '26a00ad1c95e6c2b8feaafc36103fb7fb869039f', class: "metric-compact" }, h("span", { key: 'a1c7fb80b6795f10111c1ed403de933aadcbe450', class: "metric-label" }, "RATE"), h("span", { key: '49471b7bfa2d6ca6357a39bf611738fd6344764a', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '3870b7399d2d5068e7f59177225476b00bef7fc7', class: "watermark" }, h("img", { key: '5030e9f14eebd4546207ced129d7d00d85abb189', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
|
|
1001
1206
|
}
|
|
1002
1207
|
// Utility methods
|
|
1003
1208
|
updateDetectionBoxes(boxes) {
|
|
@@ -1221,6 +1426,8 @@ export class JaakStamps {
|
|
|
1221
1426
|
showFlipAnimation: true
|
|
1222
1427
|
});
|
|
1223
1428
|
this.triggerRerender();
|
|
1429
|
+
// Progressive resource cleanup after front capture
|
|
1430
|
+
await this.onFrontCaptureComplete();
|
|
1224
1431
|
setTimeout(() => {
|
|
1225
1432
|
this.stateManager.updateCaptureState({
|
|
1226
1433
|
showFlipAnimation: false,
|
|
@@ -1296,6 +1503,8 @@ export class JaakStamps {
|
|
|
1296
1503
|
isDetectionPaused: true,
|
|
1297
1504
|
showFlipAnimation: true
|
|
1298
1505
|
});
|
|
1506
|
+
// Progressive resource cleanup after front capture
|
|
1507
|
+
await this.onFrontCaptureComplete();
|
|
1299
1508
|
setTimeout(() => {
|
|
1300
1509
|
this.stateManager.updateCaptureState({
|
|
1301
1510
|
showFlipAnimation: false,
|
|
@@ -1473,6 +1682,16 @@ export class JaakStamps {
|
|
|
1473
1682
|
setTimeout(() => {
|
|
1474
1683
|
this.stateManager.updateCaptureState({ showSuccessAnimation: false });
|
|
1475
1684
|
}, 3000);
|
|
1685
|
+
// Aggressive cleanup after process completion with delay
|
|
1686
|
+
setTimeout(async () => {
|
|
1687
|
+
const cleanupResult = await this.aggressiveResourceCleanup();
|
|
1688
|
+
if (this.debug) {
|
|
1689
|
+
console.log('🧹 Post-completion cleanup:', cleanupResult.freed);
|
|
1690
|
+
if (cleanupResult.errors.length > 0) {
|
|
1691
|
+
console.warn('⚠️ Cleanup errors:', cleanupResult.errors);
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
}, 1000); // Wait 1 second after completion
|
|
1476
1695
|
}
|
|
1477
1696
|
stopDetection() {
|
|
1478
1697
|
if (this.animationId) {
|
|
@@ -2054,7 +2273,7 @@ export class JaakStamps {
|
|
|
2054
2273
|
},
|
|
2055
2274
|
"stopCapture": {
|
|
2056
2275
|
"complexType": {
|
|
2057
|
-
"signature": "() => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>",
|
|
2276
|
+
"signature": "() => Promise<{ success: boolean; resourcesFreed: string[]; cleanupErrors: string[]; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; cleanupErrors?: undefined; }>",
|
|
2058
2277
|
"parameters": [],
|
|
2059
2278
|
"references": {
|
|
2060
2279
|
"Promise": {
|
|
@@ -2062,7 +2281,7 @@ export class JaakStamps {
|
|
|
2062
2281
|
"id": "global::Promise"
|
|
2063
2282
|
}
|
|
2064
2283
|
},
|
|
2065
|
-
"return": "Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>"
|
|
2284
|
+
"return": "Promise<{ success: boolean; resourcesFreed: string[]; cleanupErrors: string[]; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; cleanupErrors?: undefined; }>"
|
|
2066
2285
|
},
|
|
2067
2286
|
"docs": {
|
|
2068
2287
|
"text": "",
|
|
@@ -2222,6 +2441,40 @@ export class JaakStamps {
|
|
|
2222
2441
|
"text": "",
|
|
2223
2442
|
"tags": []
|
|
2224
2443
|
}
|
|
2444
|
+
},
|
|
2445
|
+
"getResourceReport": {
|
|
2446
|
+
"complexType": {
|
|
2447
|
+
"signature": "() => Promise<any>",
|
|
2448
|
+
"parameters": [],
|
|
2449
|
+
"references": {
|
|
2450
|
+
"Promise": {
|
|
2451
|
+
"location": "global",
|
|
2452
|
+
"id": "global::Promise"
|
|
2453
|
+
}
|
|
2454
|
+
},
|
|
2455
|
+
"return": "Promise<any>"
|
|
2456
|
+
},
|
|
2457
|
+
"docs": {
|
|
2458
|
+
"text": "",
|
|
2459
|
+
"tags": []
|
|
2460
|
+
}
|
|
2461
|
+
},
|
|
2462
|
+
"forceResourceCleanup": {
|
|
2463
|
+
"complexType": {
|
|
2464
|
+
"signature": "() => Promise<{ success: boolean; resourcesFreed: string[]; errors: string[]; timestamp: string; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; errors?: undefined; timestamp?: undefined; }>",
|
|
2465
|
+
"parameters": [],
|
|
2466
|
+
"references": {
|
|
2467
|
+
"Promise": {
|
|
2468
|
+
"location": "global",
|
|
2469
|
+
"id": "global::Promise"
|
|
2470
|
+
}
|
|
2471
|
+
},
|
|
2472
|
+
"return": "Promise<{ success: boolean; resourcesFreed: string[]; errors: string[]; timestamp: string; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; errors?: undefined; timestamp?: undefined; }>"
|
|
2473
|
+
},
|
|
2474
|
+
"docs": {
|
|
2475
|
+
"text": "",
|
|
2476
|
+
"tags": []
|
|
2477
|
+
}
|
|
2225
2478
|
}
|
|
2226
2479
|
};
|
|
2227
2480
|
}
|