easyproctor-hml 2.7.0 → 2.7.1
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 +57 -171
- package/extension/{extensionEasyProctor.d.ts → extension.d.ts} +1 -1
- package/index.js +57 -171
- package/new-flow/chunk/ChunkStorageService.d.ts +1 -1
- package/package.json +2 -2
- package/proctoring/proctoring.d.ts +0 -5
- package/proctoring/useProctoring.d.ts +0 -2
- package/unpkg/easyproctor.min.js +42 -42
- package/extension/extensionEasyCatcher.d.ts +0 -11
package/esm/index.js
CHANGED
|
@@ -13551,8 +13551,8 @@ var _ChunkStorageService = class _ChunkStorageService {
|
|
|
13551
13551
|
}
|
|
13552
13552
|
};
|
|
13553
13553
|
_ChunkStorageService.DB_NAME = "EasyProctorChunksDb";
|
|
13554
|
-
/**
|
|
13555
|
-
_ChunkStorageService.DB_VERSION =
|
|
13554
|
+
/** v2: índices numéricos; v3: payload como ArrayBuffer em vez de Blob (Safari iOS). */
|
|
13555
|
+
_ChunkStorageService.DB_VERSION = 3;
|
|
13556
13556
|
_ChunkStorageService.STORE_NAME = "chunks";
|
|
13557
13557
|
var ChunkStorageService = _ChunkStorageService;
|
|
13558
13558
|
|
|
@@ -13734,32 +13734,41 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13734
13734
|
console.log(`[BackgroundUpload] ${pendingChunks.length} chunks pendentes encontrados. Modo final: ${isFinal}`);
|
|
13735
13735
|
let virtualStart = this.totalBytesPurged;
|
|
13736
13736
|
const chunksWithMeta = allChunks.map((c3) => {
|
|
13737
|
+
const byteLen = c3.arrayBuffer.byteLength;
|
|
13737
13738
|
const start = virtualStart;
|
|
13738
|
-
const end = start +
|
|
13739
|
-
virtualStart +=
|
|
13739
|
+
const end = start + byteLen - 1;
|
|
13740
|
+
virtualStart += byteLen;
|
|
13740
13741
|
return { chunk: c3, start, end };
|
|
13741
13742
|
});
|
|
13742
|
-
|
|
13743
|
+
const sliceParts = [];
|
|
13743
13744
|
let lastProcessedChunkId = null;
|
|
13744
13745
|
let finalChunkIndex = 0;
|
|
13745
13746
|
let mimeType = pendingChunks[0].mimeType;
|
|
13746
13747
|
for (const meta of chunksWithMeta) {
|
|
13747
13748
|
if (this.currentOffset > meta.end) continue;
|
|
13748
13749
|
const sliceStart = Math.max(0, this.currentOffset - meta.start);
|
|
13749
|
-
const
|
|
13750
|
-
|
|
13750
|
+
const view = new Uint8Array(meta.chunk.arrayBuffer);
|
|
13751
|
+
sliceParts.push(view.subarray(sliceStart));
|
|
13751
13752
|
lastProcessedChunkId = meta.chunk.id;
|
|
13752
13753
|
finalChunkIndex = meta.chunk.chunkIndex;
|
|
13753
13754
|
}
|
|
13754
|
-
if (
|
|
13755
|
+
if (sliceParts.length === 0 && !isFinal) {
|
|
13755
13756
|
this.isProcessing = false;
|
|
13756
13757
|
return;
|
|
13757
13758
|
}
|
|
13758
|
-
|
|
13759
|
-
|
|
13759
|
+
const combinedLength = sliceParts.reduce((acc, p3) => acc + p3.length, 0);
|
|
13760
|
+
const combined = new Uint8Array(combinedLength);
|
|
13761
|
+
{
|
|
13762
|
+
let off = 0;
|
|
13763
|
+
for (const p3 of sliceParts) {
|
|
13764
|
+
combined.set(p3, off);
|
|
13765
|
+
off += p3.length;
|
|
13766
|
+
}
|
|
13767
|
+
}
|
|
13768
|
+
let sendableSize = combined.byteLength;
|
|
13760
13769
|
let totalSizeForHeader = void 0;
|
|
13761
13770
|
if (!isFinal) {
|
|
13762
|
-
sendableSize = Math.floor(
|
|
13771
|
+
sendableSize = Math.floor(combined.byteLength / this.GCS_CHUNK_SIZE) * this.GCS_CHUNK_SIZE;
|
|
13763
13772
|
if (sendableSize === 0) {
|
|
13764
13773
|
console.log("[BackgroundUpload] Dados insuficientes para atingir 256KB. Aguardando novo chunk...");
|
|
13765
13774
|
this.isProcessing = false;
|
|
@@ -13768,9 +13777,14 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13768
13777
|
} else {
|
|
13769
13778
|
totalSizeForHeader = virtualStart;
|
|
13770
13779
|
}
|
|
13771
|
-
const
|
|
13780
|
+
const payload = sendableSize === combined.byteLength ? combined : combined.subarray(0, sendableSize);
|
|
13772
13781
|
try {
|
|
13773
|
-
await this.uploadData(
|
|
13782
|
+
await this.uploadData(
|
|
13783
|
+
payload.byteLength > 0 ? payload : null,
|
|
13784
|
+
mimeType,
|
|
13785
|
+
finalChunkIndex,
|
|
13786
|
+
totalSizeForHeader
|
|
13787
|
+
);
|
|
13774
13788
|
for (const meta of chunksWithMeta) {
|
|
13775
13789
|
if (meta.chunk.uploaded === 0 && meta.end < this.currentOffset) {
|
|
13776
13790
|
await this.chunkStorage.markAsUploaded(meta.chunk.id);
|
|
@@ -13781,7 +13795,10 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13781
13795
|
}
|
|
13782
13796
|
if (this.config.cleanAfterUpload) {
|
|
13783
13797
|
const chunksToClear = chunksWithMeta.filter((meta) => meta.chunk.uploaded === 1 || meta.chunk.uploaded === 0 && meta.end < this.currentOffset);
|
|
13784
|
-
const sizePurged = chunksToClear.reduce(
|
|
13798
|
+
const sizePurged = chunksToClear.reduce(
|
|
13799
|
+
(acc, meta) => acc + meta.chunk.arrayBuffer.byteLength,
|
|
13800
|
+
0
|
|
13801
|
+
);
|
|
13785
13802
|
await this.chunkStorage.clearUploadedChunks(this.proctoringId);
|
|
13786
13803
|
if (sizePurged > 0) {
|
|
13787
13804
|
this.totalBytesPurged += sizePurged;
|
|
@@ -13805,7 +13822,8 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13805
13822
|
/**
|
|
13806
13823
|
* Faz o upload bruto de dados para a sessão GCS.
|
|
13807
13824
|
*/
|
|
13808
|
-
async uploadData(
|
|
13825
|
+
async uploadData(body, mimeType, chunkIndex, totalSize) {
|
|
13826
|
+
var _a2;
|
|
13809
13827
|
const fileName = `EP_${this.proctoringId}_camera_0.webm`;
|
|
13810
13828
|
if (!this.sessionUrl) {
|
|
13811
13829
|
const initiateUrl = await this.backend.initiateUpload(this.token, `${this.proctoringId}/${fileName}`, mimeType);
|
|
@@ -13836,16 +13854,28 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13836
13854
|
} else {
|
|
13837
13855
|
console.log(`[BackgroundUpload] Usando sess\xE3o GCS existente: ${this.sessionUrl}`);
|
|
13838
13856
|
}
|
|
13857
|
+
const size = (_a2 = body == null ? void 0 : body.byteLength) != null ? _a2 : 0;
|
|
13839
13858
|
const start = this.currentOffset;
|
|
13840
|
-
const end = start +
|
|
13859
|
+
const end = start + size - 1;
|
|
13841
13860
|
const totalHeader = totalSize !== void 0 ? totalSize.toString() : "*";
|
|
13842
|
-
const contentRangeHeader =
|
|
13843
|
-
console.log(
|
|
13861
|
+
const contentRangeHeader = size === 0 && totalSize !== void 0 ? `bytes */${totalHeader}` : `bytes ${start}-${end}/${totalHeader}`;
|
|
13862
|
+
console.log(
|
|
13863
|
+
`[BackgroundUpload] Enviando ${size > 0 ? "dados" : "finaliza\xE7\xE3o"}: ${contentRangeHeader} (Size: ${size})`
|
|
13864
|
+
);
|
|
13865
|
+
let uploadBody = null;
|
|
13866
|
+
if (size > 0 && body) {
|
|
13867
|
+
const raw = body.buffer;
|
|
13868
|
+
if (raw instanceof ArrayBuffer) {
|
|
13869
|
+
uploadBody = body.byteOffset === 0 && body.byteLength === raw.byteLength ? raw : raw.slice(body.byteOffset, body.byteOffset + body.byteLength);
|
|
13870
|
+
} else {
|
|
13871
|
+
uploadBody = new ArrayBuffer(body.byteLength);
|
|
13872
|
+
new Uint8Array(uploadBody).set(body);
|
|
13873
|
+
}
|
|
13874
|
+
}
|
|
13844
13875
|
const response = await fetch(this.sessionUrl, {
|
|
13845
13876
|
method: "PUT",
|
|
13846
13877
|
headers: { "Content-Range": contentRangeHeader },
|
|
13847
|
-
body:
|
|
13848
|
-
// Usa null para garantir corpo vazio se necessário
|
|
13878
|
+
body: uploadBody
|
|
13849
13879
|
});
|
|
13850
13880
|
console.log(`[BackgroundUpload] Resposta GCS (uploadData): ${response.status}`);
|
|
13851
13881
|
if (response.status !== 200 && response.status !== 201 && response.status !== 308) {
|
|
@@ -13858,13 +13888,13 @@ var BackgroundUploadService = class _BackgroundUploadService {
|
|
|
13858
13888
|
const lastByte = parseInt(rangeHeader.split("-")[1], 10);
|
|
13859
13889
|
this.currentOffset = lastByte + 1;
|
|
13860
13890
|
} else {
|
|
13861
|
-
this.currentOffset +=
|
|
13891
|
+
this.currentOffset += size;
|
|
13862
13892
|
}
|
|
13863
13893
|
this.saveSessionState();
|
|
13864
13894
|
trackers.registerUploadFile(
|
|
13865
13895
|
this.proctoringId,
|
|
13866
13896
|
`GCS Stream Upload
|
|
13867
|
-
Size: ${
|
|
13897
|
+
Size: ${size}
|
|
13868
13898
|
Range: ${start}-${end}
|
|
13869
13899
|
Last Index: ${chunkIndex}`,
|
|
13870
13900
|
"CameraChunk"
|
|
@@ -14407,10 +14437,11 @@ Setting: ${JSON.stringify(settings, null, 2)}`
|
|
|
14407
14437
|
const savePromise = (async () => {
|
|
14408
14438
|
var _a2;
|
|
14409
14439
|
try {
|
|
14440
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
14410
14441
|
await this.chunkStorage.saveChunk({
|
|
14411
14442
|
proctoringId: this.proctoringId,
|
|
14412
14443
|
chunkIndex: this.chunkIndex,
|
|
14413
|
-
|
|
14444
|
+
arrayBuffer,
|
|
14414
14445
|
timestamp: Date.now(),
|
|
14415
14446
|
uploaded: 0,
|
|
14416
14447
|
mimeType: ((_a2 = this.recorderOptions) == null ? void 0 : _a2.mimeType) || "video/webm"
|
|
@@ -16352,8 +16383,8 @@ var CapturePhoto = class {
|
|
|
16352
16383
|
}
|
|
16353
16384
|
};
|
|
16354
16385
|
|
|
16355
|
-
// src/extension/
|
|
16356
|
-
var
|
|
16386
|
+
// src/extension/extension.ts
|
|
16387
|
+
var Extension = class {
|
|
16357
16388
|
constructor() {
|
|
16358
16389
|
this.hasExtension = false;
|
|
16359
16390
|
this.tryes = 0;
|
|
@@ -16398,89 +16429,6 @@ var ExtensionEasyProctor = class {
|
|
|
16398
16429
|
}
|
|
16399
16430
|
};
|
|
16400
16431
|
|
|
16401
|
-
// src/extension/extensionEasyCatcher.ts
|
|
16402
|
-
var ExtensionEasyCatcher = class {
|
|
16403
|
-
constructor(options) {
|
|
16404
|
-
this.hasExtension = false;
|
|
16405
|
-
this.tryes = 0;
|
|
16406
|
-
this.responseStart = false;
|
|
16407
|
-
this.options = options || {};
|
|
16408
|
-
}
|
|
16409
|
-
/**
|
|
16410
|
-
* Verifica se a extensão está instalada e ativa.
|
|
16411
|
-
* Retorna o número da versão se encontrada, ou lança erro após timeout.
|
|
16412
|
-
*/
|
|
16413
|
-
checkExtensionInstalled(timeoutMs = 2e3) {
|
|
16414
|
-
return new Promise((resolve, reject) => {
|
|
16415
|
-
let handled = false;
|
|
16416
|
-
const handler = (event) => {
|
|
16417
|
-
if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "version") {
|
|
16418
|
-
handled = true;
|
|
16419
|
-
window.removeEventListener("message", handler);
|
|
16420
|
-
resolve(event.data.message);
|
|
16421
|
-
}
|
|
16422
|
-
};
|
|
16423
|
-
window.addEventListener("message", handler);
|
|
16424
|
-
window.postMessage({
|
|
16425
|
-
type: "easycatcher",
|
|
16426
|
-
func: "verifyExtensionEasycatcher"
|
|
16427
|
-
}, "*");
|
|
16428
|
-
setTimeout(() => {
|
|
16429
|
-
if (!handled) {
|
|
16430
|
-
window.removeEventListener("message", handler);
|
|
16431
|
-
reject(new Error("Extens\xE3o n\xE3o detectada ou n\xE3o respondeu."));
|
|
16432
|
-
}
|
|
16433
|
-
}, timeoutMs);
|
|
16434
|
-
});
|
|
16435
|
-
}
|
|
16436
|
-
/**
|
|
16437
|
-
* Solicita o JSON da sessão atual capturado pela extensão.
|
|
16438
|
-
*/
|
|
16439
|
-
getSessionData(timeoutMs = 5e3) {
|
|
16440
|
-
return new Promise((resolve, reject) => {
|
|
16441
|
-
let handled = false;
|
|
16442
|
-
const handler = (event) => {
|
|
16443
|
-
if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "data_response") {
|
|
16444
|
-
handled = true;
|
|
16445
|
-
window.removeEventListener("message", handler);
|
|
16446
|
-
resolve(event.data.payload);
|
|
16447
|
-
}
|
|
16448
|
-
};
|
|
16449
|
-
window.addEventListener("message", handler);
|
|
16450
|
-
window.postMessage({
|
|
16451
|
-
type: "easycatcher",
|
|
16452
|
-
func: "getDataExtensionEasycatcher"
|
|
16453
|
-
}, "*");
|
|
16454
|
-
setTimeout(() => {
|
|
16455
|
-
if (!handled) {
|
|
16456
|
-
window.removeEventListener("message", handler);
|
|
16457
|
-
reject(new Error("Timeout ao aguardar dados da extens\xE3o."));
|
|
16458
|
-
}
|
|
16459
|
-
}, timeoutMs);
|
|
16460
|
-
});
|
|
16461
|
-
}
|
|
16462
|
-
start() {
|
|
16463
|
-
return new Promise((resolve, reject) => {
|
|
16464
|
-
let handled = false;
|
|
16465
|
-
const handler = (event) => {
|
|
16466
|
-
if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "started_confirmed") {
|
|
16467
|
-
handled = true;
|
|
16468
|
-
window.removeEventListener("message", handler);
|
|
16469
|
-
resolve(true);
|
|
16470
|
-
}
|
|
16471
|
-
};
|
|
16472
|
-
window.addEventListener("message", handler);
|
|
16473
|
-
window.postMessage({ type: "easycatcher", func: "startExtensionEasycatcher" }, "*");
|
|
16474
|
-
setTimeout(() => {
|
|
16475
|
-
if (!handled) {
|
|
16476
|
-
window.removeEventListener("message", handler);
|
|
16477
|
-
reject(new Error("Timeout: Extens\xE3o n\xE3o confirmou o in\xEDcio."));
|
|
16478
|
-
}
|
|
16479
|
-
}, 3e3);
|
|
16480
|
-
});
|
|
16481
|
-
}
|
|
16482
|
-
};
|
|
16483
|
-
|
|
16484
16432
|
// src/modules/onChangeDevices.ts
|
|
16485
16433
|
var onChangeDevices = class {
|
|
16486
16434
|
constructor(repositoryDevices, proctoringId2, sessionOptions, allRecorders) {
|
|
@@ -23655,10 +23603,7 @@ var Proctoring = class {
|
|
|
23655
23603
|
if (this.context.token === void 0) {
|
|
23656
23604
|
throw TOKEN_MISSING;
|
|
23657
23605
|
}
|
|
23658
|
-
|
|
23659
|
-
this.extensionEasycatcher = new ExtensionEasyCatcher();
|
|
23660
|
-
}
|
|
23661
|
-
this.extension = new ExtensionEasyProctor();
|
|
23606
|
+
this.extension = new Extension();
|
|
23662
23607
|
this.extension.addEventListener();
|
|
23663
23608
|
const baseURL = this.backend.selectBaseUrl(this.context.type);
|
|
23664
23609
|
const devices = await enumarateDevices();
|
|
@@ -24042,61 +23987,6 @@ Error: ` + error
|
|
|
24042
23987
|
_screenStream: (_a2 = this.allRecorders.screenRecorder) == null ? void 0 : _a2.screenStream
|
|
24043
23988
|
};
|
|
24044
23989
|
}
|
|
24045
|
-
async startChallenge(templateId) {
|
|
24046
|
-
var _a2;
|
|
24047
|
-
if (!this.sessionOptions.useChallenge) {
|
|
24048
|
-
throw new Error("useChallenge is set as false on start method");
|
|
24049
|
-
}
|
|
24050
|
-
await this.extensionEasycatcher.checkExtensionInstalled().catch((err) => {
|
|
24051
|
-
throw new Error("EasyCatcher Extension is not installed");
|
|
24052
|
-
});
|
|
24053
|
-
this.extensionEasycatcher.start();
|
|
24054
|
-
const start = Date.now() - ((_a2 = this.allRecorders.cameraRecorder.getStartTime()) == null ? void 0 : _a2.getTime()) || 0;
|
|
24055
|
-
await this.backend.startChallenge({
|
|
24056
|
-
proctoringId: this.proctoringId,
|
|
24057
|
-
templateId,
|
|
24058
|
-
start
|
|
24059
|
-
}).then((resp) => {
|
|
24060
|
-
console.log(resp);
|
|
24061
|
-
this.challengeId = resp.id;
|
|
24062
|
-
}).catch((reason) => {
|
|
24063
|
-
trackers.registerError(
|
|
24064
|
-
this.proctoringId,
|
|
24065
|
-
"N\xE3o foi poss\xEDvel iniciar desafio!"
|
|
24066
|
-
);
|
|
24067
|
-
throw reason;
|
|
24068
|
-
});
|
|
24069
|
-
this.isChallengeRunning = true;
|
|
24070
|
-
}
|
|
24071
|
-
async stopChallenge() {
|
|
24072
|
-
var _a2;
|
|
24073
|
-
if (!this.isChallengeRunning) {
|
|
24074
|
-
throw new Error("Challenge not started");
|
|
24075
|
-
}
|
|
24076
|
-
try {
|
|
24077
|
-
const sessionData = await this.extensionEasycatcher.getSessionData();
|
|
24078
|
-
const end = Date.now() - ((_a2 = this.allRecorders.cameraRecorder.getStartTime()) == null ? void 0 : _a2.getTime()) || 0;
|
|
24079
|
-
await this.backend.stopChallenge(
|
|
24080
|
-
this.challengeId,
|
|
24081
|
-
{
|
|
24082
|
-
end,
|
|
24083
|
-
data: sessionData
|
|
24084
|
-
}
|
|
24085
|
-
).catch((reason) => {
|
|
24086
|
-
trackers.registerError(
|
|
24087
|
-
this.proctoringId,
|
|
24088
|
-
"N\xE3o foi poss\xEDvel finalizar o desafio no backend!"
|
|
24089
|
-
);
|
|
24090
|
-
return void 0;
|
|
24091
|
-
});
|
|
24092
|
-
this.isChallengeRunning = false;
|
|
24093
|
-
} catch (error) {
|
|
24094
|
-
trackers.registerError(
|
|
24095
|
-
this.proctoringId,
|
|
24096
|
-
"Erro ao recuperar dados da extens\xE3o: " + error.message
|
|
24097
|
-
);
|
|
24098
|
-
}
|
|
24099
|
-
}
|
|
24100
23990
|
};
|
|
24101
23991
|
|
|
24102
23992
|
// src/proctoring/SignTerm.ts
|
|
@@ -24325,8 +24215,6 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
24325
24215
|
return originalStart(parameters2, videoOptions);
|
|
24326
24216
|
};
|
|
24327
24217
|
const finish = proctoring.finish.bind(proctoring);
|
|
24328
|
-
const startChallenge = proctoring.startChallenge.bind(proctoring);
|
|
24329
|
-
const stopChallenge = proctoring.stopChallenge.bind(proctoring);
|
|
24330
24218
|
const pause = proctoring.pause.bind(proctoring);
|
|
24331
24219
|
const resume = proctoring.resume.bind(proctoring);
|
|
24332
24220
|
const onFocus = proctoring.setOnFocusCallback.bind(proctoring);
|
|
@@ -24351,8 +24239,6 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
|
|
|
24351
24239
|
login,
|
|
24352
24240
|
start,
|
|
24353
24241
|
finish,
|
|
24354
|
-
startChallenge,
|
|
24355
|
-
stopChallenge,
|
|
24356
24242
|
onFocus,
|
|
24357
24243
|
onLostFocus,
|
|
24358
24244
|
onChangeDevices: onChangeDevices2,
|