easyproctor-hml 2.7.8 → 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
@@ -13434,44 +13434,35 @@ var _ChunkStorageService = class _ChunkStorageService {
13434
13434
  });
13435
13435
  }
13436
13436
  /**
13437
- * Marca um chunk como enviado (uploaded = 1).
13437
+ * Remove vários chunks numa única transação (delete por chave — sem put com buffer).
13438
13438
  */
13439
- async markAsUploaded(chunkId) {
13439
+ async deleteChunkIds(chunkIds) {
13440
+ if (chunkIds.length === 0) return;
13440
13441
  const db = await this.connect();
13441
13442
  return new Promise((resolve, reject) => {
13442
13443
  const transaction = db.transaction(_ChunkStorageService.STORE_NAME, "readwrite");
13443
13444
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13444
- const getRequest = store.get(chunkId);
13445
- getRequest.onsuccess = () => {
13446
- const chunk = getRequest.result;
13447
- if (!chunk) {
13448
- resolve();
13449
- return;
13450
- }
13451
- const updated = {
13452
- id: chunk.id,
13453
- proctoringId: chunk.proctoringId,
13454
- chunkIndex: chunk.chunkIndex,
13455
- arrayBuffer: _ChunkStorageService.detachedArrayBufferCopy(chunk.arrayBuffer),
13456
- timestamp: chunk.timestamp,
13457
- uploaded: 1,
13458
- mimeType: chunk.mimeType
13459
- };
13460
- const putRequest = store.put(updated);
13461
- putRequest.onsuccess = () => resolve();
13462
- putRequest.onerror = () => {
13463
- var _a2;
13464
- return reject(new Error(`Erro ao marcar chunk como enviado: ${(_a2 = putRequest.error) == null ? void 0 : _a2.message}`));
13465
- };
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
+ );
13466
13453
  };
13467
- getRequest.onerror = () => {
13468
- var _a2;
13469
- 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"}`));
13470
13457
  };
13458
+ for (const id of chunkIds) {
13459
+ store.delete(id);
13460
+ }
13471
13461
  });
13472
13462
  }
13473
13463
  /**
13474
- * 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).
13475
13466
  */
