blob: 1d029747486400b5f2bfd11df838c0d7221bc7ae (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
/**
* Translation session management (background).
*
* Only one translation may be active at a time (SEC-14 / Design.md §9).
* Starting a new request aborts the previous one. Chunks belonging to a
* stale requestId are discarded.
*/
import { ERROR_CODES } from '../shared/constants.js';
export class TranslationSession {
constructor() {
/** @type {{requestId: string, controller: AbortController, port: object}|null} */
this.active = null;
}
/**
* @returns {boolean}
*/
hasActive() {
return this.active !== null;
}
/**
* Abort the active request, if any. Notifies its port so the UI can reset.
* @returns {void}
*/
abortActive() {
if (!this.active) return;
const { controller, port, requestId } = this.active;
this.active = null;
try {
controller.abort();
} catch {
// ignore abort errors
}
if (port) {
try {
port.postMessage({ type: 'error', requestId, code: ERROR_CODES.REQUEST_ABORTED, message: 'Superseded by a newer request' });
} catch {
// port may be gone
}
}
}
/**
* Register a new active request, aborting any previous one.
* @param {string} requestId
* @param {object} port runtime.Port owning the request
* @returns {AbortController} the controller for the new request
*/
start(requestId, port) {
this.abortActive();
const controller = new AbortController();
this.active = { requestId, controller, port };
return controller;
}
/**
* @param {string} requestId
* @returns {boolean} true when the given id is the active request.
*/
isActive(requestId) {
return this.active !== null && this.active.requestId === requestId;
}
/**
* Clear the active session when it matches the id.
* @param {string} requestId
*/
clear(requestId) {
if (this.isActive(requestId)) {
this.active = null;
}
}
}
|