@jaak.ai/stamps 2.5.7 → 2.5.8-dev.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/dist/cjs/{index-D6NBn_qu.js → index-BcFBOmM6.js} +30 -4
- package/dist/cjs/index-BcFBOmM6.js.map +1 -0
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +2 -2
- package/dist/cjs/jaak-stamps.cjs.entry.js +264 -75
- 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 +2 -2
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/{my-component/my-component.js → jaak-stamps/jaak-stamps.js} +209 -37
- package/dist/collection/components/jaak-stamps/jaak-stamps.js.map +1 -0
- package/dist/collection/components/jaak-stamps/watermark-fallback.js.map +1 -0
- package/dist/collection/services/DetectionService.js +60 -38
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/components/index.js +20 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/jaak-stamps.js +266 -74
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/{index-BCfAsrzL.js → index-Cb0ILUvS.js} +30 -4
- package/dist/esm/index-Cb0ILUvS.js.map +1 -0
- package/dist/esm/jaak-stamps-webcomponent.js +3 -3
- package/dist/esm/jaak-stamps.entry.js +264 -75
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +3 -3
- 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-Cb0ILUvS.js +3 -0
- package/dist/jaak-stamps-webcomponent/p-Cb0ILUvS.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/{p-63c2c085.entry.js → p-b4834625.entry.js} +3 -3
- package/dist/jaak-stamps-webcomponent/p-b4834625.entry.js.map +1 -0
- package/dist/types/components/{my-component/my-component.d.ts → jaak-stamps/jaak-stamps.d.ts} +12 -0
- package/dist/types/services/DetectionService.d.ts +5 -4
- package/package.json +4 -4
- package/dist/cjs/index-D6NBn_qu.js.map +0 -1
- package/dist/collection/components/my-component/my-component.js.map +0 -1
- package/dist/collection/components/my-component/watermark-fallback.js.map +0 -1
- package/dist/collection/utils/utils.js +0 -4
- package/dist/collection/utils/utils.js.map +0 -1
- package/dist/esm/index-BCfAsrzL.js.map +0 -1
- package/dist/jaak-stamps-webcomponent/p-63c2c085.entry.js.map +0 -1
- package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js +0 -3
- package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js.map +0 -1
- package/dist/types/utils/utils.d.ts +0 -1
- /package/dist/collection/components/{my-component/my-component.css → jaak-stamps/jaak-stamps.css} +0 -0
- /package/dist/collection/components/{my-component → jaak-stamps}/watermark-fallback.js +0 -0
- /package/dist/types/components/{my-component → jaak-stamps}/watermark-fallback.d.ts +0 -0
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-BcFBOmM6.js');
|
|
4
4
|
var appGlobals = require('./app-globals-V2Kpy_OQ.js');
|
|
5
5
|
|
|
6
6
|
const defineCustomElements = async (win, options) => {
|
|
7
7
|
if (typeof window === 'undefined') return undefined;
|
|
8
8
|
await appGlobals.globalScripts();
|
|
9
|
-
return index.bootstrapLazy([["jaak-stamps.cjs",[[257,"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"],"telemetryCollectorUrl":[1,"telemetry-collector-url"],"metricsCollectorUrl":[1,"metrics-collector-url"],"enableTelemetry":[4,"enable-telemetry"],"enableMetrics":[4,"enable-metrics"],"customerId":[1,"customer-id"],"tenantId":[1,"tenant-id"],"environment":[1],"propagateTraceHeaderCorsUrls":[1,"propagate-trace-header-cors-urls"],"metricsExportIntervalMillis":[2,"metrics-export-interval-millis"],"license":[1],"licenseEnvironment":[1,"license-environment"],"traceId":[1,"trace-id"],"appId":[1,"app-id"],"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],"licenseValid":[32],"licenseError":[32],"classificationDisabled":[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);
|
|
9
|
+
return index.bootstrapLazy([["jaak-stamps.cjs",[[257,"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"],"telemetryCollectorUrl":[1,"telemetry-collector-url"],"metricsCollectorUrl":[1,"metrics-collector-url"],"enableTelemetry":[4,"enable-telemetry"],"enableMetrics":[4,"enable-metrics"],"customerId":[1,"customer-id"],"tenantId":[1,"tenant-id"],"environment":[1],"propagateTraceHeaderCorsUrls":[1,"propagate-trace-header-cors-urls"],"metricsExportIntervalMillis":[2,"metrics-export-interval-millis"],"license":[1],"licenseEnvironment":[1,"license-environment"],"traceId":[1,"trace-id"],"appId":[1,"app-id"],"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],"licenseValid":[32],"licenseError":[32],"classificationDisabled":[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]},null,{"license":["onLicenseChanged"],"licenseEnvironment":["onLicenseEnvironmentChanged"]}]]]], options);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
exports.setNonce = index.setNonce;
|
package/dist/collection/components/{my-component/my-component.js → jaak-stamps/jaak-stamps.js}
RENAMED
|
@@ -24,7 +24,7 @@ export class JaakStamps {
|
|
|
24
24
|
propagateTraceHeaderCorsUrls; // Comma-separated URLs or regex patterns
|
|
25
25
|
metricsExportIntervalMillis = 60000; // Export metrics every 60 seconds
|
|
26
26
|
license; // License key for validation
|
|
27
|
-
licenseEnvironment = 'prod';
|
|
27
|
+
licenseEnvironment = 'prod';
|
|
28
28
|
traceId; // Optional trace ID for tracking
|
|
29
29
|
appId = 'jaak-stamps-web'; // Application ID for license validation
|
|
30
30
|
captureCompleted;
|
|
@@ -72,6 +72,10 @@ export class JaakStamps {
|
|
|
72
72
|
licenseValid = true; // License validation status
|
|
73
73
|
licenseError = null; // License validation error message
|
|
74
74
|
classificationDisabled = false; // Classification disabled at runtime due to errors
|
|
75
|
+
_initialized = false;
|
|
76
|
+
_initializing = false;
|
|
77
|
+
_pendingEnvironmentRetry = false;
|
|
78
|
+
_pendingInit = null;
|
|
75
79
|
// Services
|
|
76
80
|
licenseValidationService = null;
|
|
77
81
|
serviceContainer;
|
|
@@ -140,46 +144,124 @@ export class JaakStamps {
|
|
|
140
144
|
// Canvas pool for optimized screenshot capture
|
|
141
145
|
canvasPool = [];
|
|
142
146
|
MAX_CANVAS_POOL_SIZE = 3;
|
|
147
|
+
// Readiness gate for startCapture(). The host may call startCapture() before the
|
|
148
|
+
// component finishes loading its resources (ONNX Runtime + WASM/models from the CDN).
|
|
149
|
+
// On slow devices/networks this race made startCapture() abort with "El componente
|
|
150
|
+
// está cargando recursos", leaving the screen black (TO-807). Instead of aborting we
|
|
151
|
+
// wait for initialization to settle and retry. `initializationSettled` flips once
|
|
152
|
+
// finalizeInitialization() has run; pending waiters are released via these callbacks.
|
|
153
|
+
initializationSettled = false;
|
|
154
|
+
initializationWaiters = [];
|
|
155
|
+
// Max time startCapture() waits for a still-initializing component before giving up.
|
|
156
|
+
// Sized for slow Android/network asset downloads; if resources never load (CDN down,
|
|
157
|
+
// 404, CORS) the timeout fires and startCapture() returns the original error.
|
|
158
|
+
START_CAPTURE_READY_TIMEOUT_MS = 15000;
|
|
143
159
|
async componentWillLoad() {
|
|
160
|
+
// @Watch handlers fire synchronously when Angular sets properties, which happens
|
|
161
|
+
// BEFORE componentWillLoad (Stencil schedules componentWillLoad as a microtask after
|
|
162
|
+
// connectedCallback, while Angular sets props synchronously in that same call stack).
|
|
163
|
+
// @Watch('license') defers init to a macrotask so @Watch('licenseEnvironment') fires
|
|
164
|
+
// first. By the time we resume here, init may already be in progress.
|
|
165
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
144
166
|
if (this.debug) {
|
|
145
|
-
console.log('[JAAK-DEBUG] componentWillLoad() - Props
|
|
167
|
+
console.log('[JAAK-DEBUG] componentWillLoad() - Props after yield:');
|
|
168
|
+
console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
|
|
169
|
+
console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
|
|
170
|
+
console.log('[JAAK-DEBUG] _initializing:', this._initializing);
|
|
171
|
+
console.log('[JAAK-DEBUG] _initialized:', this._initialized);
|
|
146
172
|
console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
|
|
147
173
|
console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
|
|
148
174
|
console.log('[JAAK-DEBUG] debug:', this.debug);
|
|
149
|
-
console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
|
|
150
|
-
console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
|
|
151
175
|
console.log('[JAAK-DEBUG] alignmentTolerance:', this.alignmentTolerance);
|
|
152
176
|
console.log('[JAAK-DEBUG] maskSize:', this.maskSize);
|
|
153
177
|
console.log('[JAAK-DEBUG] captureDelay:', this.captureDelay);
|
|
154
178
|
console.log('[JAAK-DEBUG] preferredCamera:', this.preferredCamera);
|
|
155
179
|
console.log('[JAAK-DEBUG] appId:', this.appId);
|
|
156
180
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
|
|
165
|
-
await this.validateLicense();
|
|
166
|
-
// If license validation failed, stop initialization
|
|
167
|
-
if (!this.licenseValid) {
|
|
168
|
-
if (this.debug) {
|
|
169
|
-
console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
|
|
181
|
+
if (!this.license) {
|
|
182
|
+
if (!this._initialized && !this._initializing) {
|
|
183
|
+
// No license and init not started — show blocking error UI
|
|
184
|
+
this.licenseValid = false;
|
|
185
|
+
this.licenseError = 'Se requiere una licencia para continuar. Por favor, proporcione una licencia usando el atributo "license".';
|
|
186
|
+
this.updateStatus('Licencia requerida', 'Proporcione una licencia para continuar', 'error');
|
|
170
187
|
}
|
|
171
|
-
return;
|
|
172
188
|
}
|
|
173
|
-
if (this.
|
|
174
|
-
|
|
189
|
+
else if (!this._initialized && !this._initializing) {
|
|
190
|
+
// License present but init hasn't started yet (no @Watch fired) — set initial status
|
|
191
|
+
// so the first render already shows it without a redundant state change in componentDidLoad
|
|
192
|
+
this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
|
|
175
193
|
}
|
|
194
|
+
// Heavy initialization is deferred to componentDidLoad so the first render is not blocked
|
|
176
195
|
}
|
|
177
196
|
async componentDidLoad() {
|
|
197
|
+
// If @Watch('license') already scheduled or started init, let it proceed
|
|
198
|
+
if (!this.license || this._initialized || this._initializing || this._pendingInit !== null) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
await this.validateAndInitialize();
|
|
202
|
+
}
|
|
203
|
+
onLicenseChanged(newLicense) {
|
|
204
|
+
if (!newLicense || this._initialized || this._initializing) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// Defer init by one macrotask (setTimeout 0) so @Watch('licenseEnvironment') fires
|
|
208
|
+
// first. Angular applies [license] before [licenseEnvironment] in template order,
|
|
209
|
+
// meaning a synchronous start here would use the Stencil default "prod" for the env.
|
|
210
|
+
if (this._pendingInit !== null)
|
|
211
|
+
clearTimeout(this._pendingInit);
|
|
212
|
+
this._pendingInit = setTimeout(async () => {
|
|
213
|
+
this._pendingInit = null;
|
|
214
|
+
if (!this._initialized && !this._initializing && this.license) {
|
|
215
|
+
this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
|
|
216
|
+
await this.validateAndInitialize();
|
|
217
|
+
}
|
|
218
|
+
}, 0);
|
|
219
|
+
}
|
|
220
|
+
async onLicenseEnvironmentChanged() {
|
|
221
|
+
// Always recreate the service so the correct environment URL is ready.
|
|
222
|
+
this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
|
|
223
|
+
if (this._initializing) {
|
|
224
|
+
// Validation is already in-flight with the wrong environment.
|
|
225
|
+
// Flag a retry so validateAndInitialize restarts once the current attempt ends.
|
|
226
|
+
this._pendingEnvironmentRetry = true;
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
// If @Watch('license') already scheduled a deferred init, that init will read
|
|
230
|
+
// this.licenseEnvironment at fire time (after this handler returns), so the
|
|
231
|
+
// correct URL will be used — no need to trigger a second init here.
|
|
232
|
+
if (this._pendingInit !== null) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (this._initialized) {
|
|
236
|
+
// Component was fully initialized with the wrong env URL (e.g. Ionic animation
|
|
237
|
+
// delayed Angular's CD past the initial validateAndInitialize() cycle).
|
|
238
|
+
// Re-validate the license only — services and camera are already running.
|
|
239
|
+
await this.validateLicense();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (this.license) {
|
|
243
|
+
this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
|
|
244
|
+
await this.validateAndInitialize();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async validateAndInitialize() {
|
|
248
|
+
if (this._initialized || this._initializing) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this._initializing = true;
|
|
178
252
|
try {
|
|
179
|
-
//
|
|
253
|
+
// Status was already set synchronously by the caller (componentWillLoad or @Watch)
|
|
254
|
+
// to avoid a state change inside componentDidLoad that Stencil warns about.
|
|
255
|
+
await this.validateLicense();
|
|
180
256
|
if (!this.licenseValid) {
|
|
257
|
+
if (this.debug) {
|
|
258
|
+
console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
|
|
259
|
+
}
|
|
181
260
|
return;
|
|
182
261
|
}
|
|
262
|
+
if (this.debug) {
|
|
263
|
+
console.log('[JAAK-DEBUG] License validation OK');
|
|
264
|
+
}
|
|
183
265
|
this.updateStatus('Preparando capturador...', 'Configurando herramientas de captura', 'initializing');
|
|
184
266
|
await this.initializeServices();
|
|
185
267
|
this.updateStatus('Preparando funciones...', 'Configurando herramientas de trabajo', 'initializing');
|
|
@@ -189,9 +271,37 @@ export class JaakStamps {
|
|
|
189
271
|
if (this.debug) {
|
|
190
272
|
this.initializePerformanceMonitor();
|
|
191
273
|
}
|
|
274
|
+
this._initialized = true;
|
|
192
275
|
}
|
|
193
276
|
catch (error) {
|
|
194
|
-
|
|
277
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
278
|
+
this.updateStatus('Error de inicialización', errorMessage, 'error');
|
|
279
|
+
}
|
|
280
|
+
finally {
|
|
281
|
+
this._initializing = false;
|
|
282
|
+
if (this._pendingEnvironmentRetry && this.license) {
|
|
283
|
+
this._pendingEnvironmentRetry = false;
|
|
284
|
+
if (this._initialized) {
|
|
285
|
+
// Already fully initialized with wrong env URL — re-validate only the license.
|
|
286
|
+
// Services and camera are already running and don't depend on the env URL.
|
|
287
|
+
await this.validateLicense();
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// Not yet initialized — full retry with the correct environment.
|
|
291
|
+
this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
|
|
292
|
+
await this.validateAndInitialize();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
this._pendingEnvironmentRetry = false;
|
|
297
|
+
}
|
|
298
|
+
// Release any startCapture() calls waiting on readiness. On success this is a
|
|
299
|
+
// no-op (finalizeInitialization already settled); on a terminal failure (invalid
|
|
300
|
+
// license / init error) it lets startCapture() return its error without waiting
|
|
301
|
+
// out the full timeout. Idempotent, so a completed retry above stays settled.
|
|
302
|
+
if (!this._initializing) {
|
|
303
|
+
this.settleInitialization();
|
|
304
|
+
}
|
|
195
305
|
}
|
|
196
306
|
}
|
|
197
307
|
async initializeServices() {
|
|
@@ -241,14 +351,14 @@ export class JaakStamps {
|
|
|
241
351
|
}
|
|
242
352
|
async validateLicense() {
|
|
243
353
|
if (!this.license) {
|
|
244
|
-
console.error('❌ No license provided for JAAK Stamps component');
|
|
245
354
|
this.licenseError = 'Este componente requiere una licencia válida. Por favor, proporcione una licencia usando el atributo "license".';
|
|
246
355
|
this.licenseValid = false;
|
|
247
356
|
this.updateStatus('Error de licencia', 'Licencia no proporcionada', 'error');
|
|
248
357
|
return;
|
|
249
358
|
}
|
|
250
359
|
try {
|
|
251
|
-
|
|
360
|
+
if (this.debug)
|
|
361
|
+
console.log('[jaak-stamps] validating license...');
|
|
252
362
|
// Initialize license validation service
|
|
253
363
|
this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
|
|
254
364
|
// Validate the license, passing traceId and appId if provided
|
|
@@ -256,18 +366,21 @@ export class JaakStamps {
|
|
|
256
366
|
if (response && response.access_token) {
|
|
257
367
|
this.licenseValid = true;
|
|
258
368
|
this.licenseError = null;
|
|
259
|
-
|
|
369
|
+
if (this.debug)
|
|
370
|
+
console.log('[jaak-stamps] license validated successfully');
|
|
260
371
|
// Emit the traceId (either provided or generated)
|
|
261
372
|
if (response.traceId) {
|
|
262
373
|
this.traceIdGenerated.emit({ traceId: response.traceId });
|
|
263
|
-
|
|
374
|
+
if (this.debug)
|
|
375
|
+
console.log('[jaak-stamps] traceId:', response.traceId);
|
|
264
376
|
}
|
|
265
377
|
}
|
|
266
378
|
else {
|
|
267
379
|
this.licenseValid = false;
|
|
268
380
|
this.licenseError = 'La licencia proporcionada no es válida. Por favor, verifique su licencia e intente nuevamente.';
|
|
269
381
|
this.updateStatus('Error de licencia', 'Licencia inválida', 'error');
|
|
270
|
-
|
|
382
|
+
if (this.debug)
|
|
383
|
+
console.error('[jaak-stamps] invalid license');
|
|
271
384
|
}
|
|
272
385
|
}
|
|
273
386
|
catch (error) {
|
|
@@ -275,7 +388,8 @@ export class JaakStamps {
|
|
|
275
388
|
const licenseError = error;
|
|
276
389
|
this.licenseError = licenseError.error_description || 'Error al validar la licencia. Por favor, verifique su conexión e intente nuevamente.';
|
|
277
390
|
this.updateStatus('Error de licencia', 'Fallo en la validación', 'error');
|
|
278
|
-
|
|
391
|
+
if (this.debug)
|
|
392
|
+
console.error('[jaak-stamps] license validation failed:', error);
|
|
279
393
|
}
|
|
280
394
|
}
|
|
281
395
|
async setupEventListeners() {
|
|
@@ -378,6 +492,42 @@ export class JaakStamps {
|
|
|
378
492
|
};
|
|
379
493
|
}
|
|
380
494
|
this.emitReadyEvent();
|
|
495
|
+
this.settleInitialization();
|
|
496
|
+
}
|
|
497
|
+
// Releases any startCapture() calls that arrived while the component was still
|
|
498
|
+
// initializing. Idempotent: safe to call more than once.
|
|
499
|
+
settleInitialization() {
|
|
500
|
+
if (this.initializationSettled) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
this.initializationSettled = true;
|
|
504
|
+
const waiters = this.initializationWaiters;
|
|
505
|
+
this.initializationWaiters = [];
|
|
506
|
+
waiters.forEach(resolve => resolve());
|
|
507
|
+
}
|
|
508
|
+
// Waits until initialization settles (finalizeInitialization ran) or the timeout
|
|
509
|
+
// elapses, whichever comes first. Resolves regardless of outcome; the caller
|
|
510
|
+
// re-checks isComponentReady() afterwards to decide success/failure.
|
|
511
|
+
waitForInitialization(timeoutMs) {
|
|
512
|
+
if (this.initializationSettled) {
|
|
513
|
+
return Promise.resolve();
|
|
514
|
+
}
|
|
515
|
+
return new Promise(resolve => {
|
|
516
|
+
let settled = false;
|
|
517
|
+
const done = () => {
|
|
518
|
+
if (settled) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
settled = true;
|
|
522
|
+
clearTimeout(timer);
|
|
523
|
+
resolve();
|
|
524
|
+
};
|
|
525
|
+
const timer = setTimeout(() => {
|
|
526
|
+
this.initializationWaiters = this.initializationWaiters.filter(w => w !== done);
|
|
527
|
+
done();
|
|
528
|
+
}, timeoutMs);
|
|
529
|
+
this.initializationWaiters.push(done);
|
|
530
|
+
});
|
|
381
531
|
}
|
|
382
532
|
updateStatus(message, description, type = 'loading') {
|
|
383
533
|
this.currentStatus = {
|
|
@@ -569,7 +719,20 @@ export class JaakStamps {
|
|
|
569
719
|
}
|
|
570
720
|
async startCapture() {
|
|
571
721
|
const span = this.tracingService?.startSpan('capture.start');
|
|
572
|
-
|
|
722
|
+
let readyCheck = this.isComponentReady();
|
|
723
|
+
// TO-807: absorb the start-before-ready race instead of aborting. When the
|
|
724
|
+
// component is still loading its resources (transient initializing/loading
|
|
725
|
+
// state) we wait for initialization to settle and re-check, rather than
|
|
726
|
+
// returning an error immediately (which left the host with a black screen).
|
|
727
|
+
// A terminal state ('error' / missing services) is not waited on.
|
|
728
|
+
if (!readyCheck.ready && (readyCheck.status === 'initializing' || readyCheck.status === 'loading')) {
|
|
729
|
+
this.updateStatus('El componente está cargando recursos', 'Espere a que termine la inicialización', 'loading');
|
|
730
|
+
if (span) {
|
|
731
|
+
this.tracingService?.setSpanAttribute(span, 'startCapture.waitedForReady', true);
|
|
732
|
+
}
|
|
733
|
+
await this.waitForInitialization(this.START_CAPTURE_READY_TIMEOUT_MS);
|
|
734
|
+
readyCheck = this.isComponentReady();
|
|
735
|
+
}
|
|
573
736
|
if (!readyCheck.ready) {
|
|
574
737
|
this.updateStatus(readyCheck.message, 'Espere a que termine la inicialización', readyCheck.status);
|
|
575
738
|
if (span) {
|
|
@@ -1562,7 +1725,7 @@ export class JaakStamps {
|
|
|
1562
1725
|
isCapturing: false
|
|
1563
1726
|
};
|
|
1564
1727
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
1565
|
-
return (h("div", { key: '
|
|
1728
|
+
return (h("div", { key: 'ed400c7cc247fb12e5915e270207d3fa916362fd', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: 'd2f7507026d01d2fd381d365c9954067eb37c3f4', class: "license-error-container" }, h("div", { key: 'fc4ae7ae434a038a3730057a99a7d96d851dba43', class: "license-error-card" }, h("svg", { key: '7361da72e3fda0147044873bc770460098a4b4f1', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { key: '57a3dce14d47d4b91af6ff84ab39cde58814f573', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { key: '8c96a1638602eface0ae8c7377cdda04dffde5c7', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: '7455af58b1827570713d778a4ef01bb0ffcfb553', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '5779f8a2c4468ea185df620edecb3f79b7ae8bfb', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: '8180147597c077798ff4ea4eb9309a3bec69c77f', class: "license-error-message" }, this.licenseError), h("p", { key: '2103af42045a8ee8385de273da8f98e23395469b', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '8a7fe987b24600b123216c952c5b69f2c2afc0a0', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: 'fd00ef42e259669b7b7cc512478c9c925bd03415', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '44a92ba0a4cc066bb4497f4f548fce0bd5dbc121', class: "video-container" }, h("video", { key: '9ef40fb28c0fea1b59657ae50134b4dc3df4cf24', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
|
|
1566
1729
|
// Keep the element rendered (display: block) so the browser
|
|
1567
1730
|
// loads stream metadata and fires 'loadedmetadata'. Hiding it
|
|
1568
1731
|
// with display:none prevents metadata loading in Chrome and
|
|
@@ -1571,7 +1734,7 @@ export class JaakStamps {
|
|
|
1571
1734
|
// render context alive.
|
|
1572
1735
|
opacity: captureState.isVideoActive ? '1' : '0',
|
|
1573
1736
|
visibility: captureState.isVideoActive ? 'visible' : 'hidden',
|
|
1574
|
-
} }), h("div", { key: '
|
|
1737
|
+
} }), h("div", { key: 'f3d6e544bb8b13214894f71216badf092d2516dd', 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: {
|
|
1575
1738
|
position: 'absolute',
|
|
1576
1739
|
left: `${box.x}px`,
|
|
1577
1740
|
top: `${box.y}px`,
|
|
@@ -1580,9 +1743,9 @@ export class JaakStamps {
|
|
|
1580
1743
|
border: '2px solid #32406C',
|
|
1581
1744
|
pointerEvents: 'none',
|
|
1582
1745
|
boxSizing: 'border-box'
|
|
1583
|
-
} })))), this.isMaskReady && (h("div", { key: '
|
|
1746
|
+
} })))), this.isMaskReady && (h("div", { key: '312b9d7733e550a444e84d699c0e14834fc41057', class: "overlay-mask" }, h("div", { key: '2af1c83efb4d360ecada3301f4479bbf8845f032', class: "card-outline" }, h("div", { key: 'b6f57f153953e059056fae6d9f8a8220bfff4357', class: "side side-top" }), h("div", { key: 'e465f72b8834a04174dc88897b813517afa372fb', class: "side side-right" }), h("div", { key: '32e2785c7570f2002b6bc68b491007925d9fcad5', class: "side side-bottom" }), h("div", { key: 'bf2133811df7f516d9e3b37ae6019c90c0a68d0b', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'de00829ac42fe7f3645cb515fb46cfabe415190b', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'ae09d9c23635d87d31110781dc0ab3acb8ec4667', class: "back-capture-section" }, h("div", { key: 'a30a50ee0272140d16e32f582dd93f8de87d2a44', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: 'fb104cf6feaeca2f9542a2d5933bbf4f15c6771f', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '7a1bff56bae244c5b8d1d4c3fd523e7a20b4b5ce', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: '59125b29ad55122e5ee9e8c2aaf9689a1fef588e', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: '4d0b8184b4eb82824d5d864fb1b196f22302506d', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
1584
1747
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
1585
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '
|
|
1748
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '1febf678f87e32916d3990677b41345ce034db4e', class: "camera-controls" }, h("button", { key: '79f00bac9d56347de1fc08b2e06be1c0e996a855', 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: '4f6d101ce789b7fff227a6a2ce2479cb6255fd58', class: "camera-selector-dropdown" }, h("div", { key: 'f82222bb25162d2717d84c098c2a6540caa821f3', class: "camera-selector-header" }, h("span", { key: '0b1648857467c5749fe5d1d846d1786fa2e394c3' }, "Seleccionar C\u00E1mara"), h("button", { key: 'f406f08ad9dc2dcaced7e95aed013665c5fcfb4e', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'a051beeab1c8447730d41e963cd3b95027922cab', 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: 'c9c0702a57c105b02062f325cd413b531c7f802c', class: "device-info" }, h("small", { key: '584f4c1ce525b8ab03107329c92797737d5afad5' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'e3e2a270d3c4e7accdd9bc8b37861af4fceaad5d', class: "manual-capture-section" }, h("button", { key: '1283629ce59fc82d7b3fc08d5573bc69238f7aab', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '5de009e4d2ff0de43355e95e1d69f12d7f2e65f8', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '975142144bb104d3ed532ac80fca19a7f237bb2b', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '5d54b9130ed4d1e13b95cfeee8f9d694b5de68d3', class: "flip-animation" }, h("div", { key: 'c8b955180065d2b99f8e5f405b1ff92bc050af77', class: "id-card-icon" }), h("div", { key: 'f103b1871266886455d5bba094a0e119aa484595', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '5845c045d37099cf906f7c56d3c91568dd198bdf', class: "success-animation" }, h("div", { key: '430496db95f10834a43842e9ac97bdf0f025eb3b', class: "check-icon" }), h("div", { key: '0815cf6feffe8bd4ba84712c14d8f29c1a945577', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'f8a8a529850fc93e93f12810b7928e4700bac880', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '929ab612be046e97bb02ebe366b531864b90cc7a', class: "status-spinner" })), h("div", { key: 'defaf70aa54f2ccc222ddbe392cc47f7c143fc06', class: "status-content" }, h("div", { key: '685cca31f70e26d062f2d01b9ffd8c5a4a6b6f86', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '21bce9f6de9e5a50763ef83a25787225319dc5bf', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '6e43560821e469e397b78ab44d1679a3ff8e330f', class: "performance-monitor" }, h("div", { key: 'afcde6083be4a1b4a76d5523e0a239926b76ff9a', class: "performance-expanded" }, h("div", { key: '0706e93c06bcaf2e573c0c2ac414c3ca7d3605ba', class: "metrics-row" }, h("div", { key: '32b755f0f81ae758d9ab0b2e75dd9d55ef52eef0', class: "metric-compact" }, h("span", { key: 'b1d8e773fdd1e333cd55bb5bbed2878a7e106474', class: "metric-label" }, "FPS"), h("span", { key: 'a6c53d389e7424f6696b6279bef267b28e112201', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'a8c4157b696ae53e8ae5cee14f9e8b37be34a0a6', class: "metric-compact" }, h("span", { key: '0fa82dd84f6e0a9c16c1894021932e8ba355991a', class: "metric-label" }, "MEM"), h("span", { key: 'fc7f19be4e3fbbc82da538703ef9049e26571496', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '84bd7b6da8e91004ef6c554264b97b89fa6123e1', class: "metrics-row" }, h("div", { key: 'a2bc7af57fe87f5ef53ee00f76aa27675736c404', class: "metric-compact" }, h("span", { key: '59e9114f50cf4d69bfc447162001e8ab3214906a', class: "metric-label" }, "INF"), h("span", { key: 'c92e1f7e92127d85e0cdd647af44f1da4c46da57', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '5751e9dee9d55ddc559d1c60e68c4be7da2eb7a2', class: "metric-compact" }, h("span", { key: 'a34e394ab188e74a39eb77af4cf0108c8a2be1c3', class: "metric-label" }, "FRAME"), h("span", { key: '19165e851fc7f348e6cee93deccff0159c3bb982', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'dde9e547b8c9e200624e525d15baaa4a18a27417', class: "metrics-row" }, h("div", { key: '770301e51025a446e29638d38e8e8a8dfb911882', class: "metric-compact" }, h("span", { key: '96750b7a455ef1f3353b870467afdff402fa605b', class: "metric-label" }, "DET"), h("span", { key: 'a7951b69998e1d13beee40b6677d55091a413a4c', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'a82589fbccc749ef904a68933c6b850c3b69018c', class: "metric-compact" }, h("span", { key: 'ced7d42d2ebf2c4f20671c696b845263f4de4f4a', class: "metric-label" }, "RATE"), h("span", { key: '693c9735796ec276ca1d7e559aea250dafb0e5cf', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '3ff1698eae36352f9268839b86cef29144de297c', class: "watermark" }, h("img", { key: 'efa9735216e7caafdb67e10a5fc9363b503307b5', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
|
|
1586
1749
|
const img = e.target;
|
|
1587
1750
|
img.onerror = null;
|
|
1588
1751
|
img.src = POWERED_BY_JAAK_FALLBACK;
|
|
@@ -2130,7 +2293,7 @@ export class JaakStamps {
|
|
|
2130
2293
|
await this.tracingService.flush();
|
|
2131
2294
|
}
|
|
2132
2295
|
catch (error) {
|
|
2133
|
-
console.error('[
|
|
2296
|
+
console.error('[jaak-stamps] Failed to flush traces:', error);
|
|
2134
2297
|
}
|
|
2135
2298
|
}
|
|
2136
2299
|
this.captureCompleted.emit(finalImages);
|
|
@@ -2406,12 +2569,12 @@ export class JaakStamps {
|
|
|
2406
2569
|
static get encapsulation() { return "shadow"; }
|
|
2407
2570
|
static get originalStyleUrls() {
|
|
2408
2571
|
return {
|
|
2409
|
-
"$": ["
|
|
2572
|
+
"$": ["jaak-stamps.css"]
|
|
2410
2573
|
};
|
|
2411
2574
|
}
|
|
2412
2575
|
static get styleUrls() {
|
|
2413
2576
|
return {
|
|
2414
|
-
"$": ["
|
|
2577
|
+
"$": ["jaak-stamps.css"]
|
|
2415
2578
|
};
|
|
2416
2579
|
}
|
|
2417
2580
|
static get assetsDirs() { return ["../../assets"]; }
|
|
@@ -3177,5 +3340,14 @@ export class JaakStamps {
|
|
|
3177
3340
|
};
|
|
3178
3341
|
}
|
|
3179
3342
|
static get elementRef() { return "el"; }
|
|
3343
|
+
static get watchers() {
|
|
3344
|
+
return [{
|
|
3345
|
+
"propName": "license",
|
|
3346
|
+
"methodName": "onLicenseChanged"
|
|
3347
|
+
}, {
|
|
3348
|
+
"propName": "licenseEnvironment",
|
|
3349
|
+
"methodName": "onLicenseEnvironmentChanged"
|
|
3350
|
+
}];
|
|
3351
|
+
}
|
|
3180
3352
|
}
|
|
3181
|
-
//# sourceMappingURL=
|
|
3353
|
+
//# sourceMappingURL=jaak-stamps.js.map
|