13476
13467
  async clearUploadedChunks(proctoringId2) {
13477
13468
  const db = await this.connect();
@@ -13480,11 +13471,11 @@ var _ChunkStorageService = class _ChunkStorageService {
13480
13471
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13481
13472
  const index = store.index("proctoringId_uploaded");
13482
13473
  const range = IDBKeyRange.only([proctoringId2, 1]);
13483
- const request = index.openCursor(range);
13474
+ const request = index.openKeyCursor(range);
13484
13475
  request.onsuccess = () => {
13485
13476
  const cursor = request.result;
13486
13477
  if (cursor) {
13487
- cursor.delete();
13478
+ store.delete(cursor.primaryKey);
13488
13479
  cursor.continue();
13489
13480
  } else {
13490
13481
  resolve();
@@ -13506,11 +13497,11 @@ var _ChunkStorageService = class _ChunkStorageService {
13506
13497
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
13507
13498
  const index = store.index("proctoringId");
13508
13499
  const range = IDBKeyRange.only(proctoringId2);
13509
- const request = index.openCursor(range);
13500
+ const request = index.openKeyCursor(range);
13510
13501
  request.onsuccess = () => {
13511
13502
  const cursor = request.result;
13512
13503
  if (cursor) {
13513
- cursor.delete();
13504
+ store.delete(cursor.primaryKey);
13514
13505
  cursor.continue();
13515
13506
  } else {
13516
13507
  resolve();
@@ -13772,6 +13763,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
13772
13763
  let lastProcessedChunkId = null;
13773
13764
  let finalChunkIndex = 0;
13774
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`);
13775
13767
  for (const meta of chunksWithMeta) {
13776
13768
  if (this.currentOffset > meta.end) continue;
13777
13769
  const sliceStart = Math.max(0, this.currentOffset - meta.start);
@@ -13780,11 +13772,13 @@ var BackgroundUploadService = class _BackgroundUploadService {
13780
13772
  lastProcessedChunkId = meta.chunk.id;
13781
13773
  finalChunkIndex = meta.chunk.chunkIndex;
13782
13774
  }
13775
+ console.log(`[BackgroundUpload] passo 2 ok`);
13783
13776
  if (combinedBufferParts.length === 0 && !isFinal) {
13784
13777
  this.isProcessing = false;
13785
13778
  return;
13786
13779
  }
13787
13780
  const fullBuffer = _BackgroundUploadService.concatArrayBuffers(combinedBufferParts);
13781
+ console.log(`[BackgroundUpload] passo 3 ok`);
13788
13782
  let sendableSize = fullBuffer.byteLength;
13789
13783
  let totalSizeForHeader = void 0;
13790
13784
  if (!isFinal) {
@@ -13797,33 +13791,44 @@ var BackgroundUploadService = class _BackgroundUploadService {
13797
13791
  } else {
13798
13792
  totalSizeForHeader = virtualStart;
13799
13793
  }
13794
+ console.log(`[BackgroundUpload] passo 4 ok`);
13800
13795
  const bufferToSend = sendableSize < fullBuffer.byteLength ? fullBuffer.slice(0, sendableSize) : fullBuffer;
13801
13796
  try {
13802
13797
  await this.uploadData(bufferToSend, mimeType, finalChunkIndex, totalSizeForHeader);
13803
- for (const meta of chunksWithMeta) {
13804
- if (meta.chunk.uploaded === 0 && meta.end < this.currentOffset) {
13805
- 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) {
13806
13810
  this.retryCount.delete(meta.chunk.id);
13807
13811
  (_e3 = this.onChunkUploaded) == null ? void 0 : _e3.call(this, meta.chunk.id, meta.chunk.chunkIndex);
13808
- 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
+ );
13809
13815
  }
13810
13816
  }
13811
- if (this.config.cleanAfterUpload) {
13812
- const chunksToClear = chunksWithMeta.filter((meta) => meta.chunk.uploaded === 1 || meta.chunk.uploaded === 0 && meta.end < this.currentOffset);
13813
- const sizePurged = chunksToClear.reduce(
13814
- (acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
13815
- 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}`
13816
13825
  );
13817
- await this.chunkStorage.clearUploadedChunks(this.proctoringId);
13818
- if (sizePurged > 0) {
13819
- this.totalBytesPurged += sizePurged;
13820
- this.saveSessionState();
13821
- console.log(`[BackgroundUpload] ${sizePurged} bytes limpos do armazenamento local. Total purgado: ${this.totalBytesPurged}`);
13822
- }
13823
13826
  }
13827
+ console.log(`[BackgroundUpload] passo 8 ok`);
13824
13828
  if (isFinal) {
13825
13829
  this.clearSessionState();
13826
13830
  }
13831
+ console.log(`[BackgroundUpload] passo 9 ok`);
13827
13832
  } catch (error) {
13828
13833
  console.error("[BackgroundUpload] Falha no upload:", error);
13829
13834
  (_f = this.onUploadError) == null ? void 0 : _f.call(this, lastProcessedChunkId || 0, error);
@@ -14447,7 +14452,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
14447
14452
  * Salva o chunk no IndexedDB para persistência e recuperação.
14448
14453
  */
14449
14454
  async handleNewChunk(blob, idx) {
14450
- if (!this.proctoringId || !this.chunkStorage) return;
14455
+ if (!this.proctoringId || !this.chunkStorage || blob.size == 0) return;
14451
14456
  const savePromise = (async () => {
14452
14457
  var _a2;
14453
14458
  try {
package/index.js CHANGED
@@ -31531,44 +31531,35 @@ var _ChunkStorageService = class _ChunkStorageService {
31531
31531
  });
31532
31532
  }
31533
31533
  /**
31534
- * Marca um chunk como enviado (uploaded = 1).
31534
+ * Remove vários chunks numa única transação (delete por chave — sem put com buffer).
31535
31535
  */
31536
- async markAsUploaded(chunkId) {
31536
+ async deleteChunkIds(chunkIds) {
31537
+ if (chunkIds.length === 0) return;
31537
31538
  const db = await this.connect();
31538
31539
  return new Promise((resolve, reject) => {
31539
31540
  const transaction = db.transaction(_ChunkStorageService.STORE_NAME, "readwrite");
31540
31541
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31541
- const getRequest = store.get(chunkId);
31542
- getRequest.onsuccess = () => {
31543
- const chunk = getRequest.result;
31544
- if (!chunk) {
31545
- resolve();
31546
- return;
31547
- }
31548
- const updated = {
31549
- id: chunk.id,
31550
- proctoringId: chunk.proctoringId,
31551
- chunkIndex: chunk.chunkIndex,
31552
- arrayBuffer: _ChunkStorageService.detachedArrayBufferCopy(chunk.arrayBuffer),
31553
- timestamp: chunk.timestamp,
31554
- uploaded: 1,
31555
- mimeType: chunk.mimeType
31556
- };
31557
- const putRequest = store.put(updated);
31558
- putRequest.onsuccess = () => resolve();
31559
- putRequest.onerror = () => {
31560
- var _a2;
31561
- return reject(new Error(`Erro ao marcar chunk como enviado: ${(_a2 = putRequest.error) == null ? void 0 : _a2.message}`));
31562
- };
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
+ );
31563
31550
  };
31564
- getRequest.onerror = () => {
31565
- var _a2;
31566
- 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"}`));
31567
31554
  };
31555
+ for (const id of chunkIds) {
31556
+ store.delete(id);
31557
+ }
31568
31558
  });
31569
31559
  }
31570
31560
  /**
31571
- * 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).
31572
31563
  */
31573
31564
  async clearUploadedChunks(proctoringId2) {
31574
31565
  const db = await this.connect();
@@ -31577,11 +31568,11 @@ var _ChunkStorageService = class _ChunkStorageService {
31577
31568
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31578
31569
  const index = store.index("proctoringId_uploaded");
31579
31570
  const range = IDBKeyRange.only([proctoringId2, 1]);
31580
- const request = index.openCursor(range);
31571
+ const request = index.openKeyCursor(range);
31581
31572
  request.onsuccess = () => {
31582
31573
  const cursor = request.result;
31583
31574
  if (cursor) {
31584
- cursor.delete();
31575
+ store.delete(cursor.primaryKey);
31585
31576
  cursor.continue();
31586
31577
  } else {
31587
31578
  resolve();
@@ -31603,11 +31594,11 @@ var _ChunkStorageService = class _ChunkStorageService {
31603
31594
  const store = transaction.objectStore(_ChunkStorageService.STORE_NAME);
31604
31595
  const index = store.index("proctoringId");
31605
31596
  const range = IDBKeyRange.only(proctoringId2);
31606
- const request = index.openCursor(range);
31597
+ const request = index.openKeyCursor(range);
31607
31598
  request.onsuccess = () => {
31608
31599
  const cursor = request.result;
31609
31600
  if (cursor) {
31610
- cursor.delete();
31601
+ store.delete(cursor.primaryKey);
31611
31602
  cursor.continue();
31612
31603
  } else {
31613
31604
  resolve();
@@ -31869,6 +31860,7 @@ var BackgroundUploadService = class _BackgroundUploadService {
31869
31860
  let lastProcessedChunkId = null;
31870
31861
  let finalChunkIndex = 0;
31871
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`);
31872
31864
  for (const meta of chunksWithMeta) {
31873
31865
  if (this.currentOffset > meta.end) continue;
31874
31866
  const sliceStart = Math.max(0, this.currentOffset - meta.start);
@@ -31877,11 +31869,13 @@ var BackgroundUploadService = class _BackgroundUploadService {
31877
31869
  lastProcessedChunkId = meta.chunk.id;
31878
31870
  finalChunkIndex = meta.chunk.chunkIndex;
31879
31871
  }
31872
+ console.log(`[BackgroundUpload] passo 2 ok`);
31880
31873
  if (combinedBufferParts.length === 0 && !isFinal) {
31881
31874
  this.isProcessing = false;
31882
31875
  return;
31883
31876
  }
31884
31877
  const fullBuffer = _BackgroundUploadService.concatArrayBuffers(combinedBufferParts);
31878
+ console.log(`[BackgroundUpload] passo 3 ok`);
31885
31879
  let sendableSize = fullBuffer.byteLength;
31886
31880
  let totalSizeForHeader = void 0;
31887
31881
  if (!isFinal) {
@@ -31894,33 +31888,44 @@ var BackgroundUploadService = class _BackgroundUploadService {
31894
31888
  } else {
31895
31889
  totalSizeForHeader = virtualStart;
31896
31890
  }
31891
+ console.log(`[BackgroundUpload] passo 4 ok`);
31897
31892
  const bufferToSend = sendableSize < fullBuffer.byteLength ? fullBuffer.slice(0, sendableSize) : fullBuffer;
31898
31893
  try {
31899
31894
  await this.uploadData(bufferToSend, mimeType, finalChunkIndex, totalSizeForHeader);
31900
- for (const meta of chunksWithMeta) {
31901
- if (meta.chunk.uploaded === 0 && meta.end < this.currentOffset) {
31902
- 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) {
31903
31907
  this.retryCount.delete(meta.chunk.id);
31904
31908
  (_e3 = this.onChunkUploaded) == null ? void 0 : _e3.call(this, meta.chunk.id, meta.chunk.chunkIndex);
31905
- 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
+ );
31906
31912
  }
31907
31913
  }
31908
- if (this.config.cleanAfterUpload) {
31909
- const chunksToClear = chunksWithMeta.filter((meta) => meta.chunk.uploaded === 1 || meta.chunk.uploaded === 0 && meta.end < this.currentOffset);
31910
- const sizePurged = chunksToClear.reduce(
31911
- (acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
31912
- 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}`
31913
31922
  );
31914
- await this.chunkStorage.clearUploadedChunks(this.proctoringId);
31915
- if (sizePurged > 0) {
31916
- this.totalBytesPurged += sizePurged;
31917
- this.saveSessionState();
31918
- console.log(`[BackgroundUpload] ${sizePurged} bytes limpos do armazenamento local. Total purgado: ${this.totalBytesPurged}`);
31919
- }
31920
31923
  }
31924
+ console.log(`[BackgroundUpload] passo 8 ok`);
31921
31925
  if (isFinal) {
31922
31926
  this.clearSessionState();
31923
31927
  }
31928
+ console.log(`[BackgroundUpload] passo 9 ok`);
31924
31929
  } catch (error) {
31925
31930
  console.error("[BackgroundUpload] Falha no upload:", error);
31926
31931
  (_f = this.onUploadError) == null ? void 0 : _f.call(this, lastProcessedChunkId || 0, error);
@@ -32544,7 +32549,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
32544
32549
  * Salva o chunk no IndexedDB para persistência e recuperação.
32545
32550
  */
32546
32551
  async handleNewChunk(blob, idx) {
32547
- if (!this.proctoringId || !this.chunkStorage) return;
32552
+ if (!this.proctoringId || !this.chunkStorage || blob.size == 0) return;
32548
32553
  const savePromise = (async () => {
32549
32554
  var _a2;
32550
32555
  try {
@@ -17,7 +17,7 @@ export declare class ChunkStorageService {
17
17
  saveChunk(chunk: Omit<VideoChunk, "id">): Promise<number>;
18
18
  getPendingChunks(proctoringId: string): Promise<VideoChunk[]>;
19
19
  getAllChunks(proctoringId: string): Promise<VideoChunk[]>;
20
- markAsUploaded(chunkId: number): Promise<void>;
20
+ deleteChunkIds(chunkIds: number[]): Promise<void>;
21
21
  clearUploadedChunks(proctoringId: string): Promise<void>;
22
22
  clearAllChunks(proctoringId: string): Promise<void>;
23
23
  hasAnyPendingChunks(): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easyproctor-hml",
3
- "version": "2.7.8",
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",