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 +77 -43
- package/index.js +77 -43
- package/new-flow/chunk/ChunkStorageService.d.ts +2 -1
- package/package.json +1 -1
- package/unpkg/easyproctor.min.js +17 -17
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(
|
|
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
|
-
*
|
|
13437
|
+
* Remove vários chunks numa única transação (delete por chave — sem put com buffer).
|
|
13420
13438
|
*/
|
|
13421
|
-
async
|
|
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
|
-
|
|
13427
|
-
|
|
13428
|
-
|
|
13429
|
-
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13433
|
-
|
|
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
|
-
|
|
13442
|
-
var _a2;
|
|
13443
|
-
return reject(new Error(`
|
|
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
|
|
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.
|
|
13474
|
+
const request = index.openKeyCursor(range);
|
|
13458
13475
|
request.onsuccess = () => {
|
|
13459
13476
|
const cursor = request.result;
|
|
13460
13477
|
if (cursor) {
|
|
13461
|
-
|
|
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.
|
|
13500
|
+
const request = index.openKeyCursor(range);
|
|
13484
13501
|
request.onsuccess = () => {
|
|
13485
13502
|
const cursor = request.result;
|
|
13486
13503
|
if (cursor) {
|
|
13487
|
-
|
|
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
|
|
13555
|
-
_ChunkStorageService.DB_VERSION =
|
|
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
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
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(
|
|
13812
|
+
console.log(
|
|
13813
|
+
`[BackgroundUpload] Chunk ${meta.chunk.chunkIndex} removido do IndexedDB ap\xF3s upload.`
|
|
13814
|
+
);
|
|
13780
13815
|
}
|
|
13781
13816
|
}
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
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(
|
|
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
|
-
*
|
|
31534
|
+
* Remove vários chunks numa única transação (delete por chave — sem put com buffer).
|
|
31517
31535
|
*/
|
|
31518
|
-
async
|
|
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
|
-
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
31527
|
-
|
|
31528
|
-
|
|
31529
|
-
|
|
31530
|
-
|
|
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
|
-
|
|
31539
|
-
var _a2;
|
|
31540
|
-
return reject(new Error(`
|
|
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
|
|
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.
|
|
31571
|
+
const request = index.openKeyCursor(range);
|
|
31555
31572
|
request.onsuccess = () => {
|
|
31556
31573
|
const cursor = request.result;
|
|
31557
31574
|
if (cursor) {
|
|
31558
|
-
|
|
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.
|
|
31597
|
+
const request = index.openKeyCursor(range);
|
|
31581
31598
|
request.onsuccess = () => {
|
|
31582
31599
|
const cursor = request.result;
|
|
31583
31600
|
if (cursor) {
|
|
31584
|
-
|
|
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
|
|
31652
|
-
_ChunkStorageService.DB_VERSION =
|
|
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
|
-
|
|
31872
|
-
|
|
31873
|
-
|
|
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(
|
|
31909
|
+
console.log(
|
|
31910
|
+
`[BackgroundUpload] Chunk ${meta.chunk.chunkIndex} removido do IndexedDB ap\xF3s upload.`
|
|
31911
|
+
);
|
|
31877
31912
|
}
|
|
31878
31913
|
}
|
|
31879
|
-
|
|
31880
|
-
|
|
31881
|
-
|
|
31882
|
-
|
|
31883
|
-
|
|
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
|
-
|
|
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>;
|