idmission-web-sdk 2.3.122 → 2.3.124

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.
@@ -211,7 +211,7 @@
211
211
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
212
212
  };
213
213
 
214
- var webSdkVersion = '2.3.122';
214
+ var webSdkVersion = '2.3.124';
215
215
 
216
216
  function getPlatform() {
217
217
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -1127,38 +1127,35 @@
1127
1127
  function useDebugLogging(enabled) {
1128
1128
  useLogLevel(enabled ? LogLevel.Debug : logLevel);
1129
1129
  }
1130
- function debug() {
1131
- var parts = [];
1130
+ var noop$1 = function noop() {};
1131
+ var debug = function debug() {
1132
+ var args = [];
1132
1133
  for (var _i = 0; _i < arguments.length; _i++) {
1133
- parts[_i] = arguments[_i];
1134
+ args[_i] = arguments[_i];
1134
1135
  }
1135
- if (logLevel < LogLevel.Debug) return;
1136
- console.debug.apply(console, parts); // eslint-disable-line no-console
1137
- }
1138
- function log() {
1139
- var parts = [];
1136
+ return (logLevel >= LogLevel.Debug ? console.debug : noop$1).apply(void 0, args);
1137
+ }; // eslint-disable-line no-console
1138
+ var log = function log() {
1139
+ var args = [];
1140
1140
  for (var _i = 0; _i < arguments.length; _i++) {
1141
- parts[_i] = arguments[_i];
1141
+ args[_i] = arguments[_i];
1142
1142
  }
1143
- if (logLevel < LogLevel.Info) return;
1144
- console.log.apply(console, parts); // eslint-disable-line no-console
1145
- }
1146
- function warn() {
1147
- var parts = [];
1143
+ return (logLevel >= LogLevel.Info ? console.log : noop$1).apply(void 0, args);
1144
+ }; // eslint-disable-line no-console
1145
+ var warn = function warn() {
1146
+ var args = [];
1148
1147
  for (var _i = 0; _i < arguments.length; _i++) {
1149
- parts[_i] = arguments[_i];
1148
+ args[_i] = arguments[_i];
1150
1149
  }
1151
- if (logLevel < LogLevel.Warn) return;
1152
- console.warn.apply(console, parts); // eslint-disable-line no-console
1153
- }
1154
- function error() {
1155
- var parts = [];
1150
+ return (logLevel >= LogLevel.Warn ? console.warn : noop$1).apply(void 0, args);
1151
+ }; // eslint-disable-line no-console
1152
+ var error = function error() {
1153
+ var args = [];
1156
1154
  for (var _i = 0; _i < arguments.length; _i++) {
1157
- parts[_i] = arguments[_i];
1155
+ args[_i] = arguments[_i];
1158
1156
  }
1159
- if (logLevel < LogLevel.Error) return;
1160
- console.error.apply(console, parts); // eslint-disable-line no-console
1161
- }
1157
+ return (logLevel >= LogLevel.Error ? console.error : noop$1).apply(void 0, args);
1158
+ }; // eslint-disable-line no-console
1162
1159
 
1163
1160
  exports.defaultAuthUrl = 'https://portal-api.idmission.com';
1164
1161
  var allowedAuthUrls = ['https://portal-api.idmission.com', 'https://portal-api-uat.idmission.com', 'https://portal-api-demo.idmission.com', 'https://portal-api-dev.idmission.com', 'http://localhost:10000'];
@@ -9108,6 +9105,7 @@
9108
9105
  return createImpl;
9109
9106
  };
9110
9107
 
9108
+ var LOG_TAG$1 = 'camera:Camera';
9111
9109
  function listAvailableCameras(facingMode_1) {
9112
9110
  return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
9113
9111
  var cameraEnumerationStream, allDevices, allowedVideoDevices;
@@ -9170,21 +9168,24 @@
9170
9168
  var currentCamera;
9171
9169
  function obtainCameraAccess(stream, deviceLabel, video) {
9172
9170
  releaseCameraAccess();
9173
- log('obtaining camera access...');
9171
+ log("".concat(LOG_TAG$1, " obtaining camera access..."));
9174
9172
  var _a = stream.getVideoTracks()[0].getSettings(),
9175
9173
  width = _a.width,
9176
9174
  height = _a.height;
9177
- log('camera dimensions', width, height);
9175
+ log("".concat(LOG_TAG$1, " camera dimensions"), width, height);
9178
9176
  var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
9179
- log('camera label', label);
9177
+ log("".concat(LOG_TAG$1, " camera label"), label);
9180
9178
  var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
9181
- log('is rear facing?', isRearFacing);
9179
+ log("".concat(LOG_TAG$1, " is rear facing?"), isRearFacing);
9182
9180
  var release = function release() {
9181
+ debug("".concat(LOG_TAG$1, " camera releasing stream"), stream);
9183
9182
  stream.getTracks().forEach(function (track) {
9184
9183
  track.enabled = false;
9184
+ debug("".concat(LOG_TAG$1, " camera stopping stream track"), track);
9185
9185
  track.stop();
9186
9186
  });
9187
9187
  if (video) {
9188
+ debug("".concat(LOG_TAG$1, " camera releasing video element"), video);
9188
9189
  video.pause();
9189
9190
  video.srcObject = null;
9190
9191
  video.src = '';
@@ -9200,14 +9201,14 @@
9200
9201
  isRearFacing: isRearFacing,
9201
9202
  release: release
9202
9203
  };
9203
- log('camera access granted');
9204
+ log("".concat(LOG_TAG$1, " camera access granted"), currentCamera);
9204
9205
  // if (video) video.srcObject = stream
9205
9206
  // log('video source initialized')
9206
9207
  return currentCamera;
9207
9208
  }
9208
9209
  function releaseCameraAccess() {
9209
9210
  if (!currentCamera) return;
9210
- log('releasing camera access...');
9211
+ log("".concat(LOG_TAG$1, " releasing camera access..."));
9211
9212
  currentCamera.release();
9212
9213
  currentCamera = undefined;
9213
9214
  }
@@ -13149,6 +13150,7 @@
13149
13150
  }, [fallbacks, i18n.language, t, verbiage]);
