easyproctor-hml 2.7.7 → 2.7.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/esm/index.js CHANGED
@@ -13317,6 +13317,16 @@ var _ChunkStorageService = class _ChunkStorageService {
13317
13317
  constructor() {
13318
13318
  this.db = null;
13319
13319
  }
13320
+ /**
13321
+ * WebKit pode falhar em IDB.add/put com "Error preparing Blob/File data..." se o
13322
+ * ArrayBuffer ainda estiver associado ao Blob (ex.: blob.arrayBuffer()) ou no
13323
+ * round-trip get→put do mesmo registro. Esta cópia remove qualquer vínculo.
13324
+ */
13325
+ static detachedArrayBufferCopy(src) {
13326
+ const next = new Uint8Array(src.byteLength);
13327
+ next.set(new Uint8Array(src));
13328
+ return next.buffer;
13329
+ }
13320
13330
  /**
13321
13331
  * Abre a conexão com o IndexedDB, criando o banco e o object store se necessário.
13322
13332
  */
@@ -13356,10 +13366,18 @@ var _ChunkStorageService = class _ChunkStorageService {
13356
13366
  */
13357
13367
  async saveChunk(chunk) {
13358
13368
  const db = await this.connect();
13369
+ const record = {
13370
+ proctoringId: chunk.proctoringId,
13371
+ chunkIndex: chunk.chunkIndex,
13372
+ arrayBuffer: _ChunkStorageService.detachedArrayBufferCopy(chunk.arrayBuffer),
13373
+ timestamp: chunk.timestamp,
13374
+ uploaded: chunk.uploaded,
13375
+ mimeType: chunk.mimeType
13376
+ };
13359
13377
  return new Promise((resolve, reject) => {
13360
13378
  const transaction = db.transaction(_ChunkStorageService.STORE_NAME, "readwrite");
13361
13379
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13362
- const request = store.add(chunk);
13380
+ const request = store.add(record);
13363
13381
  request.onsuccess = () => {
13364
13382
  resolve(request.result);
13365
13383
  };
@@ -13416,36 +13434,35 @@ var _ChunkStorageService = class _ChunkStorageService {
13416
13434
  });
13417
13435
  }
13418
13436
  /**
13419
- * Marca um chunk como enviado (uploaded = 1).
13437
+ * Remove vários chunks numa única transação (delete por chave — sem put com buffer).
13420
13438
  */
13421
- async markAsUploaded(chunkId) {
13439
+ async deleteChunkIds(chunkIds) {
13440
+ if (chunkIds.length === 0) return;
13422
13441
  const db = await this.connect();
13423
13442
  return new Promise((resolve, reject) => {
13424
13443
  const transaction = db.transaction(_ChunkStorageService.STORE_NAME, "readwrite");
13425
13444
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13426
- const getRequest = store.get(chunkId);
13427
- getRequest.onsuccess = () => {
13428
- const chunk = getRequest.result;
13429
- if (!chunk) {
13430
- resolve();
13431
- return;
13432
- }
13433
- chunk.uploaded = 1;
13434
- const putRequest = store.put(chunk);
13435
- putRequest.onsuccess = () => resolve();
13436
- putRequest.onerror = () => {
13437
- var _a2;
13438
- return reject(new Error(`Erro ao marcar chunk como enviado: ${(_a2 = putRequest.error) == null ? void 0 : _a2.message}`));
13439
- };
13445
+ transaction.oncomplete = () => resolve();
13446
+ transaction.onerror = () => {
13447
+ var _a2, _b;
13448
+ return reject(
13449
+ new Error(
13450
+ `Erro ao remover chunks em lote: ${(_b = (_a2 = transaction.error) == null ? void 0 : _a2.message) != null ? _b : "unknown"}`
13451
+ )
13452
+ );
13440
13453
  };
13441
- getRequest.onerror = () => {
13442
- var _a2;
13443
- return reject(new Error(`Erro ao buscar chunk para marcar: ${(_a2 = getRequest.error) == null ? void 0 : _a2.message}`));
13454
+ transaction.onabort = () => {
13455
+ var _a2, _b;
13456
+ return reject(new Error(`Remo\xE7\xE3o em lote abortada: ${(_b = (_a2 = transaction.error) == null ? void 0 : _a2.message) != null ? _b : "unknown"}`));
13444
13457
  };
13458
+ for (const id of chunkIds) {
13459
+ store.delete(id);
13460
+ }
13445
13461
  });
13446
13462
  }
13447
13463
  /**
13448
- * Remove todos os chunks enviados de um proctoringId para liberar espaço.
13464
+ * Remove registros com uploaded = 1 (vestígio de versões antigas que faziam put).
13465
+ * Usa openKeyCursor + delete por primaryKey para não materializar o valor (WebKit/iOS).
13449
13466
  */
13450
13467
  async clearUploadedChunks(proctoringId2) {
13451
13468
  const db = await this.connect();
@@ -13454,11 +13471,11 @@ var _ChunkStorageService = class _ChunkStorageService {
13454
13471
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13455
13472
  const index = store.index("proctoringId_uploaded");
13456
13473
  const range = IDBKeyRange.only([proctoringId2, 1]);
13457
- const request = index.openCursor(range);
13474
+ const request = index.openKeyCursor(range);
13458
13475
  request.onsuccess = () => {
13459
13476
  const cursor = request.result;
13460
13477
  if (cursor) {
13461
- cursor.delete();
13478
+ store.delete(cursor.primaryKey);
13462
13479
  cursor.continue();
13463
13480
  } else {
13464
13481
  resolve();
@@ -13480,11 +13497,11 @@ var _ChunkStorageService = class _ChunkStorageService {
13480
13497
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13481
13498
  const index = store.index("proctoringId");
13482
13499
  const range = IDBKeyRange.only(proctoringId2);
13483
- const request = index.openCursor(range);
13500
+ const request = index.openKeyCursor(range);
13484
13501
  request.onsuccess = () => {
13485
13502
  const cursor = request.result;
13486
13503
  if (cursor) {
13487
- cursor.delete();
13504
+ store.delete(cursor.primaryKey);
13488
13505
  cursor.continue();
13489
13506
  } else {
13490
13507
  resolve();
@@ -13551,8 +13568,8 @@ var _ChunkStorageService = class _ChunkStorageService {
13551
13568
  }
13552
13569
  };
13553
13570
  _ChunkStorageService.DB_NAME = "EasyProctorChunksDb";
13554
- /** v2: índices numéricos; v3: payload em ArrayBuffer (Safari/iOS com Blob no IDB) */
13555
- _ChunkStorageService.DB_VERSION = 3;
13571
+ /** v2: índices numéricos; v3: ArrayBuffer no payload; v4: cópia explícita de bytes (WebKit/iOS) */
13572
+ _ChunkStorageService.DB_VERSION = 4;
13556
13573
  _ChunkStorageService.STORE_NAME = "chunks";
13557
13574
  var ChunkStorageService = _ChunkStorageService;
13558
13575
 
@@ -13713,6 +13730,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
13713
13730
  */
13714
13731
  async processQueue(isFinal = false) {
13715
13732
  var _a2, _b, _c2, _d, _e3, _f;
13733
+ console.log(`[BackgroundUpload] processQueue init`);
13716
13734
  if (this.isProcessing) return;
13717
13735
  this.isProcessing = true;
13718
13736
  try {
@@ -13725,8 +13743,10 @@ var BackgroundUploadService = class _BackgroundUploadService {
13725
13743
  return;
13726
13744
  }
13727
13745
  }
13746
+ console.log(`[BackgroundUpload] processQueue syncOffset ok`);
13728
13747
  const allChunks = await this.chunkStorage.getAllChunks(this.proctoringId);
13729
13748
  const pendingChunks = allChunks.filter((c3) => c3.uploaded === 0);
13749
+ console.log(`[BackgroundUpload] processQueue getAllChunks ok`);
13730
13750
  if (pendingChunks.length === 0 && !isFinal) {
13731
13751
  this.isProcessing = false;
13732
13752
  return;
@@ -13743,6 +13763,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
13743
13763
  let lastProcessedChunkId = null;
13744
13764
  let finalChunkIndex = 0;
13745
13765
  const mimeType = (_d = (_c2 = (_a2 = pendingChunks[0]) == null ? void 0 : _a2.mimeType) != null ? _c2 : (_b = allChunks[allChunks.length - 1]) == null ? void 0 : _b.mimeType) != null ? _d : "video/webm";
13766
+ console.log(`[BackgroundUpload] passo 1 ok`);
13746
13767
  for (const meta of chunksWithMeta) {
13747
13768
  if (this.currentOffset > meta.end) continue;
13748
13769
  const sliceStart = Math.max(0, this.currentOffset - meta.start);
@@ -13751,11 +13772,13 @@ var BackgroundUploadService = class _BackgroundUploadService {
13751
13772
  lastProcessedChunkId = meta.chunk.id;
13752
13773
  finalChunkIndex = meta.chunk.chunkIndex;
13753
13774
  }
13775
+ console.log(`[BackgroundUpload] passo 2 ok`);
13754
13776
  if (combinedBufferParts.length === 0 && !isFinal) {
13755
13777
  this.isProcessing = false;
13756
13778
  return;
13757
13779
  }
13758
13780
  const fullBuffer = _BackgroundUploadService.concatArrayBuffers(combinedBufferParts);
13781
+ console.log(`[BackgroundUpload] passo 3 ok`);
13759
13782
  let sendableSize = fullBuffer.byteLength;
13760
13783
  let totalSizeForHeader = void 0;
13761
13784
  if (!isFinal) {
@@ -13768,33 +13791,44 @@ var BackgroundUploadService = class _BackgroundUploadService {
13768
13791
  } else {
13769
13792
  totalSizeForHeader = virtualStart;
13770
13793
  }
13794
+ console.log(`[BackgroundUpload] passo 4 ok`);
13771
13795
  const bufferToSend = sendableSize < fullBuffer.byteLength ? fullBuffer.slice(0, sendableSize) : fullBuffer;
13772
13796
  try {
13773
13797
  await this.uploadData(bufferToSend, mimeType, finalChunkIndex, totalSizeForHeader);
13774
- for (const meta of chunksWithMeta) {
13775
- if (meta.chunk.uploaded === 0 && meta.end < this.currentOffset) {
13776
- await this.chunkStorage.markAsUploaded(meta.chunk.id);
13798
+ console.log(`[BackgroundUpload] passo 5 ok`);
13799
+ const fullySent = chunksWithMeta.filter(
13800
+ (meta) => meta.chunk.uploaded === 0 && meta.end < this.currentOffset && meta.chunk.id != null
13801
+ );
13802
+ const sizePurged = fullySent.reduce(
13803
+ (acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
13804
+ 0
13805
+ );
13806
+ const idsToDelete = fullySent.map((m3) => m3.chunk.id);
13807
+ if (idsToDelete.length > 0) {
13808
+ await this.chunkStorage.deleteChunkIds(idsToDelete);
13809
+ for (const meta of fullySent) {
13777
13810
  this.retryCount.delete(meta.chunk.id);
13778
13811
  (_e3 = this.onChunkUploaded) == null ? void 0 : _e3.call(this, meta.chunk.id, meta.chunk.chunkIndex);
13779
- console.log(`[BackgroundUpload] Chunk ${meta.chunk.chunkIndex} marcado como enviado.`);
13812
+ console.log(
13813
+ `[BackgroundUpload] Chunk ${meta.chunk.chunkIndex} removido do IndexedDB ap\xF3s upload.`
13814
+ );
13780
13815
  }
13781
13816
  }
13782
- if (this.config.cleanAfterUpload) {
13783
- const chunksToClear = chunksWithMeta.filter((meta) => meta.chunk.uploaded === 1 || meta.chunk.uploaded === 0 && meta.end < this.currentOffset);
13784
- const sizePurged = chunksToClear.reduce(
13785
- (acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
13786
- 0
13817
+ console.log(`[BackgroundUpload] passo 6 ok`);
13818
+ await this.chunkStorage.clearUploadedChunks(this.proctoringId);
13819
+ console.log(`[BackgroundUpload] passo 7 ok`);
13820
+ if (this.config.cleanAfterUpload && sizePurged > 0) {
13821
+ this.totalBytesPurged += sizePurged;
13822
+ this.saveSessionState();
13823
+ console.log(
13824
+ `[BackgroundUpload] ${sizePurged} bytes limpos do armazenamento local. Total purgado: ${this.totalBytesPurged}`
13787
13825
  );
13788
- await this.chunkStorage.clearUploadedChunks(this.proctoringId);
13789
- if (sizePurged > 0) {
13790
- this.totalBytesPurged += sizePurged;
13791
- this.saveSessionState();
13792
- console.log(`[BackgroundUpload] ${sizePurged} bytes limpos do armazenamento local. Total purgado: ${this.totalBytesPurged}`);
13793
- }
13794
13826
  }
13827
+ console.log(`[BackgroundUpload] passo 8 ok`);
13795
13828
  if (isFinal) {
13796
13829
  this.clearSessionState();
13797
13830
  }
13831
+ console.log(`[BackgroundUpload] passo 9 ok`);
13798
13832
  } catch (error) {
13799
13833
  console.error("[BackgroundUpload] Falha no upload:", error);
13800
13834
  (_f = this.onUploadError) == null ? void 0 : _f.call(this, lastProcessedChunkId || 0, error);
@@ -14418,7 +14452,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14418
14452
  * Salva o chunk no IndexedDB para persistência e recuperação.
14419
14453
  */
14420
14454
  async handleNewChunk(blob, idx) {
14421
- if (!this.proctoringId || !this.chunkStorage) return;
14455
+ if (!this.proctoringId || !this.chunkStorage || blob.size == 0) return;
14422
14456
  const savePromise = (async () => {
14423
14457
  var _a2;
14424
14458
  try {
package/index.js CHANGED
@@ -31414,6 +31414,16 @@ var _ChunkStorageService = class _ChunkStorageService {
31414
31414
  constructor() {
31415
31415
  this.db = null;
31416
31416
  }
31417
+ /**
31418
+ * WebKit pode falhar em IDB.add/put com "Error preparing Blob/File data..." se o
31419
+ * ArrayBuffer ainda estiver associado ao Blob (ex.: blob.arrayBuffer()) ou no
31420
+ * round-trip get→put do mesmo registro. Esta cópia remove qualquer vínculo.
31421
+ */
31422
+ static detachedArrayBufferCopy(src) {
31423
+ const next = new Uint8Array(src.byteLength);
31424
+ next.set(new Uint8Array(src));
31425
+ return next.buffer;
31426
+ }
31417
31427
  /**
31418
31428
  * Abre a conexão com o IndexedDB, criando o banco e o object store se necessário.
31419
31429
  */
@@ -31453,10 +31463,18 @@ var _ChunkStorageService = class _ChunkStorageService {
31453
31463
  */
31454
31464
  async saveChunk(chunk) {
31455
31465
  const db = await this.connect();
31466
+ const record = {
31467
+ proctoringId: chunk.proctoringId,
31468
+ chunkIndex: chunk.chunkIndex,
31469
+ arrayBuffer: _ChunkStorageService.detachedArrayBufferCopy(chunk.arrayBuffer),
31470
+ timestamp: chunk.timestamp,
31471
+ uploaded: chunk.uploaded,
31472
+ mimeType: chunk.mimeType
31473
+ };
31456
31474
  return new Promise((resolve, reject) => {
31457
31475
  const transaction = db.transaction(_ChunkStorageService.STORE_NAME, "readwrite");
31458
31476
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31459
- const request = store.add(chunk);
31477
+ const request = store.add(record);
31460
31478
  request.onsuccess = () => {
31461
31479
  resolve(request.result);
31462
31480
  };
@@ -31513,36 +31531,35 @@ var _ChunkStorageService = class _ChunkStorageService {
31513
31531
  });
31514
31532
  }
31515
31533
  /**
31516
- * Marca um chunk como enviado (uploaded = 1).
31534
+ * Remove vários chunks numa única transação (delete por chave — sem put com buffer).
31517
31535
  */
31518
- async markAsUploaded(chunkId) {
31536
+ async deleteChunkIds(chunkIds) {
31537
+ if (chunkIds.length === 0) return;
31519
31538
  const db = await this.connect();
31520
31539
  return new Promise((resolve, reject) => {
31521
31540
  const transaction = db.transaction(_ChunkStorageService.STORE_NAME, "readwrite");
31522
31541
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31523
- const getRequest = store.get(chunkId);
31524
- getRequest.onsuccess = () => {
31525
- const chunk = getRequest.result;
31526
- if (!chunk) {
31527
- resolve();
31528
- return;
31529
- }
31530
- chunk.uploaded = 1;
31531
- const putRequest = store.put(chunk);
31532
- putRequest.onsuccess = () => resolve();
31533
- putRequest.onerror = () => {
31534
- var _a2;
31535
- return reject(new Error(`Erro ao marcar chunk como enviado: ${(_a2 = putRequest.error) == null ? void 0 : _a2.message}`));
31536
- };
31542
+ transaction.oncomplete = () => resolve();
31543
+ transaction.onerror = () => {
31544
+ var _a2, _b;
31545
+ return reject(
31546
+ new Error(
31547
+ `Erro ao remover chunks em lote: ${(_b = (_a2 = transaction.error) == null ? void 0 : _a2.message) != null ? _b : "unknown"}`
31548
+ )
31549
+ );
31537
31550
  };
31538
- getRequest.onerror = () => {
31539
- var _a2;
31540
- return reject(new Error(`Erro ao buscar chunk para marcar: ${(_a2 = getRequest.error) == null ? void 0 : _a2.message}`));
31551
+ transaction.onabort = () => {
31552
+ var _a2, _b;
31553
+ return reject(new Error(`Remo\xE7\xE3o em lote abortada: ${(_b = (_a2 = transaction.error) == null ? void 0 : _a2.message) != null ? _b : "unknown"}`));
31541
31554
  };
31555
+ for (const id of chunkIds) {
31556
+ store.delete(id);
31557
+ }
31542
31558
  });
31543
31559
  }
31544
31560
  /**
31545
- * Remove todos os chunks enviados de um proctoringId para liberar espaço.
31561
+ * Remove registros com uploaded = 1 (vestígio de versões antigas que faziam put).
31562
+ * Usa openKeyCursor + delete por primaryKey para não materializar o valor (WebKit/iOS).
31546
31563
  */
31547
31564
  async clearUploadedChunks(proctoringId2) {
31548
31565
  const db = await this.connect();
@@ -31551,11 +31568,11 @@ var _ChunkStorageService = class _ChunkStorageService {
31551
31568
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31552
31569
  const index = store.index("proctoringId_uploaded");
31553
31570
  const range = IDBKeyRange.only([proctoringId2, 1]);
31554
- const request = index.openCursor(range);
31571
+ const request = index.openKeyCursor(range);
31555
31572
  request.onsuccess = () => {
31556
31573
  const cursor = request.result;
31557
31574
  if (cursor) {
31558
- cursor.delete();
31575
+ store.delete(cursor.primaryKey);
31559
31576
  cursor.continue();
31560
31577
  } else {
31561
31578
  resolve();
@@ -31577,11 +31594,11 @@ var _ChunkStorageService = class _ChunkStorageService {
31577
31594
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31578
31595
  const index = store.index("proctoringId");
31579
31596
  const range = IDBKeyRange.only(proctoringId2);
31580
- const request = index.openCursor(range);
31597
+ const request = index.openKeyCursor(range);
31581
31598
  request.onsuccess = () => {
31582
31599
  const cursor = request.result;
31583
31600
  if (cursor) {
31584
- cursor.delete();
31601
+ store.delete(cursor.primaryKey);
31585
31602
  cursor.continue();
31586
31603
  } else {
31587
31604
  resolve();
@@ -31648,8 +31665,8 @@ var _ChunkStorageService = class _ChunkStorageService {
31648
31665
  }
31649
31666
  };
31650
31667
  _ChunkStorageService.DB_NAME = "EasyProctorChunksDb";
31651
- /** v2: índices numéricos; v3: payload em ArrayBuffer (Safari/iOS com Blob no IDB) */
31652
- _ChunkStorageService.DB_VERSION = 3;
31668
+ /** v2: índices numéricos; v3: ArrayBuffer no payload; v4: cópia explícita de bytes (WebKit/iOS) */
31669
+ _ChunkStorageService.DB_VERSION = 4;
31653
31670
  _ChunkStorageService.STORE_NAME = "chunks";
31654
31671
  var ChunkStorageService = _ChunkStorageService;
31655
31672
 
@@ -31810,6 +31827,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
31810
31827
  */
31811
31828
  async processQueue(isFinal = false) {
31812
31829
  var _a2, _b, _c2, _d, _e3, _f;
31830
+ console.log(`[BackgroundUpload] processQueue init`);
31813
31831
  if (this.isProcessing) return;
31814
31832
  this.isProcessing = true;
31815
31833
  try {
@@ -31822,8 +31840,10 @@ var BackgroundUploadService = class _BackgroundUploadService {
31822
31840
  return;
31823
31841
  }
31824
31842
  }
31843
+ console.log(`[BackgroundUpload] processQueue syncOffset ok`);
31825
31844
  const allChunks = await this.chunkStorage.getAllChunks(this.proctoringId);
31826
31845
  const pendingChunks = allChunks.filter((c3) => c3.uploaded === 0);
31846
+ console.log(`[BackgroundUpload] processQueue getAllChunks ok`);
31827
31847
  if (pendingChunks.length === 0 && !isFinal) {
31828
31848
  this.isProcessing = false;
31829
31849
  return;
@@ -31840,6 +31860,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
31840
31860
  let lastProcessedChunkId = null;
31841
31861
  let finalChunkIndex = 0;
31842
31862
  const mimeType = (_d = (_c2 = (_a2 = pendingChunks[0]) == null ? void 0 : _a2.mimeType) != null ? _c2 : (_b = allChunks[allChunks.length - 1]) == null ? void 0 : _b.mimeType) != null ? _d : "video/webm";
31863
+ console.log(`[BackgroundUpload] passo 1 ok`);
31843
31864
  for (const meta of chunksWithMeta) {
31844
31865
  if (this.currentOffset > meta.end) continue;
31845
31866
  const sliceStart = Math.max(0, this.currentOffset - meta.start);
@@ -31848,11 +31869,13 @@ var BackgroundUploadService = class _BackgroundUploadService {
31848
31869
  lastProcessedChunkId = meta.chunk.id;
31849
31870
  finalChunkIndex = meta.chunk.chunkIndex;
31850
31871
  }
31872
+ console.log(`[BackgroundUpload] passo 2 ok`);
31851
31873
  if (combinedBufferParts.length === 0 && !isFinal) {
31852
31874
  this.isProcessing = false;
31853
31875
  return;
31854
31876
  }
31855
31877
  const fullBuffer = _BackgroundUploadService.concatArrayBuffers(combinedBufferParts);
31878
+ console.log(`[BackgroundUpload] passo 3 ok`);
31856
31879
  let sendableSize = fullBuffer.byteLength;
31857
31880
  let totalSizeForHeader = void 0;
31858
31881
  if (!isFinal) {
@@ -31865,33 +31888,44 @@ var BackgroundUploadService = class _BackgroundUploadService {
31865
31888
  } else {
31866
31889
  totalSizeForHeader = virtualStart;
31867
31890
  }
31891
+ console.log(`[BackgroundUpload] passo 4 ok`);
31868
31892
  const bufferToSend = sendableSize < fullBuffer.byteLength ? fullBuffer.slice(0, sendableSize) : fullBuffer;
31869
31893
  try {
31870
31894
  await this.uploadData(bufferToSend, mimeType, finalChunkIndex, totalSizeForHeader);
31871
- for (const meta of chunksWithMeta) {
31872
- if (meta.chunk.uploaded === 0 && meta.end < this.currentOffset) {
31873
- await this.chunkStorage.markAsUploaded(meta.chunk.id);
31895
+ console.log(`[BackgroundUpload] passo 5 ok`);
31896
+ const fullySent = chunksWithMeta.filter(
31897
+ (meta) => meta.chunk.uploaded === 0 && meta.end < this.currentOffset && meta.chunk.id != null
31898
+ );
31899
+ const sizePurged = fullySent.reduce(
31900
+ (acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
31901
+ 0
31902
+ );
31903
+ const idsToDelete = fullySent.map((m3) => m3.chunk.id);
31904
+ if (idsToDelete.length > 0) {
31905
+ await this.chunkStorage.deleteChunkIds(idsToDelete);
31906
+ for (const meta of fullySent) {
31874
31907
  this.retryCount.delete(meta.chunk.id);
31875
31908
  (_e3 = this.onChunkUploaded) == null ? void 0 : _e3.call(this, meta.chunk.id, meta.chunk.chunkIndex);
31876
- console.log(`[BackgroundUpload] Chunk ${meta.chunk.chunkIndex} marcado como enviado.`);
31909
+ console.log(
31910
+ `[BackgroundUpload] Chunk ${meta.chunk.chunkIndex} removido do IndexedDB ap\xF3s upload.`
31911
+ );
31877
31912
  }
31878
31913
  }
31879
- if (this.config.cleanAfterUpload) {
31880
- const chunksToClear = chunksWithMeta.filter((meta) => meta.chunk.uploaded === 1 || meta.chunk.uploaded === 0 && meta.end < this.currentOffset);
31881
- const sizePurged = chunksToClear.reduce(
31882
- (acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
31883
- 0
31914
+ console.log(`[BackgroundUpload] passo 6 ok`);
31915
+ await this.chunkStorage.clearUploadedChunks(this.proctoringId);
31916
+ console.log(`[BackgroundUpload] passo 7 ok`);
31917
+ if (this.config.cleanAfterUpload && sizePurged > 0) {
31918
+ this.totalBytesPurged += sizePurged;
31919
+ this.saveSessionState();
31920
+ console.log(
31921
+ `[BackgroundUpload] ${sizePurged} bytes limpos do armazenamento local. Total purgado: ${this.totalBytesPurged}`
31884
31922
  );
31885
- await this.chunkStorage.clearUploadedChunks(this.proctoringId);
31886
- if (sizePurged > 0) {
31887
- this.totalBytesPurged += sizePurged;
31888
- this.saveSessionState();
31889
- console.log(`[BackgroundUpload] ${sizePurged} bytes limpos do armazenamento local. Total purgado: ${this.totalBytesPurged}`);
31890
- }
31891
31923
  }
31924
+ console.log(`[BackgroundUpload] passo 8 ok`);
31892
31925
  if (isFinal) {
31893
31926
  this.clearSessionState();
31894
31927
  }
31928
+ console.log(`[BackgroundUpload] passo 9 ok`);
31895
31929
  } catch (error) {
31896
31930
  console.error("[BackgroundUpload] Falha no upload:", error);
31897
31931
  (_f = this.onUploadError) == null ? void 0 : _f.call(this, lastProcessedChunkId || 0, error);
@@ -32515,7 +32549,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32515
32549
  * Salva o chunk no IndexedDB para persistência e recuperação.
32516
32550
  */
32517
32551
  async handleNewChunk(blob, idx) {
32518
- if (!this.proctoringId || !this.chunkStorage) return;
32552
+ if (!this.proctoringId || !this.chunkStorage || blob.size == 0) return;
32519
32553
  const savePromise = (async () => {
32520
32554
  var _a2;
32521
32555
  try {
@@ -12,11 +12,12 @@ export declare class ChunkStorageService {
12
12
  private static readonly DB_VERSION;
13
13
  private static readonly STORE_NAME;
14
14
  private db;
15
+ private static detachedArrayBufferCopy;
15
16
  connect(): Promise<IDBDatabase>;
16
17
  saveChunk(chunk: Omit<VideoChunk, "id">): Promise<number>;
17
18
  getPendingChunks(proctoringId: string): Promise<VideoChunk[]>;
18
19
  getAllChunks(proctoringId: string): Promise<VideoChunk[]>;
19
- markAsUploaded(chunkId: number): Promise<void>;
20
+ deleteChunkIds(chunkIds: number[]): Promise<void>;
20
21
  clearUploadedChunks(proctoringId: string): Promise<void>;
21
22
  clearAllChunks(proctoringId: string): Promise<void>;
22
23
  hasAnyPendingChunks(): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easyproctor-hml",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Modulo web de gravação do EasyProctor",
5
5
  "main": "./index.js",
6
6
  "module": "./esm/index.js",