13150
13151
  }
13151
13152
 
13153
+ var LOG_TAG = 'camera:store';
13152
13154
  var camera = null;
13153
13155
  var videoStream = null;
13154
13156
  var audioStream = null;
@@ -13174,7 +13176,8 @@
13174
13176
  var store = createStore(function (set, get) {
13175
13177
  return _assign(_assign(_assign({}, initialState$6), config), {
13176
13178
  reset: function reset() {
13177
- return set(_assign(_assign({}, initialState$6), config));
13179
+ debug("".concat(LOG_TAG, " reset"));
13180
+ set(_assign(_assign({}, initialState$6), config));
13178
13181
  },
13179
13182
  setConfig: function setConfig(config) {
13180
13183
  return set(config);
@@ -13205,6 +13208,7 @@
13205
13208
  return __generator(this, function (_f) {
13206
13209
  switch (_f.label) {
13207
13210
  case 0:
13211
+ debug("".concat(LOG_TAG, " requestCameraAccess"), new Error().stack);
13208
13212
  _a = get(), videoRef = _a.videoRef, releaseCameraAccess = _a.releaseCameraAccess, preferFrontFacingCamera = _a.preferFrontFacingCamera, preferIphoneContinuityCamera = _a.preferIphoneContinuityCamera, iphoneContinuityCameraDenied = _a.iphoneContinuityCameraDenied;
13209
13213
  releaseCameraAccess();
13210
13214
  _f.label = 1;
@@ -13214,9 +13218,9 @@
13214
13218
  case 2:
13215
13219
  availableCameras = _f.sent();
13216
13220
  selectedCamera = void 0;
13217
- debug('availableCameras', availableCameras);
13221
+ debug("".concat(LOG_TAG, " availableCameras"), availableCameras);
13218
13222
  platform_1 = getPlatform();
13219
- debug('platformDetails', platform_1);
13223
+ debug("".concat(LOG_TAG, " platformDetails"), platform_1);
13220
13224
  if (!iphoneContinuityCameraDenied && (!(platform_1 === null || platform_1 === void 0 ? void 0 : platform_1.os) || platform_1.os.family === 'OS X')) {
13221
13225
  iphoneContinuityCamera = availableCameras.find(function (deviceInfo) {
13222
13226
  return cameraLabelMatches(deviceInfo, 'iphone');
@@ -13233,7 +13237,7 @@
13233
13237
  availableCameras = availableCameras.sort(function (a, b) {
13234
13238
  return a.label.toLowerCase().localeCompare(b.label.toLowerCase());
13235
13239
  });
13236
- debug('cameras have been sorted', availableCameras);
13240
+ debug("".concat(LOG_TAG, " cameras have been sorted"), availableCameras);
13237
13241
  }
13238
13242
  if (preferFrontFacingCamera) {
13239
13243
  selectedCamera = availableCameras.find(function (deviceInfo) {
@@ -13257,7 +13261,7 @@
13257
13261
  selectedCamera || (selectedCamera = availableCameras[1]);
13258
13262
  }
13259
13263
  selectedCamera || (selectedCamera = availableCameras[0]);
13260
- debug('selectedCamera', selectedCamera);
13264
+ debug("".concat(LOG_TAG, " selectedCamera"), selectedCamera);
13261
13265
  set({
13262
13266
  videoDevice: selectedCamera
13263
13267
  });
@@ -13285,7 +13289,7 @@
13285
13289
  _f.label = 3;
13286
13290
  case 3:
13287
13291
  _f.trys.push([3, 5,, 6]);
13288
- debug('obtaining camera access with constraints', constraints);
13292
+ debug("".concat(LOG_TAG, " obtaining camera access with constraints"), constraints);
13289
13293
  return [4 /*yield*/, navigator.mediaDevices.getUserMedia(constraints)];
13290
13294
  case 4:
13291
13295
  stream_1 = _f.sent();
@@ -13317,21 +13321,21 @@
13317
13321
  })];
13318
13322
  case 8:
13319
13323
  stream_1 = _f.sent();
13320
- debug('opened stream with no width and height constraints');
13324
+ debug("".concat(LOG_TAG, " opened stream with no width and height constraints"));
13321
13325
  return [3 /*break*/, 10];
13322
13326
  case 9:
13323
13327
  e_2 = _f.sent();
13324
- debug('cannot open stream at all', e_2);
13328
+ debug("".concat(LOG_TAG, " cannot open stream at all"), e_2);
13325
13329
  return [3 /*break*/, 10];
13326
13330
  case 10:
13327
13331
  if (!stream_1) {
13328
- error('failed to open camera');
13332
+ error("".concat(LOG_TAG, " failed to open camera"));
13329
13333
  throw new Error('failed to open camera: ');
13330
13334
  }
13331
- debug('camera access granted with constraints', constraints);
13335
+ debug("".concat(LOG_TAG, " camera access requested with constraints"), constraints);
13332
13336
  handleStreamEnded_1 = function handleStreamEnded_1() {
13333
13337
  if (preferIphoneContinuityCamera && get().iphoneContinuityCameraAvailable) {
13334
- debug('someone unplugged the continuity camera');
13338
+ debug("".concat(LOG_TAG, " someone unplugged the continuity camera"), camera);
13335
13339
  videoStream = null;
13336
13340
  set({
13337
13341
  videoDevice: null,
@@ -13339,10 +13343,8 @@
13339
13343
  iphoneContinuityCameraAvailable: false,
13340
13344
  iphoneContinuityCameraDenied: true
13341
13345
  });
13342
- get().requestCameraAccess();
13343
13346
  } else {
13344
- debug('someone unplugged the webcam');
13345
- get().releaseCameraAccess();
13347
+ debug("".concat(LOG_TAG, " someone unplugged the webcam"), camera);
13346
13348
  videoStream = null;
13347
13349
  set({
13348
13350
  videoDevice: null,
@@ -13352,16 +13354,25 @@
13352
13354
  });
13353
13355
  }
13354
13356
  };
13355
- (_d = videoRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener('ended', handleStreamEnded_1);
13357
+ (_d = videoRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener('ended', function () {
13358
+ debug("".concat(LOG_TAG, ":handleStreamEnded HTMLVideoElement ended event"));
13359
+ handleStreamEnded_1();
13360
+ });
13356
13361
  videoTrack_1 = stream_1.getVideoTracks()[0];
13357
- videoTrack_1.onended = handleStreamEnded_1;
13362
+ videoTrack_1.onended = function () {
13363
+ debug("".concat(LOG_TAG, ":handleStreamEnded MediaStreamTrack onended"), 'videoStream', videoStream, 'videoTrack', videoTrack_1, 'camera', camera);
13364
+ handleStreamEnded_1();
13365
+ };
13358
13366
  camera = obtainCameraAccess(stream_1, selectedCamera.label, videoRef.current);
13359
13367
  setTimeout(function () {
13360
13368
  var _a;
13361
13369
  // iOS 17 has a strange behavior where the video track flickers between muted and unmuted
13362
13370
  // when the camera access is being requested. This delay is a workaround for that.
13363
13371
  videoTrack_1.onmute = function () {
13364
- if (videoTrack_1.readyState !== 'live') handleStreamEnded_1();
13372
+ if (videoTrack_1.readyState !== 'live') {
13373
+ debug("".concat(LOG_TAG, ":handleStreamEnded MediaStreamTrack onmute"), 'videoStream', videoStream, 'videoTrack', videoTrack_1);
13374
+ handleStreamEnded_1();
13375
+ }
13365
13376
  };
13366
13377
  videoStream = stream_1;
13367
13378
  var isRearFacing = (_a = camera === null || camera === void 0 ? void 0 : camera.isRearFacing) !== null && _a !== void 0 ? _a : false;
@@ -13375,12 +13386,12 @@
13375
13386
  case 11:
13376
13387
  e_3 = _f.sent();
13377
13388
  if (e_3.name === 'NotAllowedError' || ((_e = e_3.message) === null || _e === void 0 ? void 0 : _e.includes('Could not start video source'))) {
13378
- error('camera access has been blocked by the user', e_3);
13389
+ error("".concat(LOG_TAG, " camera access has been blocked by the user"), e_3);
13379
13390
  set({
13380
13391
  cameraAccessDenied: true
13381
13392
  });
13382
13393
  } else {
13383
- error('camera access encountered some other error', e_3);
13394
+ error("".concat(LOG_TAG, " camera access encountered some other error"), e_3);
13384
13395
  throw e_3;
13385
13396
  }
13386
13397
  return [3 /*break*/, 12];
@@ -13393,12 +13404,10 @@
13393
13404
  releaseCameraAccess: function releaseCameraAccess() {
13394
13405
  return __awaiter(this, void 0, void 0, function () {
13395
13406
  return __generator(this, function (_a) {
13407
+ debug("".concat(LOG_TAG, " release camera access"), 'camera', camera, 'videoStream', videoStream);
13396
13408
  if (!camera) return [2 /*return*/];
13397
- camera.release();
13409
+ camera.release(); // NOTE calls stop Camera tracks internally as noted above
13398
13410
  camera = null;
13399
- videoStream === null || videoStream === void 0 ? void 0 : videoStream.getTracks().forEach(function (track) {
13400
- track.stop();
13401
- });
13402
13411
  videoStream = null;
13403
13412
  set({
13404
13413
  cameraReady: false,
@@ -13453,7 +13462,7 @@
13453
13462
  return [3 /*break*/, 4];
13454
13463
  case 3:
13455
13464
  e_4 = _a.sent();
13456
- debug('failed to open microphone', e_4);
13465
+ debug("".concat(LOG_TAG, " failed to open microphone"), e_4);
13457
13466
  set({
13458
13467
  microphoneAccessDenied: true
13459
13468
  });
@@ -13480,6 +13489,7 @@
13480
13489
  });
13481
13490
  });
13482
13491
  if (config.requestAccessAutomatically) {
13492
+ debug("".concat(LOG_TAG, " requesting camera access automatically"));
13483
13493
  void store.getState().requestCameraAccess();
13484
13494
  }
13485
13495
  return _assign(_assign({}, store), {
@@ -24273,9 +24283,6 @@
24273
24283
 
24274
24284
  var signatureRecorder = null;
24275
24285
  var signatureChunks = [];
24276
- var ondataavailableInvocations = [];
24277
- var ondataavailableStartTime;
24278
- var lastCalculatedVideoChunkRate;
24279
24286
  var videoSignatureInitialState = {
24280
24287
  startRecording: function startRecording() {
24281
24288
  return null;
@@ -24300,10 +24307,6 @@
24300
24307
  signatureValid: false,
24301
24308
  supportsRequestVideoFrameCallback: undefined,
24302
24309
  supportsRoundRect: undefined,
24303
- nullChunksReceived: 0,
24304
- timesSignatureCleared: 0,
24305
- finalChunkReceived: false,
24306
- requestDataInterval: undefined,
24307
24310
  onSignatureVideoCaptured: function onSignatureVideoCaptured() {
24308
24311
  return null;
24309
24312
  }
@@ -24316,11 +24319,8 @@
24316
24319
  captureAudio = false;
24317
24320
  }
24318
24321
  if (!camera) throw new Error('Camera not found');
24319
- // clear whatever we have recorded so far.
24322
+ // set our flag and clear whatever we have recorded so far.
24320
24323
  signatureChunks = [];
24321
- ondataavailableInvocations = [];
24322
- ondataavailableStartTime = undefined;
24323
- lastCalculatedVideoChunkRate = undefined;
24324
24324
  // start recording from the output canvas to capture the signature
24325
24325
  var outputStream = (_a = get().outputCanvas.current) === null || _a === void 0 ? void 0 : _a.captureStream(24);
24326
24326
  if (!outputStream) throw new Error('outputStream not found');
@@ -24338,123 +24338,77 @@
24338
24338
  recordingStartedAt: e.timeStamp
24339
24339
  });
24340
24340
  };
24341
+ var hasFirstChunk = false;
24341
24342
  signatureRecorder.ondataavailable = function (event) {
24342
- var now = performance.now();
24343
24343
  signatureChunks.push(event.data);
24344
- trackVideoChunkRate(now);
24345
- if (event.data.size > 0) {
24346
- set(function (state) {
24347
- var _a;
24348
- return {
24349
- firstChunkReceivedAt: (_a = state.firstChunkReceivedAt) !== null && _a !== void 0 ? _a : now,
24350
- lastChunkReceivedAt: now
24351
- };
24344
+ if (!hasFirstChunk) {
24345
+ hasFirstChunk = true;
24346
+ set({
24347
+ firstChunkReceivedAt: performance.now(),
24348
+ lastChunkReceivedAt: performance.now()
24352
24349
  });
24353
24350
  } else {
24354
- set(function (state) {
24355
- var _a;
24356
- return {
24357
- nullChunksReceived: state.nullChunksReceived + 1,
24358
- firstNullChunkReceivedAt: (_a = state.firstNullChunkReceivedAt) !== null && _a !== void 0 ? _a : now,
24359
- lastNullChunkReceivedAt: now
24360
- };
24351
+ set({
24352
+ lastChunkReceivedAt: performance.now()
24361
24353
  });
24362
24354
  }
24363
24355
  };
24364
- signatureRecorder.start();
24365
- var interval = setInterval(function () {
24366
- return signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.requestData();
24367
- }, 250);
24356
+ signatureRecorder.start(250);
24368
24357
  set({
24369
- requestDataInterval: interval,
24370
24358
  recordingStartRequestedAt: performance.now()
24371
24359
  });
24372
24360
  },
24373
24361
  stopRecording: function stopRecording(signatureData, imageUrl) {
24374
24362
  return __awaiter(this, void 0, void 0, function () {
24375
- function processVideo() {
24376
- return __awaiter(this, void 0, void 0, function () {
24377
- var recordingStoppedAt, mimeType, blob, _a, onSignatureVideoCaptured, recordingStartRequestedAt, recordingStartedAt, firstChunkReceivedAt, signatureStartedAt, signatureEndedAt, acceptClickedAt, clearClickedAt, recordingStopRequestedAt, lastChunkReceivedAt, supportsRequestVideoFrameCallback, supportsRoundRect, nullChunksReceived, firstNullChunkReceivedAt, lastNullChunkReceivedAt, timesSignatureCleared, metadata;
24378
- return __generator(this, function (_b) {
24379
- if (get().recordingStoppedAt) return [2 /*return*/];
24380
- recordingStoppedAt = performance.now();
24381
- set({
24382
- recordingStoppedAt: recordingStoppedAt
24383
- });
24384
- mimeType = inferBlobType(signatureChunks[0]) || (signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.mimeType) || 'video/mp4';
24385
- blob = new Blob(signatureChunks, {
24386
- type: mimeType
24387
- });
24388
- signatureChunks = [];
24389
- signatureRecorder = null;
24390
- _a = get(), onSignatureVideoCaptured = _a.onSignatureVideoCaptured, recordingStartRequestedAt = _a.recordingStartRequestedAt, recordingStartedAt = _a.recordingStartedAt, firstChunkReceivedAt = _a.firstChunkReceivedAt, signatureStartedAt = _a.signatureStartedAt, signatureEndedAt = _a.signatureEndedAt, acceptClickedAt = _a.acceptClickedAt, clearClickedAt = _a.clearClickedAt, recordingStopRequestedAt = _a.recordingStopRequestedAt, lastChunkReceivedAt = _a.lastChunkReceivedAt, supportsRequestVideoFrameCallback = _a.supportsRequestVideoFrameCallback, supportsRoundRect = _a.supportsRoundRect, nullChunksReceived = _a.nullChunksReceived, firstNullChunkReceivedAt = _a.firstNullChunkReceivedAt, lastNullChunkReceivedAt = _a.lastNullChunkReceivedAt, timesSignatureCleared = _a.timesSignatureCleared;
24391
- metadata = {
24392
- mimeType: mimeType,
24393
- browserFeatures: {
24394
- supportsRoundRect: supportsRoundRect,
24395
- supportsRequestVideoFrameCallback: supportsRequestVideoFrameCallback
24396
- },
24397
- diagnostics: {
24398
- nullChunksReceived: nullChunksReceived,
24399
- firstNullChunkReceivedAt: firstNullChunkReceivedAt ? Math.ceil(firstNullChunkReceivedAt) : 0,
24400
- lastNullChunkReceivedAt: lastNullChunkReceivedAt ? Math.ceil(lastNullChunkReceivedAt) : 0,
24401
- finalChunkReceived: finalChunkReceived,
24402
- finalChunkTimedOut: timedOut,
24403
- finalChunkWaitedMs: Math.ceil(waitedMs),
24404
- videoChunkRate: lastCalculatedVideoChunkRate,
24405
- timesSignatureCleared: timesSignatureCleared
24406
- },
24407
- timingData: {
24408
- recordingStartRequestedAt: recordingStartRequestedAt ? Math.ceil(recordingStartRequestedAt) : 0,
24409
- recordingStartedAt: recordingStartedAt ? Math.ceil(recordingStartedAt) : 0,
24410
- firstChunkReceivedAt: firstChunkReceivedAt ? Math.ceil(firstChunkReceivedAt) : 0,
24411
- signatureStartedAt: signatureStartedAt ? Math.ceil(signatureStartedAt) : 0,
24412
- signatureEndedAt: signatureEndedAt ? Math.ceil(signatureEndedAt) : 0,
24413
- acceptClickedAt: acceptClickedAt ? Math.ceil(acceptClickedAt) : 0,
24414
- clearClickedAt: clearClickedAt ? Math.ceil(clearClickedAt) : 0,
24415
- recordingStopRequestedAt: recordingStopRequestedAt ? Math.ceil(recordingStopRequestedAt) : 0,
24416
- recordingStoppedAt: Math.ceil(recordingStoppedAt),
24417
- lastChunkReceivedAt: lastChunkReceivedAt ? Math.ceil(lastChunkReceivedAt) : 0
24418
- }
24419
- };
24420
- debug('signature video metadata', metadata);
24421
- onSignatureVideoCaptured(blob, signatureData !== null && signatureData !== void 0 ? signatureData : null, imageUrl !== null && imageUrl !== void 0 ? imageUrl : null, metadata);
24422
- return [2 /*return*/];
24423
- });
24424
- });
24425
- }
24426
- var _a, recordingStartedAt, recordingStopRequestedAt, isRecording, _b, finalChunkReceived, timedOut, waitedMs;
24427
- return __generator(this, function (_c) {
24428
- switch (_c.label) {
24363
+ var _this = this;
24364
+ return __generator(this, function (_a) {
24365
+ switch (_a.label) {
24429
24366
  case 0:
24430
- _a = get(), recordingStartedAt = _a.recordingStartedAt, recordingStopRequestedAt = _a.recordingStopRequestedAt;
24431
- isRecording = !!recordingStartedAt && !recordingStopRequestedAt;
24432
- if (!isRecording) return [2 /*return*/];
24433
24367
  set({
24434
- recordingStopRequestedAt: performance.now(),
24435
- recordingStoppedAt: undefined
24368
+ recordingStopRequestedAt: performance.now()
24436
24369
  });
24437
- clearInterval(get().requestDataInterval);
24438
- return [4 /*yield*/, waitForOneMoreChunk()
24439
- // this represents the time that it is safe to release the camera access
24440
- ];
24370
+ if (!signatureRecorder) return [2 /*return*/];
24371
+ return [4 /*yield*/, waitForOneMoreChunk()];
24441
24372
  case 1:
24442
- _b = _c.sent(), finalChunkReceived = _b.finalChunkReceived, timedOut = _b.timedOut, waitedMs = _b.waitedMs;
24443
- // this represents the time that it is safe to release the camera access
24444
- set({
24445
- finalChunkReceived: true
24446
- });
24447
- if (!signatureRecorder) return [3 /*break*/, 2];
24448
- signatureRecorder.onstop = processVideo;
24373
+ _a.sent();
24374
+ signatureRecorder.onstop = function () {
24375
+ return __awaiter(_this, void 0, void 0, function () {
24376
+ var recordingStoppedAt, mimeType, blob, _a, onSignatureVideoCaptured, recordingStartRequestedAt, recordingStartedAt, firstChunkReceivedAt, signatureStartedAt, signatureEndedAt, acceptClickedAt, recordingStopRequestedAt, lastChunkReceivedAt, supportsRequestVideoFrameCallback, supportsRoundRect;
24377
+ return __generator(this, function (_b) {
24378
+ recordingStoppedAt = performance.now();
24379
+ set({
24380
+ recordingStoppedAt: recordingStoppedAt
24381
+ });
24382
+ mimeType = inferBlobType(signatureChunks[0]) || (signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.mimeType) || 'video/mp4';
24383
+ blob = new Blob(signatureChunks, {
24384
+ type: mimeType
24385
+ });
24386
+ signatureChunks = [];
24387
+ signatureRecorder = null;
24388
+ _a = get(), onSignatureVideoCaptured = _a.onSignatureVideoCaptured, recordingStartRequestedAt = _a.recordingStartRequestedAt, recordingStartedAt = _a.recordingStartedAt, firstChunkReceivedAt = _a.firstChunkReceivedAt, signatureStartedAt = _a.signatureStartedAt, signatureEndedAt = _a.signatureEndedAt, acceptClickedAt = _a.acceptClickedAt, recordingStopRequestedAt = _a.recordingStopRequestedAt, lastChunkReceivedAt = _a.lastChunkReceivedAt, supportsRequestVideoFrameCallback = _a.supportsRequestVideoFrameCallback, supportsRoundRect = _a.supportsRoundRect;
24389
+ onSignatureVideoCaptured(blob, signatureData !== null && signatureData !== void 0 ? signatureData : null, imageUrl !== null && imageUrl !== void 0 ? imageUrl : null, {
24390
+ mimeType: mimeType,
24391
+ browserFeatures: {
24392
+ supportsRoundRect: supportsRoundRect,
24393
+ supportsRequestVideoFrameCallback: supportsRequestVideoFrameCallback
24394
+ },
24395
+ timingData: {
24396
+ recordingStartRequestedAt: recordingStartRequestedAt ? Math.ceil(recordingStartRequestedAt) : 0,
24397
+ recordingStartedAt: recordingStartedAt ? Math.ceil(recordingStartedAt) : 0,
24398
+ firstChunkReceivedAt: firstChunkReceivedAt ? Math.ceil(firstChunkReceivedAt) : 0,
24399
+ signatureStartedAt: signatureStartedAt ? Math.ceil(signatureStartedAt) : 0,
24400
+ signatureEndedAt: signatureEndedAt ? Math.ceil(signatureEndedAt) : 0,
24401
+ acceptClickedAt: acceptClickedAt ? Math.ceil(acceptClickedAt) : 0,
24402
+ recordingStopRequestedAt: recordingStopRequestedAt ? Math.ceil(recordingStopRequestedAt) : 0,
24403
+ recordingStoppedAt: Math.ceil(recordingStoppedAt),
24404
+ lastChunkReceivedAt: lastChunkReceivedAt ? Math.ceil(lastChunkReceivedAt) : 0
24405
+ }
24406
+ });
24407
+ return [2 /*return*/];
24408
+ });
24409
+ });
24410
+ };
24449
24411
  signatureRecorder.stop();
24450
- return [3 /*break*/, 4];
24451
- case 2:
24452
- warn('signature recorder not found, processing video immediately');
24453
- return [4 /*yield*/, processVideo()];
24454
- case 3:
24455
- _c.sent();
24456
- _c.label = 4;
24457
- case 4:
24458
24412
  return [2 /*return*/];
24459
24413
  }
24460
24414
  });
@@ -24462,9 +24416,6 @@
24462
24416
  },
24463
24417
  clearRecordedData: function clearRecordedData() {
24464
24418
  signatureChunks = [];
24465
- ondataavailableInvocations = [];
24466
- ondataavailableStartTime = undefined;
24467
- lastCalculatedVideoChunkRate = undefined;
24468
24419
  signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.stop();
24469
24420
  signatureRecorder = null;
24470
24421
  set({
@@ -24479,13 +24430,8 @@
24479
24430
  signatureStartedAt: undefined,
24480
24431
  signatureEndedAt: undefined,
24481
24432
  acceptClickedAt: undefined,
24482
- // Note: clearClickedAt is intentionally preserved for telemetry metadata
24483
24433
  supportsRequestVideoFrameCallback: undefined,
24484
- supportsRoundRect: undefined,
24485
- nullChunksReceived: 0,
24486
- firstNullChunkReceivedAt: undefined,
24487
- lastNullChunkReceivedAt: undefined,
24488
- finalChunkReceived: false
24434
+ supportsRoundRect: undefined
24489
24435
  });
24490
24436
  }
24491
24437
  });
@@ -24495,11 +24441,11 @@
24495
24441
  * @param delayMs - The delay in milliseconds before the first check -- this is used to make sure we get at least one extra second of video.
24496
24442
  * @param checkEveryMs - The interval in milliseconds between checks after the initial delay has passed.
24497
24443
  * @param timeoutMs - The maximum time in milliseconds to wait for the chunk -- this is used to prevent infinite loops.
24498
- * @returns A promise that resolves when the delay has passed and at least one chunk has been received received. The return value is the number of milliseconds that we waited, whether we received a chunk, and whether we timed out.
24444
+ * @returns A promise that resolves when the delay has passed and at least one chunk has been received received.
24499
24445
  */
24500
24446
  function waitForOneMoreChunk(delayMs, checkEveryMs, timeoutMs) {
24501
24447
  if (delayMs === void 0) {
24502
- delayMs = 250;
24448
+ delayMs = 1000;
24503
24449
  }
24504
24450
  if (checkEveryMs === void 0) {
24505
24451
  checkEveryMs = 100;
@@ -24507,44 +24453,29 @@
24507
24453
  if (timeoutMs === void 0) {
24508
24454
  timeoutMs = 3000;
24509
24455
  }
24456
+ var start = performance.now();
24510
24457
  return new Promise(function (resolve) {
24511
- var _a;
24512
- var start = performance.now();
24513
- var initialLastChunkReceivedAt = (_a = useVideoSignatureStore.getState().lastChunkReceivedAt) !== null && _a !== void 0 ? _a : start;
24514
- signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.requestData();
24515
- function checkForChunk() {
24458
+ var initialLastChunkReceivedAt = useVideoSignatureStore.getState().lastChunkReceivedAt;
24459
+ function gotAChunk() {
24516
24460
  var lastChunkReceivedAt = useVideoSignatureStore.getState().lastChunkReceivedAt;
24517
- var waitedMs = performance.now() - start;
24518
- var timedOut = waitedMs > timeoutMs;
24519
- var finalChunkReceived = !!lastChunkReceivedAt && !!initialLastChunkReceivedAt && lastChunkReceivedAt > initialLastChunkReceivedAt;
24520
- return {
24521
- waitedMs: waitedMs,
24522
- finalChunkReceived: finalChunkReceived,
24523
- timedOut: timedOut
24524
- };
24461
+ return performance.now() - start > timeoutMs || !lastChunkReceivedAt || !initialLastChunkReceivedAt || lastChunkReceivedAt > initialLastChunkReceivedAt;
24525
24462
  }
24526
24463
  setTimeout(function () {
24527
- // check immediately
24528
- var result = checkForChunk();
24529
- if (result.finalChunkReceived || result.timedOut) return resolve(result);
24464
+ if (gotAChunk()) return resolve(); // check immediately
24530
24465
  // otherwise, check on a configured interval
24531
24466
  var interval = setInterval(function () {
24532
- var result = checkForChunk();
24533
- if (result.finalChunkReceived || result.timedOut) {
24467
+ if (gotAChunk()) {
24534
24468
  clearInterval(interval);
24535
- resolve(result);
24469
+ resolve();
24536
24470
  }
24537
24471
  }, checkEveryMs);
24538
24472
  }, delayMs);
24539
24473
  });
24540
24474
  }
24541
24475
  function VideoSignatureContextProvider(_a) {
24476
+ var _b, _c;
24542
24477
  var children = _a.children;
24543
- var _b = useCameraStore(),
24544
- videoRef = _b.videoRef,
24545
- videoWidth = _b.videoWidth,
24546
- videoHeight = _b.videoHeight,
24547
- releaseCameraAccess = _b.releaseCameraAccess;
24478
+ var videoRef = useCameraStore().videoRef;
24548
24479
  var outputCanvas = React.useRef(null);
24549
24480
  React.useEffect(function () {
24550
24481
  return useVideoSignatureStore.setState({
@@ -24552,13 +24483,18 @@
24552
24483
  });
24553
24484
  }, []);
24554
24485
  var drawOutputFrame = React.useCallback(function () {
24555
- if (!outputCanvas.current) return;
24486
+ if (!outputCanvas.current || !videoRef.current) return;
24556
24487
  var ctx = outputCanvas.current.getContext('2d');
24557
24488
  if (!ctx) return;
24558
- var _a = [outputCanvas.current.width, outputCanvas.current.height],
24489
+ var _a = [videoRef.current.videoWidth, videoRef.current.videoHeight],
24559
24490
  w = _a[0],
24560
24491
  h = _a[1];
24561
24492
  var isPortrait = w < h;
24493
+ // Only update canvas dimensions if they changed (setting dimensions clears the canvas!)
24494
+ if (outputCanvas.current.width !== w || outputCanvas.current.height !== h) {
24495
+ outputCanvas.current.width = w;
24496
+ outputCanvas.current.height = h;
24497
+ }
24562
24498
  var rect = [w * (isPortrait ? 0.02 : 0.15),
24563
24499
  // x
24564
24500
  h * (isPortrait ? 0.15 : 0.25),
@@ -24567,9 +24503,7 @@
24567
24503
  // width
24568
24504
  h * (isPortrait ? 0.7 : 0.5) // height
24569
24505
  ];
24570
- if (videoRef.current) {
24571
- ctx.drawImage(videoRef.current, 0, 0, w, h);
24572
- }
24506
+ ctx.drawImage(videoRef.current, 0, 0, w, h);
24573
24507
  ctx.beginPath();
24574
24508
  ctx.fillStyle = 'rgba(255,255,255,0.5)';
24575
24509
  var supportsRoundRect = typeof ctx.roundRect === 'function';
@@ -24591,15 +24525,11 @@
24591
24525
  ctx.drawImage.apply(ctx, __spreadArray([signatureCanvas], rect, false));
24592
24526
  }
24593
24527
  }, [videoRef]);
24594
- var finalChunkReceived = useVideoSignatureStore().finalChunkReceived;
24595
- React.useEffect(function () {
24596
- if (finalChunkReceived) releaseCameraAccess();
24597
- }, [finalChunkReceived, releaseCameraAccess]);
24598
- useVideoFrameLoop(videoRef, drawOutputFrame, !finalChunkReceived);
24528
+ useVideoFrameLoop(videoRef, drawOutputFrame);
24599
24529
  return /*#__PURE__*/React.createElement(React.Fragment, null, children, /*#__PURE__*/React.createElement(InvisibleCanvas, {
24600
24530
  ref: outputCanvas,
24601
- width: videoWidth,
24602
- height: videoHeight
24531
+ width: (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.videoWidth,
24532
+ height: (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.videoHeight
24603
24533
  }));
24604
24534
  }
24605
24535
  function requestVideoFrameCallback(video, onFrame) {
@@ -24619,11 +24549,8 @@
24619
24549
  };
24620
24550
  }
24621
24551
  }
24622
- function videoFrameLoop(video, onFrame, running) {
24623
- if (running === void 0) {
24624
- running = true;
24625
- }
24626
- if (!video || !running) return;
24552
+ function videoFrameLoop(video, onFrame) {
24553
+ if (!video) return;
24627
24554
  var cancelFn;
24628
24555
  var canceled = false;
24629
24556
  function onFrameRecursive() {
@@ -24644,51 +24571,10 @@
24644
24571
  if (cancelFn !== undefined) cancelFn();
24645
24572
  };
24646
24573
  }
24647
- function useVideoFrameLoop(ref, onFrame, running) {
24648
- if (running === void 0) {
24649
- running = true;
24650
- }
24574
+ function useVideoFrameLoop(ref, onFrame) {
24651
24575
  React.useEffect(function () {
24652
- return videoFrameLoop(ref.current, onFrame, running);
24653
- }, [onFrame, ref, running]);
24654
- }
24655
- function calculateAndStoreOndataavailableRate() {
24656
- if (ondataavailableInvocations.length < 2 || !ondataavailableStartTime) {
24657
- lastCalculatedVideoChunkRate = {
24658
- averageRate: 0,
24659
- minRate: 0,
24660
- maxRate: 0,
24661
- totalChunksReceived: ondataavailableInvocations.length,
24662
- recordingDurationMs: 0
24663
- };
24664
- return;
24665
- }
24666
- var totalDuration = ondataavailableInvocations[ondataavailableInvocations.length - 1] - ondataavailableStartTime;
24667
- var averageRate = (ondataavailableInvocations.length - 1) / (totalDuration / 1000); // invocations per second
24668
- // Calculate rates for each interval between invocations
24669
- var rates = [];
24670
- for (var i = 1; i < ondataavailableInvocations.length; i++) {
24671
- var intervalMs = ondataavailableInvocations[i] - ondataavailableInvocations[i - 1];
24672
- var rate = 1000 / intervalMs; // invocations per second for this interval
24673
- rates.push(rate);
24674
- }
24675
- var minRate = Math.min.apply(Math, rates);
24676
- var maxRate = Math.max.apply(Math, rates);
24677
- lastCalculatedVideoChunkRate = {
24678
- averageRate: Math.round(averageRate * 100) / 100,
24679
- // Round to 2 decimal places
24680
- minRate: Math.round(minRate * 100) / 100,
24681
- maxRate: Math.round(maxRate * 100) / 100,
24682
- totalChunksReceived: ondataavailableInvocations.length,
24683
- recordingDurationMs: Math.round(totalDuration)
24684
- };
24685
- }
24686
- function trackVideoChunkRate(now) {
24687
- // Track ondataavailable invocations for rate calculation
24688
- ondataavailableStartTime !== null && ondataavailableStartTime !== void 0 ? ondataavailableStartTime : ondataavailableStartTime = now;
24689
- ondataavailableInvocations.push(now);
24690
- // Calculate and store the current rate
24691
- calculateAndStoreOndataavailableRate();
24576
+ return videoFrameLoop(ref.current, onFrame);
24577
+ }, [onFrame, ref]);
24692
24578
  }
24693
24579
 
24694
24580
  function VideoSignaturePad(_a) {
@@ -24940,11 +24826,14 @@
24940
24826
  onHeadTrackingPredictionMade = _o.onPredictionMade,
24941
24827
  startHeadTracking = _o.start,
24942
24828
  stopHeadTracking = _o.stop;
24943
- var firstChunkReceivedAt = useVideoSignatureStore(useShallow(function (state) {
24944
- return {
24945
- firstChunkReceivedAt: state.firstChunkReceivedAt
24946
- };
24947
- })).firstChunkReceivedAt;
24829
+ var _p = useVideoSignatureStore(useShallow(function (state) {
24830
+ return {
24831
+ firstChunkReceivedAt: state.firstChunkReceivedAt,
24832
+ acceptClickedAt: state.acceptClickedAt
24833
+ };
24834
+ })),
24835
+ firstChunkReceivedAt = _p.firstChunkReceivedAt,
24836
+ acceptClickedAt = _p.acceptClickedAt;
24948
24837
  React.useImperativeHandle(ref, function () {
24949
24838
  return {
24950
24839
  clearRecordedData: function clearRecordedData() {
@@ -24970,15 +24859,15 @@
24970
24859
  var verbiage = useTranslations(rawVerbiage, {
24971
24860
  guidanceMessageText: 'Please sign the box below'
24972
24861
  });
24973
- var _p = React.useState(true),
24974
- headTrackingSatisfied = _p[0],
24975
- setHeadTrackingSatisfied = _p[1];
24976
- var _q = React.useState(null),
24977
- lastFace = _q[0],
24978
- setLastFace = _q[1];
24979
- var _r = React.useState(0),
24980
- numFramesWithoutFaces = _r[0],
24981
- setNumFramesWithoutFaces = _r[1];
24862
+ var _q = React.useState(true),
24863
+ headTrackingSatisfied = _q[0],
24864
+ setHeadTrackingSatisfied = _q[1];
24865
+ var _r = React.useState(null),
24866
+ lastFace = _r[0],
24867
+ setLastFace = _r[1];
24868
+ var _s = React.useState(0),
24869
+ numFramesWithoutFaces = _s[0],
24870
+ setNumFramesWithoutFaces = _s[1];
24982
24871
  onHeadTrackingPredictionMade(f(React.useCallback(function (_a) {
24983
24872
  var face = _a.face;
24984
24873
  if (headTrackingDisabled) return;
@@ -24993,12 +24882,12 @@
24993
24882
  return n + 1;
24994
24883
  });
24995
24884
  }, [headTrackingBoundaryPercentage, headTrackingBoundaryType, headTrackingDisabled, videoHeight, videoWidth]), 16));
24996
- var _s = useResizeObserver(),
24997
- containerRef = _s.ref,
24998
- _t = _s.width,
24999
- width = _t === void 0 ? 1 : _t,
25000
- _u = _s.height,
25001
- height = _u === void 0 ? 1 : _u;
24885
+ var _t = useResizeObserver(),
24886
+ containerRef = _t.ref,
24887
+ _u = _t.width,
24888
+ width = _u === void 0 ? 1 : _u,
24889
+ _v = _t.height,
24890
+ height = _v === void 0 ? 1 : _v;
25002
24891
  var debugScalingDetails = useDebugScalingDetails({
25003
24892
  enabled: debugMode,
25004
24893
  pageWidth: width,
@@ -25041,10 +24930,10 @@
25041
24930
  face: lastFace,
25042
24931
  scaling: debugScalingDetails,
25043
24932
  color: headTrackingSatisfied ? 'green' : 'red'
25044
- }))), /*#__PURE__*/React.createElement(DebugStatsPane, null, "Video: ", videoWidth, "x", videoHeight, /*#__PURE__*/React.createElement("br", null), "Recording: ", firstChunkReceivedAt ? 'true' : 'false'))), /*#__PURE__*/React.createElement(ExitCaptureButton, {
24933
+ }))), /*#__PURE__*/React.createElement(DebugStatsPane, null, "Video: ", videoWidth, "x", videoHeight, /*#__PURE__*/React.createElement("br", null), "Recording: ", firstChunkReceivedAt ? 'true' : 'false'))), !acceptClickedAt && ( /*#__PURE__*/React.createElement(ExitCaptureButton, {
25045
24934
  onClick: onExit,
25046
24935
  className: classNames.exitCaptureBtn
25047
- }));
24936
+ })));
25048
24937
  }
25049
24938
  var VideoSignatureCapture = /*#__PURE__*/React.forwardRef(VideoSignatureCaptureComponent);
25050
24939
  var Container$2 = styled.div(templateObject_1$9 || (templateObject_1$9 = __makeTemplateObject(["\n width: 100%;\n height: 100%;\n"], ["\n width: 100%;\n height: 100%;\n"
@@ -25623,18 +25512,13 @@
25623
25512
  });
25624
25513
  }, []);
25625
25514
  var onClearBtnClicked = React.useCallback(function () {
25626
- var _a;
25627
- var _b = useVideoSignatureStore.getState(),
25628
- timesSignatureCleared = _b.timesSignatureCleared,
25629
- signaturePad = _b.signaturePad;
25515
+ var _a, _b;
25630
25516
  useVideoSignatureStore.setState({
25631
- clearClickedAt: performance.now(),
25632
- timesSignatureCleared: timesSignatureCleared + 1,
25633
25517
  signatureStartedAt: undefined,
25634
25518
  signaturePadEmpty: true,
25635
25519
  signatureValid: false
25636
25520
  });
25637
- (_a = signaturePad.current) === null || _a === void 0 ? void 0 : _a.clear();
25521
+ (_b = (_a = useVideoSignatureStore.getState().signaturePad) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.clear();
25638
25522
  if (restartVideoOnSignaturePadCleared) {
25639
25523
  setTimeout(function () {
25640
25524
  useVideoSignatureStore.getState().clearRecordedData();
@@ -26632,7 +26516,6 @@
26632
26516
  idFrontText: 'ID Front Image',
26633
26517
  idBackText: 'ID Back Image'
26634
26518
  });
26635
- var requestCameraAccess = useCameraStore().requestCameraAccess;
26636
26519
  return /*#__PURE__*/React.createElement(OverlayContainer, {
26637
26520
  className: classNames.container
26638
26521
  }, /*#__PURE__*/React.createElement(OverlayInner$2, {
@@ -26691,7 +26574,6 @@
26691
26574
  variant: "warning",
26692
26575
  className: classNames.retryBtn,
26693
26576
  onClick: function onClick() {
26694
- void requestCameraAccess();
26695
26577
  return onRetryClick === null || onRetryClick === void 0 ? void 0 : onRetryClick();
26696
26578
  },
26697
26579
  colors: colors.retryBtn,