@push.rocks/smartbrowser 4.1.0 → 4.3.0

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.
@@ -0,0 +1,1830 @@
1
+ import { LiveBrowserVideoReceiver } from './classes.livebrowservideoreceiver.js';
2
+ const maxInputQueueLength = 128;
3
+ const maxInFlightInputCommands = 4;
4
+ const maxQueuedCoalescableCommands = 32;
5
+ const maxWheelDelta = 1000000;
6
+ const animationFrameFallbackMs = 16;
7
+ const resizeDebounceMs = 100;
8
+ const maxPendingAcknowledgements = 16;
9
+ const maxInputReleaseAttempts = 2;
10
+ const maxFrameDimension = 12288;
11
+ const maxFramePixelArea = 8294400;
12
+ const maxFrameByteLength = (maxFramePixelArea * 4) + 1048576;
13
+ const maxViewportWidth = 4096;
14
+ const maxViewportHeight = 4096;
15
+ const minDeviceScaleFactor = 0.25;
16
+ const maxDeviceScaleFactor = 3;
17
+ const coordinateEdgeInset = 0.001;
18
+ const defaultOperationTimeoutMs = 10000;
19
+ class LiveBrowserOperationTimeoutError extends Error {
20
+ }
21
+ class LiveBrowserRunAbortedError extends Error {
22
+ }
23
+ class LiveBrowserFrameProtocolError extends Error {
24
+ }
25
+ class LiveBrowserFrameIntegrityError extends Error {
26
+ }
27
+ const isCoalescableInputCommand = (kindArg) => kindArg === 'mouseMove' || kindArg === 'wheel';
28
+ const clampWheelDelta = (valueArg) => (Math.max(-maxWheelDelta, Math.min(maxWheelDelta, valueArg)));
29
+ const mergeWheelInput = (targetArg, sourceArg) => {
30
+ targetArg.x = sourceArg.x;
31
+ targetArg.y = sourceArg.y;
32
+ targetArg.deltaX = clampWheelDelta(targetArg.deltaX + sourceArg.deltaX);
33
+ targetArg.deltaY = clampWheelDelta(targetArg.deltaY + sourceArg.deltaY);
34
+ targetArg.modifiers = sourceArg.modifiers;
35
+ };
36
+ const inputIdentityEquals = (firstArg, secondArg) => (firstArg.tabId === secondArg.tabId
37
+ && firstArg.generation === secondArg.generation
38
+ && firstArg.viewportRevision === secondArg.viewportRevision);
39
+ const viewportEquals = (firstArg, secondArg) => (firstArg.width === secondArg.width
40
+ && firstArg.height === secondArg.height
41
+ && firstArg.deviceScaleFactor === secondArg.deviceScaleFactor);
42
+ const createModifiers = (eventArg) => ({
43
+ alt: eventArg.altKey,
44
+ control: eventArg.ctrlKey,
45
+ meta: eventArg.metaKey,
46
+ shift: eventArg.shiftKey,
47
+ });
48
+ const createFrameAcknowledgementRequest = (frameArg) => ({
49
+ tabId: frameArg.tabId,
50
+ sequence: frameArg.sequence,
51
+ generation: frameArg.generation,
52
+ viewportRevision: frameArg.viewportRevision,
53
+ });
54
+ const createInputIdentity = (displayedFrameArg) => ({
55
+ tabId: displayedFrameArg.tabId,
56
+ generation: displayedFrameArg.generation,
57
+ viewportRevision: displayedFrameArg.viewportRevision,
58
+ });
59
+ const getErrorMessage = (errorArg) => (errorArg instanceof Error ? errorArg.message : String(errorArg));
60
+ /**
61
+ * Renders transport-neutral live browser frames and maps DOM input back to the
62
+ * currently displayed SmartPuppeteer frame identity.
63
+ */
64
+ export class LiveBrowserRenderer {
65
+ constructor(optionsArg) {
66
+ this.lifecycleTail = Promise.resolve();
67
+ this.runEpoch = 0;
68
+ this.running = false;
69
+ this.suspended = false;
70
+ this.stopping = false;
71
+ this.interruptionRequested = false;
72
+ this.operationControllers = new Set();
73
+ this.acceptingFrames = false;
74
+ this.focusWasAdjusted = false;
75
+ this.focusHadTabIndex = false;
76
+ this.focusTabIndexValue = null;
77
+ this.highestFrameSequence = -1;
78
+ this.acknowledgementPromises = new Set();
79
+ this.rawDecodeSettlementPromises = new Set();
80
+ this.inputBlocked = true;
81
+ this.inputCommands = [];
82
+ this.inFlightInputCommands = 0;
83
+ this.inFlightWheelCommands = 0;
84
+ this.inputIdleResolvers = [];
85
+ this.inputResetTail = Promise.resolve();
86
+ this.inputResetCount = 0;
87
+ this.wheelFrameElapsed = true;
88
+ this.pressedKeys = new Map();
89
+ this.pressedMouseButtons = new Map();
90
+ this.capturedPointerIds = new Set();
91
+ this.viewportProcessing = false;
92
+ this.statistics = {
93
+ framesReceived: 0,
94
+ framesDecoded: 0,
95
+ framesSkipped: 0,
96
+ inputCommandsEnqueued: 0,
97
+ inputCommandsCoalesced: 0,
98
+ lastInputRoundTripMs: 0,
99
+ };
100
+ this.canvas = 'video' in optionsArg ? optionsArg.video : optionsArg.canvas;
101
+ this.client = optionsArg.client;
102
+ this.focusTarget = optionsArg.focusTarget ?? this.canvas;
103
+ this.resizeTarget = optionsArg.resizeTarget;
104
+ this.getDeviceScaleFactor = optionsArg.getDeviceScaleFactor
105
+ ?? (() => window.devicePixelRatio || 1);
106
+ this.operationTimeoutMs = this.validateTimeout(optionsArg.operationTimeoutMs ?? defaultOperationTimeoutMs, 'operationTimeoutMs');
107
+ this.frameDecodeTimeoutMs = this.validateTimeout(('frameDecodeTimeoutMs' in optionsArg ? optionsArg.frameDecodeTimeoutMs : undefined) ?? this.operationTimeoutMs, 'frameDecodeTimeoutMs');
108
+ this.onError = optionsArg.onError;
109
+ this.onFrameRendered = 'onFrameRendered' in optionsArg ? optionsArg.onFrameRendered : undefined;
110
+ this.initialCanvasWidth = this.canvas.width;
111
+ this.initialCanvasHeight = this.canvas.height;
112
+ if ('video' in optionsArg) {
113
+ this.videoReceiver = new LiveBrowserVideoReceiver({
114
+ video: optionsArg.video, client: optionsArg.client, operationTimeoutMs: this.operationTimeoutMs,
115
+ onUnavailable: () => {
116
+ this.displayedFrame = undefined;
117
+ this.inputBlocked = true;
118
+ if (this.running)
119
+ void this.scheduleInputReset(false, this.runEpoch);
120
+ },
121
+ onPresented: (sourceArg) => this.presentVideo(sourceArg),
122
+ onError: (errorArg) => this.reportError(errorArg, this.runEpoch),
123
+ });
124
+ return;
125
+ }
126
+ const bitmapContext = optionsArg.canvas.getContext('bitmaprenderer');
127
+ if (bitmapContext) {
128
+ this.bitmapContext = bitmapContext;
129
+ }
130
+ else {
131
+ // A canvas that already owns a 2D context keeps the 2D drawing path.
132
+ const canvasContext = optionsArg.canvas.getContext('2d');
133
+ if (!canvasContext) {
134
+ throw new Error('LiveBrowserCanvasRenderer requires a bitmaprenderer or 2D canvas context');
135
+ }
136
+ this.canvasContext = canvasContext;
137
+ }
138
+ }
139
+ get isRunning() {
140
+ return this.running;
141
+ }
142
+ get isSuspended() {
143
+ return this.suspended;
144
+ }
145
+ /**
146
+ * Cumulative frame and input counters for this renderer instance across runs.
147
+ */
148
+ getStatistics() {
149
+ return {
150
+ ...this.statistics,
151
+ ...this.videoReceiver?.getCounters(),
152
+ ...(this.videoReceiver ? { video: this.videoReceiver.getStatistics() } : {}),
153
+ inputCommandsInFlight: this.inFlightInputCommands,
154
+ };
155
+ }
156
+ start() {
157
+ return this.enqueueLifecycle(async () => {
158
+ if (this.running) {
159
+ return;
160
+ }
161
+ if (this.suspended) {
162
+ throw new Error('Live browser renderer is suspended; call resume() to start a fresh run');
163
+ }
164
+ await this.startRun(false);
165
+ });
166
+ }
167
+ stop() {
168
+ this.interruptRun(this.runEpoch);
169
+ return this.enqueueLifecycle(async () => {
170
+ const runEpoch = this.runEpoch;
171
+ this.interruptRun(runEpoch);
172
+ if (this.stopping) {
173
+ await this.finishRun(runEpoch, false);
174
+ return;
175
+ }
176
+ if (!this.suspended) {
177
+ return;
178
+ }
179
+ this.suspended = false;
180
+ this.restoreCanvasAndFocus();
181
+ });
182
+ }
183
+ /**
184
+ * Aborts the current transport generation without replaying input recovery.
185
+ */
186
+ suspend() {
187
+ this.interruptRun(this.runEpoch);
188
+ return this.enqueueLifecycle(async () => {
189
+ const runEpoch = this.runEpoch;
190
+ this.interruptRun(runEpoch);
191
+ if (!this.stopping) {
192
+ return;
193
+ }
194
+ await this.finishRun(runEpoch, true);
195
+ });
196
+ }
197
+ /**
198
+ * Starts a new transport generation that requires new state and a new frame.
199
+ */
200
+ resume() {
201
+ return this.enqueueLifecycle(async () => {
202
+ if (this.running) {
203
+ return;
204
+ }
205
+ if (!this.suspended) {
206
+ throw new Error('Live browser renderer is not suspended');
207
+ }
208
+ await this.startRun(true);
209
+ });
210
+ }
211
+ /**
212
+ * Sends arbitrary committed text, including text produced by an external IME.
213
+ */
214
+ async insertText(textArg) {
215
+ const displayedFrame = this.requireInputFrame();
216
+ const inputIdentity = createInputIdentity(displayedFrame);
217
+ await this.enqueueInputCommand({
218
+ kind: 'text',
219
+ runEpoch: this.runEpoch,
220
+ execute: async (optionsArg) => {
221
+ await this.client.insertText({
222
+ ...inputIdentity,
223
+ text: textArg,
224
+ }, optionsArg);
225
+ },
226
+ });
227
+ }
228
+ /**
229
+ * Reads the configured stable resize target and requests the corresponding
230
+ * remote CSS viewport. Intrinsic canvas dimensions are never used here.
231
+ */
232
+ syncViewport() {
233
+ if (!this.running || this.stopping || this.interruptionRequested || !this.resizeTarget) {
234
+ return;
235
+ }
236
+ this.queueViewport(this.resizeTarget.clientWidth, this.resizeTarget.clientHeight, this.runEpoch);
237
+ }
238
+ enqueueLifecycle(operationArg) {
239
+ const operation = this.lifecycleTail.then(operationArg, operationArg);
240
+ this.lifecycleTail = operation.then(() => undefined, () => undefined);
241
+ return operation;
242
+ }
243
+ async startRun(resumingArg) {
244
+ await Promise.all([...this.rawDecodeSettlementPromises]);
245
+ const runEpoch = ++this.runEpoch;
246
+ this.runController = new AbortController();
247
+ this.running = true;
248
+ this.suspended = false;
249
+ this.stopping = false;
250
+ this.interruptionRequested = false;
251
+ this.acceptingFrames = true;
252
+ this.inputBlocked = true;
253
+ this.wheelFrameElapsed = true;
254
+ this.state = undefined;
255
+ this.displayedFrame = undefined;
256
+ this.highestFrameSequence = -1;
257
+ this.clearCanvas();
258
+ try {
259
+ this.makeFocusTargetFocusable();
260
+ this.installDomListeners(runEpoch);
261
+ this.unsubscribe = this.client.onEvent((eventArg) => {
262
+ this.handleEvent(eventArg, runEpoch);
263
+ });
264
+ this.applyState(this.client.getState(), runEpoch);
265
+ this.installResizeObserver(runEpoch);
266
+ }
267
+ catch (error) {
268
+ this.interruptRun(runEpoch);
269
+ await this.finishRun(runEpoch, resumingArg);
270
+ throw error;
271
+ }
272
+ }
273
+ interruptRun(runEpochArg) {
274
+ if (runEpochArg !== this.runEpoch
275
+ || (!this.running && !this.stopping)) {
276
+ return;
277
+ }
278
+ this.running = false;
279
+ this.stopping = true;
280
+ this.interruptionRequested = true;
281
+ this.acceptingFrames = false;
282
+ this.inputBlocked = true;
283
+ this.pendingViewport = undefined;
284
+ this.queuedFrame = undefined;
285
+ this.displayedFrame = undefined;
286
+ this.resizeFence = undefined;
287
+ this.discardPendingDraw();
288
+ this.discardPendingWheel();
289
+ this.releasePointerCaptures();
290
+ this.clearCanvas();
291
+ this.videoReceiver?.interrupt();
292
+ const interruptionError = new LiveBrowserRunAbortedError(`Live browser renderer run ${runEpochArg} was interrupted`);
293
+ this.runController?.abort(interruptionError);
294
+ for (const controller of this.operationControllers) {
295
+ controller.abort(interruptionError);
296
+ }
297
+ const abandonedCommands = this.inputCommands.splice(0);
298
+ for (const command of abandonedCommands) {
299
+ command.reject(interruptionError);
300
+ }
301
+ this.pressedKeys.clear();
302
+ this.pressedMouseButtons.clear();
303
+ }
304
+ async finishRun(runEpochArg, suspendArg) {
305
+ if (runEpochArg !== this.runEpoch) {
306
+ return;
307
+ }
308
+ try {
309
+ this.resizeObserver?.disconnect();
310
+ this.resizeObserver = undefined;
311
+ this.clearResizeDebounce();
312
+ this.listenerController?.abort();
313
+ this.listenerController = undefined;
314
+ const unsubscribe = this.unsubscribe;
315
+ this.unsubscribe = undefined;
316
+ if (unsubscribe) {
317
+ try {
318
+ unsubscribe();
319
+ }
320
+ catch (error) {
321
+ this.reportError({
322
+ code: 'renderer_cleanup_failed',
323
+ message: `Could not unsubscribe the live browser renderer: ${getErrorMessage(error)}`,
324
+ cause: error,
325
+ }, runEpochArg);
326
+ }
327
+ }
328
+ await Promise.allSettled([
329
+ this.videoReceiver?.stop(),
330
+ this.viewportProcessingPromise,
331
+ this.inputResetTail,
332
+ this.waitForInputIdle(),
333
+ this.frameProcessingPromise,
334
+ ...this.acknowledgementPromises,
335
+ ]);
336
+ }
337
+ finally {
338
+ for (const controller of this.operationControllers) {
339
+ controller.abort(new LiveBrowserRunAbortedError(`Live browser renderer run ${runEpochArg} finished`));
340
+ }
341
+ this.operationControllers.clear();
342
+ this.runController = undefined;
343
+ this.running = false;
344
+ this.suspended = suspendArg;
345
+ this.acceptingFrames = false;
346
+ this.state = undefined;
347
+ this.displayedFrame = undefined;
348
+ this.highestFrameSequence = -1;
349
+ this.queuedFrame = undefined;
350
+ this.frameProcessingPromise = undefined;
351
+ this.discardPendingDraw();
352
+ this.discardPendingWheel();
353
+ this.clearResizeDebounce();
354
+ this.acknowledgementPromises.clear();
355
+ this.resizeFence = undefined;
356
+ this.lastRequestedViewport = undefined;
357
+ this.pendingViewport = undefined;
358
+ this.inFlightViewport = undefined;
359
+ this.viewportProcessing = false;
360
+ this.viewportProcessingPromise = undefined;
361
+ this.inputResetPromise = undefined;
362
+ this.inputResetTail = Promise.resolve();
363
+ this.inputResetCount = 0;
364
+ this.inputBlocked = true;
365
+ this.pressedKeys.clear();
366
+ this.pressedMouseButtons.clear();
367
+ this.releasePointerCaptures();
368
+ const abandonedCommands = this.inputCommands.splice(0);
369
+ for (const command of abandonedCommands) {
370
+ command.reject(new Error('Live browser renderer stopped before dispatching input'));
371
+ }
372
+ const inputIdleResolvers = this.inputIdleResolvers;
373
+ this.inputIdleResolvers = [];
374
+ for (const resolver of inputIdleResolvers) {
375
+ resolver();
376
+ }
377
+ this.restoreCanvasAndFocus();
378
+ this.interruptionRequested = false;
379
+ this.stopping = false;
380
+ }
381
+ }
382
+ restoreCanvasAndFocus() {
383
+ this.canvas.width = this.initialCanvasWidth;
384
+ this.canvas.height = this.initialCanvasHeight;
385
+ this.restoreFocusTarget();
386
+ }
387
+ installDomListeners(runEpochArg) {
388
+ const listenerController = new AbortController();
389
+ const signal = listenerController.signal;
390
+ this.listenerController = listenerController;
391
+ this.canvas.addEventListener('pointerdown', (eventArg) => {
392
+ this.handlePointerDown(eventArg, runEpochArg);
393
+ }, { signal });
394
+ this.canvas.addEventListener('pointermove', (eventArg) => {
395
+ this.handlePointerMove(eventArg, runEpochArg);
396
+ }, { signal });
397
+ this.canvas.addEventListener('pointerup', (eventArg) => {
398
+ this.handlePointerUp(eventArg, runEpochArg);
399
+ }, { signal });
400
+ this.canvas.addEventListener('pointercancel', (eventArg) => {
401
+ this.releasePointerCapture(eventArg.pointerId);
402
+ void this.scheduleInputReset(false, runEpochArg);
403
+ }, { signal });
404
+ this.canvas.addEventListener('lostpointercapture', (eventArg) => {
405
+ this.capturedPointerIds.delete(eventArg.pointerId);
406
+ if (this.pressedMouseButtons.size > 0) {
407
+ void this.scheduleInputReset(false, runEpochArg);
408
+ }
409
+ }, { signal });
410
+ this.canvas.addEventListener('contextmenu', (eventArg) => {
411
+ eventArg.preventDefault();
412
+ }, { signal });
413
+ this.canvas.addEventListener('wheel', (eventArg) => {
414
+ this.handleWheel(eventArg, runEpochArg);
415
+ }, { passive: false, signal });
416
+ this.focusTarget.addEventListener('keydown', (eventArg) => {
417
+ this.handleKey(eventArg, 'down', runEpochArg);
418
+ }, { signal });
419
+ this.focusTarget.addEventListener('keyup', (eventArg) => {
420
+ this.handleKey(eventArg, 'up', runEpochArg);
421
+ }, { signal });
422
+ this.focusTarget.addEventListener('compositionend', (eventArg) => {
423
+ if (!this.inputBlocked && eventArg.data) {
424
+ void this.insertText(eventArg.data).catch(() => undefined);
425
+ }
426
+ }, { signal });
427
+ window.addEventListener('blur', () => {
428
+ void this.scheduleInputReset(false, runEpochArg);
429
+ }, { signal });
430
+ window.addEventListener('resize', () => {
431
+ this.syncViewport();
432
+ }, { signal });
433
+ document.addEventListener('visibilitychange', () => {
434
+ if (this.state && this.running)
435
+ this.videoReceiver?.update(this.state);
436
+ if (document.visibilityState === 'hidden') {
437
+ void this.scheduleInputReset(false, runEpochArg);
438
+ }
439
+ }, { signal });
440
+ }
441
+ installResizeObserver(runEpochArg) {
442
+ if (!this.resizeTarget) {
443
+ return;
444
+ }
445
+ this.resizeObserver = new ResizeObserver((entriesArg) => {
446
+ const matchingEntry = entriesArg.find((entryArg) => entryArg.target === this.resizeTarget);
447
+ if (!matchingEntry || runEpochArg !== this.runEpoch) {
448
+ return;
449
+ }
450
+ this.pendingResizeSize = {
451
+ width: matchingEntry.contentRect.width,
452
+ height: matchingEntry.contentRect.height,
453
+ };
454
+ if (this.resizeDebounceTimer !== undefined) {
455
+ globalThis.clearTimeout(this.resizeDebounceTimer);
456
+ }
457
+ this.resizeDebounceTimer = globalThis.setTimeout(() => {
458
+ this.resizeDebounceTimer = undefined;
459
+ const pendingResizeSize = this.pendingResizeSize;
460
+ this.pendingResizeSize = undefined;
461
+ if (pendingResizeSize) {
462
+ this.queueViewport(pendingResizeSize.width, pendingResizeSize.height, runEpochArg);
463
+ }
464
+ }, resizeDebounceMs);
465
+ });
466
+ this.resizeObserver.observe(this.resizeTarget);
467
+ this.syncViewport();
468
+ }
469
+ clearResizeDebounce() {
470
+ if (this.resizeDebounceTimer !== undefined) {
471
+ globalThis.clearTimeout(this.resizeDebounceTimer);
472
+ this.resizeDebounceTimer = undefined;
473
+ }
474
+ this.pendingResizeSize = undefined;
475
+ }
476
+ handleEvent(eventArg, runEpochArg) {
477
+ if (eventArg.type === 'frame') {
478
+ if (this.videoReceiver)
479
+ return;
480
+ this.queueFrame(eventArg.frame, runEpochArg);
481
+ return;
482
+ }
483
+ if (!this.running || runEpochArg !== this.runEpoch) {
484
+ return;
485
+ }
486
+ if (eventArg.type === 'state') {
487
+ this.applyState(eventArg.state, runEpochArg);
488
+ return;
489
+ }
490
+ this.reportError({
491
+ code: 'remote_browser_error',
492
+ message: `${eventArg.error.code}: ${eventArg.error.message}`,
493
+ cause: eventArg.error,
494
+ }, runEpochArg);
495
+ }
496
+ applyState(stateArg, runEpochArg) {
497
+ if (!this.running || runEpochArg !== this.runEpoch) {
498
+ return;
499
+ }
500
+ this.state = stateArg;
501
+ this.followNegotiatedViewport();
502
+ this.videoReceiver?.update(stateArg);
503
+ if (this.displayedFrame && this.isStateAheadOfDisplayedFrame(stateArg, this.displayedFrame)) {
504
+ this.displayedFrame = undefined;
505
+ this.clearCanvas();
506
+ void this.scheduleInputReset(false, runEpochArg);
507
+ return;
508
+ }
509
+ this.updateInputAvailability();
510
+ }
511
+ presentVideo(sourceArg) {
512
+ if (!this.running || !this.state)
513
+ return;
514
+ const tab = this.state.tabs.find((tabArg) => tabArg.id === sourceArg.tabId);
515
+ if (this.state.status !== 'running' || this.state.activeTabId !== sourceArg.tabId
516
+ || this.state.viewportRevision !== sourceArg.viewportRevision || !tab?.streaming
517
+ || tab.status !== 'open' || tab.generation !== sourceArg.generation)
518
+ return;
519
+ this.displayedFrame = { ...sourceArg, viewport: { ...sourceArg.viewport }, sequence: 0 };
520
+ this.updateInputAvailability();
521
+ }
522
+ isStateAheadOfDisplayedFrame(stateArg, displayedFrameArg) {
523
+ if (stateArg.status !== 'running' || stateArg.activeTabId !== displayedFrameArg.tabId) {
524
+ return true;
525
+ }
526
+ const activeTab = stateArg.tabs.find((tabArg) => tabArg.id === displayedFrameArg.tabId);
527
+ if (!activeTab || activeTab.status !== 'open' || !activeTab.streaming) {
528
+ return true;
529
+ }
530
+ return stateArg.viewportRevision > displayedFrameArg.viewportRevision
531
+ || activeTab.generation > displayedFrameArg.generation;
532
+ }
533
+ queueFrame(frameArg, runEpochArg) {
534
+ if (!this.running || !this.acceptingFrames || runEpochArg !== this.runEpoch) {
535
+ return;
536
+ }
537
+ this.statistics.framesReceived++;
538
+ try {
539
+ this.validateFrame(frameArg);
540
+ if (frameArg.sequence <= this.highestFrameSequence) {
541
+ throw new LiveBrowserFrameProtocolError(`frame.sequence ${frameArg.sequence} must be strictly greater than current run high-water ${this.highestFrameSequence}`);
542
+ }
543
+ }
544
+ catch (error) {
545
+ this.requestSuspend(runEpochArg);
546
+ this.reportError({
547
+ code: 'frame_render_failed',
548
+ message: `Rejected invalid live browser frame: ${getErrorMessage(error)}`,
549
+ cause: error,
550
+ frame: frameArg,
551
+ }, runEpochArg);
552
+ return;
553
+ }
554
+ this.highestFrameSequence = frameArg.sequence;
555
+ const frameWork = {
556
+ frame: frameArg,
557
+ runEpoch: runEpochArg,
558
+ acknowledgementAttempted: false,
559
+ };
560
+ if (this.queuedFrame) {
561
+ // The superseded frame was already acknowledged at receipt.
562
+ this.queuedFrame = undefined;
563
+ this.statistics.framesSkipped++;
564
+ }
565
+ this.queuedFrame = frameWork;
566
+ void this.acknowledgeFrame(frameWork);
567
+ this.ensureFrameProcessor();
568
+ }
569
+ ensureFrameProcessor() {
570
+ if (this.frameProcessingPromise || !this.queuedFrame) {
571
+ return;
572
+ }
573
+ const processingPromise = this.processFrameQueue().finally(() => {
574
+ if (this.frameProcessingPromise === processingPromise) {
575
+ this.frameProcessingPromise = undefined;
576
+ if (this.queuedFrame) {
577
+ this.ensureFrameProcessor();
578
+ }
579
+ }
580
+ });
581
+ this.frameProcessingPromise = processingPromise;
582
+ }
583
+ async processFrameQueue() {
584
+ while (this.queuedFrame) {
585
+ const frameWork = this.queuedFrame;
586
+ this.queuedFrame = undefined;
587
+ await this.processFrame(frameWork);
588
+ }
589
+ }
590
+ async processFrame(frameWorkArg) {
591
+ const { frame, runEpoch } = frameWorkArg;
592
+ let imageBitmap;
593
+ let terminalFailure = false;
594
+ let terminalError;
595
+ try {
596
+ if (!this.canRenderFrame(frame, runEpoch)) {
597
+ return;
598
+ }
599
+ const frameBytes = new Uint8Array(frame.data.byteLength);
600
+ frameBytes.set(frame.data);
601
+ imageBitmap = await this.decodeFrame(new Blob([frameBytes.buffer], {
602
+ type: frame.mimeType,
603
+ }), runEpoch);
604
+ if (imageBitmap.width !== frame.width || imageBitmap.height !== frame.height) {
605
+ throw new LiveBrowserFrameIntegrityError(`decoded frame dimensions ${imageBitmap.width}x${imageBitmap.height} do not match ${frame.width}x${frame.height}`);
606
+ }
607
+ this.statistics.framesDecoded++;
608
+ if (!this.canRenderFrame(frame, runEpoch)) {
609
+ this.statistics.framesSkipped++;
610
+ return;
611
+ }
612
+ this.setPendingDraw({ bitmap: imageBitmap, frame, runEpoch });
613
+ imageBitmap = undefined;
614
+ }
615
+ catch (error) {
616
+ if (error instanceof LiveBrowserRunAbortedError) {
617
+ return;
618
+ }
619
+ terminalFailure = true;
620
+ terminalError = error;
621
+ }
622
+ finally {
623
+ imageBitmap?.close();
624
+ if (terminalFailure) {
625
+ this.requestSuspend(runEpoch);
626
+ this.reportError({
627
+ code: 'frame_render_failed',
628
+ message: `Could not render live browser frame: ${getErrorMessage(terminalError)}`,
629
+ cause: terminalError,
630
+ frame,
631
+ }, runEpoch);
632
+ }
633
+ }
634
+ }
635
+ /**
636
+ * Keeps only the newest decoded bitmap and presents it on the next animation frame.
637
+ */
638
+ setPendingDraw(pendingDrawArg) {
639
+ if (this.pendingDraw) {
640
+ this.pendingDraw.bitmap.close();
641
+ this.statistics.framesSkipped++;
642
+ }
643
+ this.pendingDraw = pendingDrawArg;
644
+ if (!this.drawSchedule) {
645
+ this.drawSchedule = this.scheduleAnimationFrame(() => {
646
+ this.drawSchedule = undefined;
647
+ this.drawPendingFrame();
648
+ });
649
+ }
650
+ }
651
+ discardPendingDraw() {
652
+ if (this.drawSchedule) {
653
+ this.cancelScheduledFrame(this.drawSchedule);
654
+ this.drawSchedule = undefined;
655
+ }
656
+ const pendingDraw = this.pendingDraw;
657
+ this.pendingDraw = undefined;
658
+ if (pendingDraw) {
659
+ pendingDraw.bitmap.close();
660
+ this.statistics.framesSkipped++;
661
+ }
662
+ }
663
+ drawPendingFrame() {
664
+ const pendingDraw = this.pendingDraw;
665
+ this.pendingDraw = undefined;
666
+ if (!pendingDraw) {
667
+ return;
668
+ }
669
+ const { bitmap, frame, runEpoch } = pendingDraw;
670
+ if (!this.canRenderFrame(frame, runEpoch)) {
671
+ bitmap.close();
672
+ this.statistics.framesSkipped++;
673
+ return;
674
+ }
675
+ try {
676
+ this.paintBitmap(bitmap, frame.width, frame.height);
677
+ }
678
+ catch (error) {
679
+ bitmap.close();
680
+ this.requestSuspend(runEpoch);
681
+ this.reportError({
682
+ code: 'frame_render_failed',
683
+ message: `Could not render live browser frame: ${getErrorMessage(error)}`,
684
+ cause: error,
685
+ frame,
686
+ }, runEpoch);
687
+ return;
688
+ }
689
+ this.displayedFrame = {
690
+ tabId: frame.tabId,
691
+ sequence: frame.sequence,
692
+ generation: frame.generation,
693
+ viewportRevision: frame.viewportRevision,
694
+ viewport: { ...frame.viewport },
695
+ };
696
+ if (this.resizeFence
697
+ && !this.viewportProcessing
698
+ && frame.viewportRevision >= this.resizeFence.minimumViewportRevision
699
+ && viewportEquals(frame.viewport, this.resizeFence.target)) {
700
+ this.resizeFence = undefined;
701
+ }
702
+ this.updateInputAvailability();
703
+ this.callFrameRendered(frame, runEpoch);
704
+ }
705
+ /**
706
+ * Presents one decoded bitmap. The canvas backing store is reallocated only
707
+ * when the frame dimensions differ from the current intrinsic dimensions.
708
+ */
709
+ paintBitmap(bitmapArg, widthArg, heightArg) {
710
+ if (this.canvas.width !== widthArg) {
711
+ this.canvas.width = widthArg;
712
+ }
713
+ if (this.canvas.height !== heightArg) {
714
+ this.canvas.height = heightArg;
715
+ }
716
+ if (this.bitmapContext) {
717
+ this.bitmapContext.transferFromImageBitmap(bitmapArg);
718
+ return;
719
+ }
720
+ if (!this.canvasContext) {
721
+ throw new Error('LiveBrowserCanvasRenderer has no rendering context');
722
+ }
723
+ this.canvasContext.clearRect(0, 0, widthArg, heightArg);
724
+ this.canvasContext.drawImage(bitmapArg, 0, 0, widthArg, heightArg);
725
+ bitmapArg.close();
726
+ }
727
+ canRenderFrame(frameArg, runEpochArg) {
728
+ if (!this.running
729
+ || !this.acceptingFrames
730
+ || runEpochArg !== this.runEpoch) {
731
+ return false;
732
+ }
733
+ const state = this.state;
734
+ if (!state || state.status !== 'running' || state.activeTabId !== frameArg.tabId) {
735
+ return false;
736
+ }
737
+ const activeTab = state.tabs.find((tabArg) => tabArg.id === frameArg.tabId);
738
+ if (!activeTab || activeTab.status !== 'open' || !activeTab.streaming) {
739
+ return false;
740
+ }
741
+ if (state.viewportRevision > frameArg.viewportRevision
742
+ || activeTab.generation > frameArg.generation) {
743
+ return false;
744
+ }
745
+ if (this.resizeFence && !this.viewportProcessing) {
746
+ return frameArg.viewportRevision >= this.resizeFence.minimumViewportRevision
747
+ && viewportEquals(frameArg.viewport, this.resizeFence.target);
748
+ }
749
+ return true;
750
+ }
751
+ acknowledgeFrame(frameWorkArg) {
752
+ if (frameWorkArg.acknowledgementAttempted) {
753
+ return Promise.resolve();
754
+ }
755
+ frameWorkArg.acknowledgementAttempted = true;
756
+ if (!this.isRunActive(frameWorkArg.runEpoch)) {
757
+ return Promise.resolve();
758
+ }
759
+ if (this.acknowledgementPromises.size >= maxPendingAcknowledgements) {
760
+ this.requestSuspend(frameWorkArg.runEpoch);
761
+ this.reportError({
762
+ code: 'frame_acknowledgement_failed',
763
+ message: `Live browser frame acknowledgement capacity of ${maxPendingAcknowledgements} was reached`,
764
+ }, frameWorkArg.runEpoch);
765
+ return Promise.resolve();
766
+ }
767
+ const acknowledgement = this.runClientOperation((optionsArg) => {
768
+ if (!('acknowledgeFrame' in this.client))
769
+ throw new Error('Video clients do not acknowledge image frames');
770
+ return this.client.acknowledgeFrame(createFrameAcknowledgementRequest(frameWorkArg.frame), optionsArg);
771
+ }, 'frame acknowledgement', frameWorkArg.runEpoch)
772
+ .then(() => undefined)
773
+ .catch((error) => {
774
+ if (error instanceof LiveBrowserRunAbortedError) {
775
+ return;
776
+ }
777
+ this.requestSuspend(frameWorkArg.runEpoch);
778
+ this.reportError({
779
+ code: 'frame_acknowledgement_failed',
780
+ message: `Could not acknowledge live browser frame: ${getErrorMessage(error)}`,
781
+ cause: error,
782
+ frame: frameWorkArg.frame,
783
+ }, frameWorkArg.runEpoch);
784
+ });
785
+ let trackedAcknowledgement;
786
+ trackedAcknowledgement = acknowledgement.finally(() => {
787
+ this.acknowledgementPromises.delete(trackedAcknowledgement);
788
+ });
789
+ this.acknowledgementPromises.add(trackedAcknowledgement);
790
+ return trackedAcknowledgement;
791
+ }
792
+ handlePointerDown(eventArg, runEpochArg) {
793
+ if (eventArg.pointerType && eventArg.pointerType !== 'mouse') {
794
+ return;
795
+ }
796
+ const button = this.getMouseButton(eventArg.button);
797
+ if (!button) {
798
+ return;
799
+ }
800
+ const displayedFrame = this.getInputFrame();
801
+ if (!displayedFrame || runEpochArg !== this.runEpoch) {
802
+ return;
803
+ }
804
+ eventArg.preventDefault();
805
+ const coordinates = this.mapCoordinates(eventArg, displayedFrame.viewport);
806
+ if (!coordinates) {
807
+ return;
808
+ }
809
+ this.focusTarget.focus({ preventScroll: true });
810
+ try {
811
+ this.canvas.setPointerCapture(eventArg.pointerId);
812
+ this.capturedPointerIds.add(eventArg.pointerId);
813
+ }
814
+ catch {
815
+ // Pointer capture may already have been released by the browser.
816
+ }
817
+ const input = {
818
+ ...createInputIdentity(displayedFrame),
819
+ type: 'down',
820
+ ...coordinates,
821
+ button,
822
+ buttons: eventArg.buttons,
823
+ clickCount: Math.min(3, Math.max(1, eventArg.detail || 1)),
824
+ modifiers: createModifiers(eventArg),
825
+ };
826
+ void this.enqueueInputCommand({
827
+ kind: 'mouse',
828
+ runEpoch: runEpochArg,
829
+ execute: async (optionsArg) => this.client.dispatchMouse(input, optionsArg),
830
+ onAttempt: () => this.pressedMouseButtons.set(button, input),
831
+ }).catch(() => undefined);
832
+ }
833
+ handlePointerMove(eventArg, runEpochArg) {
834
+ if (eventArg.pointerType && eventArg.pointerType !== 'mouse') {
835
+ return;
836
+ }
837
+ const displayedFrame = this.getInputFrame();
838
+ if (!displayedFrame || runEpochArg !== this.runEpoch) {
839
+ return;
840
+ }
841
+ eventArg.preventDefault();
842
+ const coordinates = this.mapCoordinates(eventArg, displayedFrame.viewport);
843
+ if (!coordinates) {
844
+ this.releasePointerCapture(eventArg.pointerId);
845
+ void this.scheduleInputReset(false, runEpochArg);
846
+ return;
847
+ }
848
+ const input = {
849
+ ...createInputIdentity(displayedFrame),
850
+ type: 'move',
851
+ ...coordinates,
852
+ button: 'none',
853
+ buttons: eventArg.buttons,
854
+ modifiers: createModifiers(eventArg),
855
+ };
856
+ void this.enqueueInputCommand({
857
+ kind: 'mouseMove',
858
+ runEpoch: runEpochArg,
859
+ execute: async (optionsArg) => this.client.dispatchMouse(input, optionsArg),
860
+ }).catch(() => undefined);
861
+ }
862
+ handlePointerUp(eventArg, runEpochArg) {
863
+ if (eventArg.pointerType && eventArg.pointerType !== 'mouse') {
864
+ return;
865
+ }
866
+ const button = this.getMouseButton(eventArg.button);
867
+ const displayedFrame = this.getInputFrame();
868
+ if (!button || !displayedFrame || runEpochArg !== this.runEpoch) {
869
+ this.releasePointerCapture(eventArg.pointerId);
870
+ return;
871
+ }
872
+ eventArg.preventDefault();
873
+ const coordinates = this.mapCoordinates(eventArg, displayedFrame.viewport);
874
+ if (!coordinates) {
875
+ this.releasePointerCapture(eventArg.pointerId);
876
+ void this.scheduleInputReset(false, runEpochArg);
877
+ return;
878
+ }
879
+ const input = {
880
+ ...createInputIdentity(displayedFrame),
881
+ type: 'up',
882
+ ...coordinates,
883
+ button,
884
+ buttons: eventArg.buttons,
885
+ clickCount: Math.min(3, Math.max(1, eventArg.detail || 1)),
886
+ modifiers: createModifiers(eventArg),
887
+ };
888
+ void this.enqueueInputCommand({
889
+ kind: 'mouse',
890
+ runEpoch: runEpochArg,
891
+ execute: async (optionsArg) => this.client.dispatchMouse(input, optionsArg),
892
+ onSuccess: () => this.pressedMouseButtons.delete(button),
893
+ }).catch(() => undefined);
894
+ this.releasePointerCapture(eventArg.pointerId);
895
+ }
896
+ handleWheel(eventArg, runEpochArg) {
897
+ const displayedFrame = this.getInputFrame();
898
+ if (!displayedFrame || runEpochArg !== this.runEpoch) {
899
+ return;
900
+ }
901
+ eventArg.preventDefault();
902
+ const coordinates = this.mapCoordinates(eventArg, displayedFrame.viewport);
903
+ if (!coordinates) {
904
+ return;
905
+ }
906
+ const multiplier = eventArg.deltaMode === WheelEvent.DOM_DELTA_LINE
907
+ ? 16
908
+ : eventArg.deltaMode === WheelEvent.DOM_DELTA_PAGE
909
+ ? displayedFrame.viewport.height
910
+ : 1;
911
+ const inputIdentity = createInputIdentity(displayedFrame);
912
+ const modifiers = createModifiers(eventArg);
913
+ this.statistics.inputCommandsEnqueued++;
914
+ const pendingWheel = this.pendingWheel;
915
+ if (pendingWheel
916
+ && pendingWheel.runEpoch === runEpochArg
917
+ && inputIdentityEquals(pendingWheel, inputIdentity)) {
918
+ mergeWheelInput(pendingWheel, {
919
+ ...inputIdentity,
920
+ ...coordinates,
921
+ deltaX: eventArg.deltaX * multiplier,
922
+ deltaY: eventArg.deltaY * multiplier,
923
+ modifiers,
924
+ });
925
+ this.statistics.inputCommandsCoalesced++;
926
+ }
927
+ else {
928
+ if (pendingWheel) {
929
+ this.flushPendingWheel();
930
+ }
931
+ this.pendingWheel = {
932
+ ...inputIdentity,
933
+ ...coordinates,
934
+ deltaX: clampWheelDelta(eventArg.deltaX * multiplier),
935
+ deltaY: clampWheelDelta(eventArg.deltaY * multiplier),
936
+ modifiers,
937
+ runEpoch: runEpochArg,
938
+ };
939
+ }
940
+ this.tryFlushPendingWheel();
941
+ }
942
+ /**
943
+ * Flushes accumulated wheel input at most once per animation frame and only
944
+ * while no wheel dispatch is in flight; the settling dispatch flushes the rest.
945
+ */
946
+ tryFlushPendingWheel() {
947
+ if (!this.pendingWheel) {
948
+ return;
949
+ }
950
+ if (!this.wheelFrameElapsed) {
951
+ this.scheduleWheelFlush();
952
+ return;
953
+ }
954
+ if (this.inFlightWheelCommands > 0) {
955
+ return;
956
+ }
957
+ this.flushPendingWheel();
958
+ }
959
+ scheduleWheelFlush() {
960
+ if (this.wheelFlushSchedule) {
961
+ return;
962
+ }
963
+ this.wheelFlushSchedule = this.scheduleAnimationFrame(() => {
964
+ this.wheelFlushSchedule = undefined;
965
+ this.wheelFrameElapsed = true;
966
+ this.tryFlushPendingWheel();
967
+ });
968
+ }
969
+ /**
970
+ * Moves the accumulated wheel input into the command queue regardless of the
971
+ * frame gate so that later discrete commands stay behind it.
972
+ */
973
+ flushPendingWheel() {
974
+ const pendingWheel = this.pendingWheel;
975
+ if (!pendingWheel) {
976
+ return;
977
+ }
978
+ this.pendingWheel = undefined;
979
+ this.wheelFrameElapsed = false;
980
+ this.scheduleWheelFlush();
981
+ const displayedFrame = this.getInputFrame();
982
+ if (!displayedFrame
983
+ || pendingWheel.runEpoch !== this.runEpoch
984
+ || !inputIdentityEquals(pendingWheel, createInputIdentity(displayedFrame))) {
985
+ return;
986
+ }
987
+ const { runEpoch, ...wheelInput } = pendingWheel;
988
+ void this.enqueueInputCommand({
989
+ kind: 'wheel',
990
+ runEpoch,
991
+ wheelInput,
992
+ execute: async (optionsArg) => this.client.dispatchWheel({
993
+ ...wheelInput,
994
+ deltaX: clampWheelDelta(wheelInput.deltaX),
995
+ deltaY: clampWheelDelta(wheelInput.deltaY),
996
+ }, optionsArg),
997
+ }).catch(() => undefined);
998
+ }
999
+ discardPendingWheel() {
1000
+ this.pendingWheel = undefined;
1001
+ if (this.wheelFlushSchedule) {
1002
+ this.cancelScheduledFrame(this.wheelFlushSchedule);
1003
+ this.wheelFlushSchedule = undefined;
1004
+ }
1005
+ this.wheelFrameElapsed = true;
1006
+ }
1007
+ handleKey(eventArg, typeArg, runEpochArg) {
1008
+ const displayedFrame = this.getInputFrame();
1009
+ if (!displayedFrame
1010
+ || runEpochArg !== this.runEpoch
1011
+ || eventArg.isComposing
1012
+ || eventArg.key === 'Process') {
1013
+ return;
1014
+ }
1015
+ eventArg.preventDefault();
1016
+ const text = typeArg === 'down'
1017
+ && eventArg.key.length === 1
1018
+ && !eventArg.metaKey
1019
+ && (!eventArg.ctrlKey || eventArg.altKey)
1020
+ ? eventArg.key
1021
+ : undefined;
1022
+ const input = {
1023
+ ...createInputIdentity(displayedFrame),
1024
+ type: typeArg,
1025
+ key: eventArg.key,
1026
+ code: eventArg.code || undefined,
1027
+ text,
1028
+ windowsVirtualKeyCode: eventArg.keyCode || undefined,
1029
+ autoRepeat: eventArg.repeat,
1030
+ isKeypad: eventArg.location === KeyboardEvent.DOM_KEY_LOCATION_NUMPAD,
1031
+ location: eventArg.location,
1032
+ modifiers: createModifiers(eventArg),
1033
+ };
1034
+ const keyIdentity = eventArg.code || eventArg.key;
1035
+ void this.enqueueInputCommand({
1036
+ kind: 'key',
1037
+ runEpoch: runEpochArg,
1038
+ execute: async (optionsArg) => this.client.dispatchKey(input, optionsArg),
1039
+ onAttempt: typeArg === 'down'
1040
+ ? () => this.pressedKeys.set(keyIdentity, input)
1041
+ : undefined,
1042
+ onSuccess: () => {
1043
+ if (typeArg === 'up') {
1044
+ this.pressedKeys.delete(keyIdentity);
1045
+ }
1046
+ },
1047
+ }).catch(() => undefined);
1048
+ }
1049
+ mapCoordinates(eventArg, viewportArg) {
1050
+ const bounds = this.canvas.getBoundingClientRect();
1051
+ let canvasBounds = { left: bounds.left, top: bounds.top, width: bounds.width, height: bounds.height };
1052
+ if (this.videoReceiver && bounds.width > 0 && bounds.height > 0) {
1053
+ const scale = Math.min(bounds.width / viewportArg.width, bounds.height / viewportArg.height);
1054
+ canvasBounds = {
1055
+ left: bounds.left + (bounds.width - viewportArg.width * scale) / 2,
1056
+ top: bounds.top + (bounds.height - viewportArg.height * scale) / 2,
1057
+ width: viewportArg.width * scale, height: viewportArg.height * scale,
1058
+ };
1059
+ if (this.pressedMouseButtons.size === 0 && (eventArg.clientX < canvasBounds.left
1060
+ || eventArg.clientX >= canvasBounds.left + canvasBounds.width
1061
+ || eventArg.clientY < canvasBounds.top || eventArg.clientY >= canvasBounds.top + canvasBounds.height))
1062
+ return undefined;
1063
+ }
1064
+ if (canvasBounds.width <= 0 || canvasBounds.height <= 0) {
1065
+ return undefined;
1066
+ }
1067
+ const x = ((eventArg.clientX - canvasBounds.left) / canvasBounds.width) * viewportArg.width;
1068
+ const y = ((eventArg.clientY - canvasBounds.top) / canvasBounds.height) * viewportArg.height;
1069
+ return {
1070
+ x: Math.max(0, Math.min(viewportArg.width - coordinateEdgeInset, x)),
1071
+ y: Math.max(0, Math.min(viewportArg.height - coordinateEdgeInset, y)),
1072
+ };
1073
+ }
1074
+ getMouseButton(buttonArg) {
1075
+ return buttonArg === 0
1076
+ ? 'left'
1077
+ : buttonArg === 1
1078
+ ? 'middle'
1079
+ : buttonArg === 2
1080
+ ? 'right'
1081
+ : buttonArg === 3
1082
+ ? 'back'
1083
+ : buttonArg === 4
1084
+ ? 'forward'
1085
+ : undefined;
1086
+ }
1087
+ getInputFrame() {
1088
+ return this.inputBlocked || !this.isDisplayedFrameCurrent()
1089
+ ? undefined
1090
+ : this.displayedFrame;
1091
+ }
1092
+ requireInputFrame() {
1093
+ const displayedFrame = this.getInputFrame();
1094
+ if (!displayedFrame) {
1095
+ throw new Error('Live browser input is unavailable until a current frame is displayed');
1096
+ }
1097
+ return displayedFrame;
1098
+ }
1099
+ isDisplayedFrameCurrent() {
1100
+ const state = this.state;
1101
+ const displayedFrame = this.displayedFrame;
1102
+ if (!state || !displayedFrame || state.status !== 'running') {
1103
+ return false;
1104
+ }
1105
+ if (state.activeTabId !== displayedFrame.tabId
1106
+ || state.viewportRevision > displayedFrame.viewportRevision) {
1107
+ return false;
1108
+ }
1109
+ const activeTab = state.tabs.find((tabArg) => tabArg.id === displayedFrame.tabId);
1110
+ return Boolean(activeTab
1111
+ && activeTab.status === 'open'
1112
+ && activeTab.streaming
1113
+ && activeTab.generation <= displayedFrame.generation);
1114
+ }
1115
+ enqueueInputCommand(commandArg) {
1116
+ if (!this.running || this.inputBlocked || commandArg.runEpoch !== this.runEpoch) {
1117
+ return Promise.reject(new Error('Live browser input is currently blocked'));
1118
+ }
1119
+ return new Promise((resolve, reject) => {
1120
+ const command = {
1121
+ ...commandArg,
1122
+ resolve,
1123
+ reject,
1124
+ };
1125
+ if (isCoalescableInputCommand(command.kind)) {
1126
+ this.enqueueCoalescableCommand(command);
1127
+ }
1128
+ else {
1129
+ const queuedDiscreteCommands = this.inputCommands.filter((queuedCommand) => (!isCoalescableInputCommand(queuedCommand.kind))).length;
1130
+ if (queuedDiscreteCommands >= maxInputQueueLength) {
1131
+ const error = new Error('Live browser input queue reached its capacity');
1132
+ this.reportError({
1133
+ code: 'input_queue_capacity_exceeded',
1134
+ message: error.message,
1135
+ cause: error,
1136
+ }, command.runEpoch);
1137
+ reject(error);
1138
+ return;
1139
+ }
1140
+ // Accumulated wheel input precedes this command in event order.
1141
+ this.flushPendingWheel();
1142
+ this.statistics.inputCommandsEnqueued++;
1143
+ this.inputCommands.push(command);
1144
+ }
1145
+ this.processInputCommands();
1146
+ });
1147
+ }
1148
+ /**
1149
+ * Coalescable commands never exhaust capacity: they merge into a same-kind
1150
+ * queue tail or evict the oldest queued coalescable command under pressure.
1151
+ */
1152
+ enqueueCoalescableCommand(commandArg) {
1153
+ // Wheel submissions are counted per DOM event before accumulation.
1154
+ if (commandArg.kind === 'mouseMove') {
1155
+ this.statistics.inputCommandsEnqueued++;
1156
+ }
1157
+ const lastCommand = this.inputCommands.at(-1);
1158
+ if (lastCommand && lastCommand.kind === commandArg.kind) {
1159
+ this.statistics.inputCommandsCoalesced++;
1160
+ if (commandArg.kind === 'wheel' && lastCommand.wheelInput && commandArg.wheelInput) {
1161
+ mergeWheelInput(lastCommand.wheelInput, commandArg.wheelInput);
1162
+ commandArg.resolve();
1163
+ }
1164
+ else {
1165
+ lastCommand.resolve();
1166
+ this.inputCommands[this.inputCommands.length - 1] = commandArg;
1167
+ }
1168
+ return;
1169
+ }
1170
+ const queuedCoalescableCommands = this.inputCommands.filter((queuedCommand) => (isCoalescableInputCommand(queuedCommand.kind)));
1171
+ if (queuedCoalescableCommands.length >= maxQueuedCoalescableCommands) {
1172
+ this.dropOldestCoalescableCommand(queuedCoalescableCommands[0]);
1173
+ }
1174
+ this.inputCommands.push(commandArg);
1175
+ }
1176
+ dropOldestCoalescableCommand(oldestCommandArg) {
1177
+ const index = this.inputCommands.indexOf(oldestCommandArg);
1178
+ if (index < 0) {
1179
+ return;
1180
+ }
1181
+ this.inputCommands.splice(index, 1);
1182
+ this.statistics.inputCommandsCoalesced++;
1183
+ if (oldestCommandArg.kind === 'wheel' && oldestCommandArg.wheelInput) {
1184
+ const nextWheelCommand = this.inputCommands.find((queuedCommand) => (queuedCommand.kind === 'wheel' && queuedCommand.wheelInput));
1185
+ if (nextWheelCommand?.wheelInput) {
1186
+ const nextWheelInput = nextWheelCommand.wheelInput;
1187
+ nextWheelInput.deltaX = clampWheelDelta(nextWheelInput.deltaX + oldestCommandArg.wheelInput.deltaX);
1188
+ nextWheelInput.deltaY = clampWheelDelta(nextWheelInput.deltaY + oldestCommandArg.wheelInput.deltaY);
1189
+ }
1190
+ }
1191
+ oldestCommandArg.resolve();
1192
+ }
1193
+ /**
1194
+ * Dispatches queued commands in order with a bounded number in flight. The
1195
+ * remote session processes operations sequentially, so order is preserved.
1196
+ */
1197
+ processInputCommands() {
1198
+ while (this.inputCommands.length > 0
1199
+ && this.inFlightInputCommands < maxInFlightInputCommands) {
1200
+ const command = this.inputCommands.shift();
1201
+ if (!this.isRunActive(command.runEpoch)) {
1202
+ command.reject(new LiveBrowserRunAbortedError(`Live browser input belongs to inactive run ${command.runEpoch}`));
1203
+ continue;
1204
+ }
1205
+ this.dispatchInputCommand(command);
1206
+ }
1207
+ if (this.inputCommands.length === 0 && this.inFlightInputCommands === 0) {
1208
+ const resolvers = this.inputIdleResolvers;
1209
+ this.inputIdleResolvers = [];
1210
+ for (const resolver of resolvers) {
1211
+ resolver();
1212
+ }
1213
+ }
1214
+ }
1215
+ dispatchInputCommand(commandArg) {
1216
+ this.inFlightInputCommands++;
1217
+ if (commandArg.kind === 'wheel') {
1218
+ this.inFlightWheelCommands++;
1219
+ }
1220
+ const startedAt = performance.now();
1221
+ let dispatch;
1222
+ try {
1223
+ commandArg.onAttempt?.();
1224
+ dispatch = this.runClientOperation(commandArg.execute, 'input dispatch', commandArg.runEpoch);
1225
+ }
1226
+ catch (error) {
1227
+ dispatch = Promise.reject(error);
1228
+ }
1229
+ void dispatch.then(() => {
1230
+ if (!this.isRunActive(commandArg.runEpoch)) {
1231
+ throw new LiveBrowserRunAbortedError(`Live browser input belongs to inactive run ${commandArg.runEpoch}`);
1232
+ }
1233
+ this.statistics.lastInputRoundTripMs = performance.now() - startedAt;
1234
+ commandArg.onSuccess?.();
1235
+ commandArg.resolve();
1236
+ }).catch((error) => {
1237
+ commandArg.reject(error);
1238
+ this.handleInputDispatchFailure(error, commandArg.runEpoch);
1239
+ }).finally(() => {
1240
+ this.inFlightInputCommands--;
1241
+ if (commandArg.kind === 'wheel') {
1242
+ this.inFlightWheelCommands--;
1243
+ if (this.inFlightWheelCommands === 0) {
1244
+ this.tryFlushPendingWheel();
1245
+ }
1246
+ }
1247
+ this.processInputCommands();
1248
+ });
1249
+ }
1250
+ handleInputDispatchFailure(errorArg, runEpochArg) {
1251
+ if (errorArg instanceof LiveBrowserRunAbortedError) {
1252
+ return;
1253
+ }
1254
+ if (errorArg instanceof LiveBrowserOperationTimeoutError) {
1255
+ this.requestSuspend(runEpochArg);
1256
+ }
1257
+ this.reportError({
1258
+ code: 'input_dispatch_failed',
1259
+ message: `Could not dispatch live browser input: ${getErrorMessage(errorArg)}`,
1260
+ cause: errorArg,
1261
+ }, runEpochArg);
1262
+ this.discardPendingWheel();
1263
+ const abandonedCommands = this.inputCommands.splice(0);
1264
+ for (const abandonedCommand of abandonedCommands) {
1265
+ abandonedCommand.reject(new Error('Live browser input was abandoned after a dispatch failure'));
1266
+ }
1267
+ if (!(errorArg instanceof LiveBrowserOperationTimeoutError) && !this.stopping) {
1268
+ void this.scheduleInputReset(true, runEpochArg);
1269
+ }
1270
+ }
1271
+ waitForInputIdle() {
1272
+ if (this.inFlightInputCommands === 0 && this.inputCommands.length === 0) {
1273
+ return Promise.resolve();
1274
+ }
1275
+ return new Promise((resolve) => {
1276
+ this.inputIdleResolvers.push(resolve);
1277
+ });
1278
+ }
1279
+ scheduleInputReset(clearDisplayArg, runEpochArg) {
1280
+ if (runEpochArg !== this.runEpoch || this.stopping) {
1281
+ return Promise.resolve();
1282
+ }
1283
+ this.inputBlocked = true;
1284
+ this.releasePointerCaptures();
1285
+ if (clearDisplayArg) {
1286
+ this.displayedFrame = undefined;
1287
+ this.clearCanvas();
1288
+ }
1289
+ if (this.inputResetPromise) {
1290
+ return this.inputResetPromise;
1291
+ }
1292
+ this.inputResetCount++;
1293
+ let resetOperation;
1294
+ resetOperation = this.inputResetTail.then(async () => {
1295
+ await this.waitForInputIdle();
1296
+ await this.releasePressedInput(runEpochArg);
1297
+ }).finally(() => {
1298
+ this.inputResetCount--;
1299
+ if (this.inputResetPromise === resetOperation) {
1300
+ this.inputResetPromise = undefined;
1301
+ }
1302
+ this.updateInputAvailability();
1303
+ });
1304
+ this.inputResetPromise = resetOperation;
1305
+ this.inputResetTail = resetOperation.then(() => undefined, () => undefined);
1306
+ return resetOperation;
1307
+ }
1308
+ async releasePressedInput(runEpochArg) {
1309
+ for (const [keyIdentity, pressedKey] of [...this.pressedKeys.entries()]) {
1310
+ const released = await this.tryInputRelease((optionsArg) => this.client.dispatchKey({
1311
+ ...pressedKey,
1312
+ type: 'up',
1313
+ text: undefined,
1314
+ autoRepeat: false,
1315
+ modifiers: {},
1316
+ }, optionsArg), runEpochArg);
1317
+ if (released && this.pressedKeys.get(keyIdentity) === pressedKey) {
1318
+ this.pressedKeys.delete(keyIdentity);
1319
+ }
1320
+ }
1321
+ for (const [button, pressedButton] of [...this.pressedMouseButtons.entries()]) {
1322
+ const released = await this.tryInputRelease((optionsArg) => this.client.dispatchMouse({
1323
+ ...pressedButton,
1324
+ type: 'up',
1325
+ buttons: 0,
1326
+ clickCount: 1,
1327
+ modifiers: {},
1328
+ }, optionsArg), runEpochArg);
1329
+ if (released && this.pressedMouseButtons.get(button) === pressedButton) {
1330
+ this.pressedMouseButtons.delete(button);
1331
+ }
1332
+ }
1333
+ }
1334
+ async tryInputRelease(operationArg, runEpochArg) {
1335
+ let lastError;
1336
+ for (let attempt = 0; attempt < maxInputReleaseAttempts; attempt++) {
1337
+ try {
1338
+ await this.runClientOperation(operationArg, 'input release', runEpochArg);
1339
+ return true;
1340
+ }
1341
+ catch (error) {
1342
+ if (error instanceof LiveBrowserRunAbortedError) {
1343
+ return false;
1344
+ }
1345
+ lastError = error;
1346
+ }
1347
+ }
1348
+ this.requestSuspend(runEpochArg);
1349
+ this.reportInputReleaseError(lastError, runEpochArg);
1350
+ return false;
1351
+ }
1352
+ reportInputReleaseError(errorArg, runEpochArg) {
1353
+ this.reportError({
1354
+ code: 'input_dispatch_failed',
1355
+ message: `Could not release live browser input: ${getErrorMessage(errorArg)}`,
1356
+ cause: errorArg,
1357
+ }, runEpochArg);
1358
+ }
1359
+ queueViewport(widthArg, heightArg, runEpochArg) {
1360
+ if (!this.running
1361
+ || this.stopping
1362
+ || this.interruptionRequested
1363
+ || runEpochArg !== this.runEpoch) {
1364
+ return;
1365
+ }
1366
+ const viewport = this.normalizeGeneratedViewport(widthArg, heightArg, runEpochArg);
1367
+ if (!viewport)
1368
+ return;
1369
+ if (this.pendingViewport && viewportEquals(viewport, this.pendingViewport)) {
1370
+ return;
1371
+ }
1372
+ if (this.inFlightViewport && viewportEquals(viewport, this.inFlightViewport)) {
1373
+ this.pendingViewport = undefined;
1374
+ return;
1375
+ }
1376
+ if (!this.inFlightViewport && this.lastRequestedViewport && viewportEquals(viewport, this.lastRequestedViewport)) {
1377
+ this.pendingViewport = undefined;
1378
+ return;
1379
+ }
1380
+ if (!this.inFlightViewport
1381
+ && this.resizeFence
1382
+ && !this.resizeFence.negotiated
1383
+ && viewportEquals(viewport, this.resizeFence.target)) {
1384
+ this.pendingViewport = undefined;
1385
+ return;
1386
+ }
1387
+ if (!this.inFlightViewport
1388
+ && !this.resizeFence
1389
+ && !this.lastRequestedViewport
1390
+ && this.state
1391
+ && viewportEquals(viewport, this.state.viewport)) {
1392
+ this.pendingViewport = undefined;
1393
+ this.lastRequestedViewport = { ...viewport };
1394
+ this.updateInputAvailability();
1395
+ return;
1396
+ }
1397
+ this.pendingViewport = viewport;
1398
+ this.inputBlocked = true;
1399
+ this.ensureViewportProcessor(runEpochArg);
1400
+ }
1401
+ normalizeGeneratedViewport(widthArg, heightArg, runEpochArg) {
1402
+ if (!Number.isFinite(widthArg)
1403
+ || !Number.isFinite(heightArg)
1404
+ || widthArg <= 0
1405
+ || heightArg <= 0) {
1406
+ this.reportError({
1407
+ code: 'viewport_update_failed',
1408
+ message: 'Live browser viewport dimensions must be positive finite numbers',
1409
+ }, runEpochArg);
1410
+ return undefined;
1411
+ }
1412
+ const measuredWidth = Math.max(1, Math.floor(widthArg));
1413
+ const measuredHeight = Math.max(1, Math.floor(heightArg));
1414
+ const reductionFactor = Math.min(1, maxViewportWidth / measuredWidth, maxViewportHeight / measuredHeight);
1415
+ const width = Math.max(1, Math.floor(measuredWidth * reductionFactor));
1416
+ const height = Math.max(1, Math.floor(measuredHeight * reductionFactor));
1417
+ const providedScale = this.getDeviceScaleFactor();
1418
+ if (!Number.isFinite(providedScale) || providedScale <= 0) {
1419
+ this.reportError({
1420
+ code: 'viewport_update_failed',
1421
+ message: 'Live browser device scale factor must be a positive finite number',
1422
+ }, runEpochArg);
1423
+ return undefined;
1424
+ }
1425
+ const desiredScale = Math.min(maxDeviceScaleFactor, Math.max(minDeviceScaleFactor, providedScale));
1426
+ const physicalAreaIsValid = (scaleArg) => (Math.ceil(width * scaleArg) * Math.ceil(height * scaleArg) <= maxFramePixelArea);
1427
+ let deviceScaleFactor = desiredScale;
1428
+ if (!physicalAreaIsValid(deviceScaleFactor)) {
1429
+ let lower = minDeviceScaleFactor;
1430
+ let upper = desiredScale;
1431
+ for (let iteration = 0; iteration < 40; iteration += 1) {
1432
+ const candidate = (lower + upper) / 2;
1433
+ if (physicalAreaIsValid(candidate))
1434
+ lower = candidate;
1435
+ else
1436
+ upper = candidate;
1437
+ }
1438
+ deviceScaleFactor = lower;
1439
+ }
1440
+ return { width, height, deviceScaleFactor };
1441
+ }
1442
+ ensureViewportProcessor(runEpochArg) {
1443
+ if (this.viewportProcessingPromise || !this.pendingViewport) {
1444
+ return;
1445
+ }
1446
+ const processingPromise = this.processViewportQueue(runEpochArg).finally(() => {
1447
+ if (this.viewportProcessingPromise === processingPromise) {
1448
+ this.viewportProcessingPromise = undefined;
1449
+ if (this.pendingViewport
1450
+ && this.running
1451
+ && !this.stopping
1452
+ && runEpochArg === this.runEpoch) {
1453
+ this.ensureViewportProcessor(runEpochArg);
1454
+ }
1455
+ }
1456
+ });
1457
+ this.viewportProcessingPromise = processingPromise;
1458
+ }
1459
+ async processViewportQueue(runEpochArg) {
1460
+ this.viewportProcessing = true;
1461
+ try {
1462
+ while (this.pendingViewport
1463
+ && this.running
1464
+ && !this.stopping
1465
+ && runEpochArg === this.runEpoch) {
1466
+ const viewport = this.pendingViewport;
1467
+ this.pendingViewport = undefined;
1468
+ this.inFlightViewport = viewport;
1469
+ if (!this.resizeFence && !this.lastRequestedViewport && this.state && viewportEquals(viewport, this.state.viewport)) {
1470
+ this.inFlightViewport = undefined;
1471
+ this.lastRequestedViewport = { ...viewport };
1472
+ continue;
1473
+ }
1474
+ await this.scheduleInputReset(false, runEpochArg);
1475
+ if (!this.running || this.stopping || runEpochArg !== this.runEpoch) {
1476
+ return;
1477
+ }
1478
+ const currentRevision = this.state?.viewportRevision ?? 0;
1479
+ const previousMinimumRevision = this.resizeFence?.minimumViewportRevision ?? currentRevision;
1480
+ try {
1481
+ const result = await this.runClientOperation((optionsArg) => this.client.setViewport(viewport, optionsArg), 'viewport update', runEpochArg);
1482
+ if (!this.running || this.stopping || runEpochArg !== this.runEpoch) {
1483
+ return;
1484
+ }
1485
+ if (result !== undefined) {
1486
+ this.validateViewport(result.viewport, 'viewport result');
1487
+ this.validateProtocolInteger(result.viewportRevision, 'viewport result revision', Math.max(1, currentRevision));
1488
+ this.resizeFence = { target: { ...result.viewport }, minimumViewportRevision: result.viewportRevision, negotiated: true };
1489
+ this.followNegotiatedViewport();
1490
+ }
1491
+ else {
1492
+ this.resizeFence = { target: viewport, minimumViewportRevision: Math.max(currentRevision, previousMinimumRevision) + 1 };
1493
+ }
1494
+ this.lastRequestedViewport = { ...viewport };
1495
+ }
1496
+ catch (error) {
1497
+ if (runEpochArg === this.runEpoch && !(error instanceof LiveBrowserRunAbortedError)) {
1498
+ this.resizeFence = undefined;
1499
+ if (error instanceof LiveBrowserOperationTimeoutError) {
1500
+ this.requestSuspend(runEpochArg);
1501
+ }
1502
+ this.reportError({
1503
+ code: 'viewport_update_failed',
1504
+ message: `Could not update live browser viewport: ${getErrorMessage(error)}`,
1505
+ cause: error,
1506
+ }, runEpochArg);
1507
+ }
1508
+ }
1509
+ finally {
1510
+ if (this.inFlightViewport && viewportEquals(this.inFlightViewport, viewport)) {
1511
+ this.inFlightViewport = undefined;
1512
+ }
1513
+ }
1514
+ }
1515
+ }
1516
+ finally {
1517
+ this.viewportProcessing = false;
1518
+ this.updateInputAvailability();
1519
+ }
1520
+ }
1521
+ updateInputAvailability() {
1522
+ if (this.resizeFence && !this.viewportProcessing && this.displayedFrame && this.isDisplayedFrameCurrent()
1523
+ && this.displayedFrame.viewportRevision >= this.resizeFence.minimumViewportRevision
1524
+ && viewportEquals(this.displayedFrame.viewport, this.resizeFence.target)) {
1525
+ this.resizeFence = undefined;
1526
+ }
1527
+ this.inputBlocked = !(this.running
1528
+ && this.acceptingFrames
1529
+ && !this.viewportProcessing
1530
+ && !this.resizeFence
1531
+ && this.inputResetCount === 0
1532
+ && this.isDisplayedFrameCurrent());
1533
+ }
1534
+ followNegotiatedViewport() {
1535
+ if (this.resizeFence?.negotiated && this.state && this.state.viewportRevision > this.resizeFence.minimumViewportRevision) {
1536
+ this.resizeFence = { target: { ...this.state.viewport }, minimumViewportRevision: this.state.viewportRevision, negotiated: true };
1537
+ }
1538
+ }
1539
+ makeFocusTargetFocusable() {
1540
+ this.focusWasAdjusted = false;
1541
+ if (this.focusTarget.tabIndex >= 0) {
1542
+ return;
1543
+ }
1544
+ this.focusHadTabIndex = this.focusTarget.hasAttribute('tabindex');
1545
+ this.focusTabIndexValue = this.focusTarget.getAttribute('tabindex');
1546
+ this.focusTarget.setAttribute('tabindex', '0');
1547
+ this.focusWasAdjusted = true;
1548
+ }
1549
+ restoreFocusTarget() {
1550
+ if (!this.focusWasAdjusted) {
1551
+ return;
1552
+ }
1553
+ if (this.focusHadTabIndex && this.focusTabIndexValue !== null) {
1554
+ this.focusTarget.setAttribute('tabindex', this.focusTabIndexValue);
1555
+ }
1556
+ else {
1557
+ this.focusTarget.removeAttribute('tabindex');
1558
+ }
1559
+ this.focusWasAdjusted = false;
1560
+ }
1561
+ clearCanvas() {
1562
+ if (this.bitmapContext) {
1563
+ this.bitmapContext.transferFromImageBitmap(null);
1564
+ return;
1565
+ }
1566
+ this.canvasContext?.clearRect(0, 0, this.canvas.width, this.canvas.height);
1567
+ }
1568
+ /**
1569
+ * Runs work on the next animation frame, or after one nominal frame period
1570
+ * when the document is not visible and animation frames would not fire.
1571
+ */
1572
+ scheduleAnimationFrame(callbackArg) {
1573
+ const schedule = {};
1574
+ if (typeof document !== 'undefined'
1575
+ && document.visibilityState === 'visible'
1576
+ && typeof globalThis.requestAnimationFrame === 'function') {
1577
+ schedule.animationFrameId = globalThis.requestAnimationFrame(() => {
1578
+ schedule.animationFrameId = undefined;
1579
+ callbackArg();
1580
+ });
1581
+ }
1582
+ else {
1583
+ schedule.timeoutId = globalThis.setTimeout(() => {
1584
+ schedule.timeoutId = undefined;
1585
+ callbackArg();
1586
+ }, animationFrameFallbackMs);
1587
+ }
1588
+ return schedule;
1589
+ }
1590
+ cancelScheduledFrame(scheduleArg) {
1591
+ if (scheduleArg.animationFrameId !== undefined) {
1592
+ globalThis.cancelAnimationFrame(scheduleArg.animationFrameId);
1593
+ scheduleArg.animationFrameId = undefined;
1594
+ }
1595
+ if (scheduleArg.timeoutId !== undefined) {
1596
+ globalThis.clearTimeout(scheduleArg.timeoutId);
1597
+ scheduleArg.timeoutId = undefined;
1598
+ }
1599
+ }
1600
+ callFrameRendered(frameArg, runEpochArg) {
1601
+ if (!this.onFrameRendered || runEpochArg !== this.runEpoch || !this.running) {
1602
+ return;
1603
+ }
1604
+ try {
1605
+ this.onFrameRendered(frameArg);
1606
+ }
1607
+ catch (error) {
1608
+ this.reportError({
1609
+ code: 'renderer_callback_failed',
1610
+ message: `Live browser frame callback failed: ${getErrorMessage(error)}`,
1611
+ cause: error,
1612
+ frame: frameArg,
1613
+ }, runEpochArg);
1614
+ }
1615
+ }
1616
+ reportError(errorArg, runEpochArg) {
1617
+ if (!this.onError || runEpochArg !== this.runEpoch) {
1618
+ return;
1619
+ }
1620
+ try {
1621
+ this.onError(errorArg);
1622
+ }
1623
+ catch {
1624
+ // Consumer error reporting must not break renderer cleanup.
1625
+ }
1626
+ }
1627
+ requestSuspend(runEpochArg) {
1628
+ if (!this.isRunActive(runEpochArg) || this.interruptionRequested) {
1629
+ return;
1630
+ }
1631
+ this.interruptRun(runEpochArg);
1632
+ void this.suspend();
1633
+ }
1634
+ validateTimeout(timeoutArg, nameArg) {
1635
+ if (!Number.isFinite(timeoutArg) || timeoutArg <= 0) {
1636
+ throw new Error(`${nameArg} must be a positive finite number`);
1637
+ }
1638
+ return timeoutArg;
1639
+ }
1640
+ runClientOperation(operationArg, operationNameArg, runEpochArg) {
1641
+ return this.runAbortableOperation((signalArg) => operationArg({ signal: signalArg }), this.operationTimeoutMs, operationNameArg, runEpochArg);
1642
+ }
1643
+ runAbortableOperation(operationArg, timeoutMsArg, operationNameArg, runEpochArg) {
1644
+ const runController = this.runController;
1645
+ if (!runController
1646
+ || !this.isRunActive(runEpochArg)
1647
+ || runController.signal.aborted) {
1648
+ return Promise.reject(new LiveBrowserRunAbortedError(`Cannot start ${operationNameArg} for inactive run ${runEpochArg}`));
1649
+ }
1650
+ const operationController = new AbortController();
1651
+ this.operationControllers.add(operationController);
1652
+ const abortFromRun = () => {
1653
+ const reason = runController.signal.reason instanceof Error
1654
+ ? runController.signal.reason
1655
+ : new LiveBrowserRunAbortedError(`Live browser renderer run ${runEpochArg} was interrupted`);
1656
+ operationController.abort(reason);
1657
+ };
1658
+ runController.signal.addEventListener('abort', abortFromRun, { once: true });
1659
+ const timeout = globalThis.setTimeout(() => {
1660
+ operationController.abort(new LiveBrowserOperationTimeoutError(`${operationNameArg} timed out after ${timeoutMsArg}ms`));
1661
+ }, timeoutMsArg);
1662
+ let abortOperation = () => undefined;
1663
+ const operation = new Promise((resolve, reject) => {
1664
+ let settled = false;
1665
+ const settle = (callbackArg) => {
1666
+ if (!settled) {
1667
+ settled = true;
1668
+ callbackArg();
1669
+ }
1670
+ };
1671
+ abortOperation = () => {
1672
+ const reason = operationController.signal.reason instanceof Error
1673
+ ? operationController.signal.reason
1674
+ : new LiveBrowserRunAbortedError(`${operationNameArg} was aborted`);
1675
+ settle(() => reject(reason));
1676
+ };
1677
+ operationController.signal.addEventListener('abort', abortOperation, { once: true });
1678
+ let operationResult;
1679
+ try {
1680
+ operationResult = operationArg(operationController.signal);
1681
+ }
1682
+ catch (error) {
1683
+ settle(() => reject(error));
1684
+ return;
1685
+ }
1686
+ operationResult.then((valueArg) => {
1687
+ settle(() => resolve(valueArg));
1688
+ }, (errorArg) => {
1689
+ settle(() => reject(errorArg));
1690
+ });
1691
+ }).finally(() => {
1692
+ globalThis.clearTimeout(timeout);
1693
+ runController.signal.removeEventListener('abort', abortFromRun);
1694
+ operationController.signal.removeEventListener('abort', abortOperation);
1695
+ this.operationControllers.delete(operationController);
1696
+ });
1697
+ return operation;
1698
+ }
1699
+ async decodeFrame(blobArg, runEpochArg) {
1700
+ let decodeOperation;
1701
+ try {
1702
+ decodeOperation = createImageBitmap(blobArg);
1703
+ }
1704
+ catch (error) {
1705
+ throw error;
1706
+ }
1707
+ let rawDecodeSettlementPromise;
1708
+ rawDecodeSettlementPromise = decodeOperation.then(() => undefined, () => undefined).finally(() => {
1709
+ this.rawDecodeSettlementPromises.delete(rawDecodeSettlementPromise);
1710
+ });
1711
+ this.rawDecodeSettlementPromises.add(rawDecodeSettlementPromise);
1712
+ try {
1713
+ return await this.runAbortableOperation(async () => decodeOperation, this.frameDecodeTimeoutMs, 'frame decode', runEpochArg);
1714
+ }
1715
+ catch (error) {
1716
+ if (error instanceof LiveBrowserOperationTimeoutError
1717
+ || error instanceof LiveBrowserRunAbortedError) {
1718
+ void decodeOperation.then((lateBitmapArg) => lateBitmapArg.close(), () => undefined);
1719
+ throw error;
1720
+ }
1721
+ throw new LiveBrowserFrameIntegrityError(`frame bytes could not be decoded: ${getErrorMessage(error)}`, { cause: error });
1722
+ }
1723
+ }
1724
+ isRunActive(runEpochArg) {
1725
+ return Boolean(this.running
1726
+ && !this.stopping
1727
+ && runEpochArg === this.runEpoch
1728
+ && this.runController
1729
+ && !this.runController.signal.aborted);
1730
+ }
1731
+ validateFrame(frameArg) {
1732
+ if (!frameArg || typeof frameArg !== 'object') {
1733
+ throw new LiveBrowserFrameProtocolError('frame must be an object');
1734
+ }
1735
+ if (typeof frameArg.tabId !== 'string'
1736
+ || frameArg.tabId.length === 0
1737
+ || frameArg.tabId.length > 4096) {
1738
+ throw new LiveBrowserFrameProtocolError('frame.tabId must be a non-empty bounded string');
1739
+ }
1740
+ this.validateProtocolInteger(frameArg.sequence, 'frame.sequence', 1);
1741
+ this.validateProtocolInteger(frameArg.generation, 'frame.generation', 1);
1742
+ this.validateProtocolInteger(frameArg.viewportRevision, 'frame.viewportRevision', 1);
1743
+ this.validateViewport(frameArg.viewport, 'frame.viewport');
1744
+ if (frameArg.format !== 'jpeg' && frameArg.format !== 'png') {
1745
+ throw new LiveBrowserFrameProtocolError('frame.format must be jpeg or png');
1746
+ }
1747
+ const expectedMimeType = frameArg.format === 'jpeg' ? 'image/jpeg' : 'image/png';
1748
+ if (frameArg.mimeType !== expectedMimeType) {
1749
+ throw new LiveBrowserFrameProtocolError(`frame.mimeType must be ${expectedMimeType} for ${frameArg.format}`);
1750
+ }
1751
+ this.validateProtocolInteger(frameArg.width, 'frame.width', 1, maxFrameDimension);
1752
+ this.validateProtocolInteger(frameArg.height, 'frame.height', 1, maxFrameDimension);
1753
+ if (frameArg.width * frameArg.height > maxFramePixelArea) {
1754
+ throw new LiveBrowserFrameProtocolError(`frame pixel area must not exceed ${maxFramePixelArea}`);
1755
+ }
1756
+ if (!(frameArg.data instanceof Uint8Array)) {
1757
+ throw new LiveBrowserFrameProtocolError('frame.data must be a Uint8Array');
1758
+ }
1759
+ if (frameArg.data.byteLength === 0 || frameArg.data.byteLength > maxFrameByteLength) {
1760
+ throw new LiveBrowserFrameProtocolError(`frame.data byte length must be between 1 and ${maxFrameByteLength}`);
1761
+ }
1762
+ const metadata = frameArg.metadata;
1763
+ if (!metadata || typeof metadata !== 'object') {
1764
+ throw new LiveBrowserFrameProtocolError('frame.metadata must be an object');
1765
+ }
1766
+ this.validateProtocolNumber(metadata.offsetTop, 'frame.metadata.offsetTop');
1767
+ this.validateProtocolNumber(metadata.pageScaleFactor, 'frame.metadata.pageScaleFactor', true);
1768
+ this.validateProtocolNumber(metadata.deviceWidth, 'frame.metadata.deviceWidth', true);
1769
+ this.validateProtocolNumber(metadata.deviceHeight, 'frame.metadata.deviceHeight', true);
1770
+ if (metadata.deviceWidth > maxFrameDimension
1771
+ || metadata.deviceHeight > maxFrameDimension
1772
+ || metadata.deviceWidth * metadata.deviceHeight > maxFramePixelArea) {
1773
+ throw new LiveBrowserFrameProtocolError(`frame metadata dimensions must fit within ${maxFramePixelArea} pixels`);
1774
+ }
1775
+ this.validateProtocolNumber(metadata.scrollOffsetX, 'frame.metadata.scrollOffsetX');
1776
+ this.validateProtocolNumber(metadata.scrollOffsetY, 'frame.metadata.scrollOffsetY');
1777
+ if (metadata.timestamp !== undefined) {
1778
+ this.validateProtocolNumber(metadata.timestamp, 'frame.metadata.timestamp');
1779
+ }
1780
+ }
1781
+ validateViewport(viewportArg, nameArg) {
1782
+ if (!viewportArg || typeof viewportArg !== 'object') {
1783
+ throw new LiveBrowserFrameProtocolError(`${nameArg} must be an object`);
1784
+ }
1785
+ this.validateProtocolInteger(viewportArg.width, `${nameArg}.width`, 1, maxViewportWidth);
1786
+ this.validateProtocolInteger(viewportArg.height, `${nameArg}.height`, 1, maxViewportHeight);
1787
+ this.validateProtocolNumber(viewportArg.deviceScaleFactor, `${nameArg}.deviceScaleFactor`, true);
1788
+ if (viewportArg.deviceScaleFactor > maxDeviceScaleFactor) {
1789
+ throw new LiveBrowserFrameProtocolError(`${nameArg}.deviceScaleFactor must not exceed ${maxDeviceScaleFactor}`);
1790
+ }
1791
+ const physicalArea = viewportArg.width
1792
+ * viewportArg.height
1793
+ * viewportArg.deviceScaleFactor
1794
+ * viewportArg.deviceScaleFactor;
1795
+ if (physicalArea > maxFramePixelArea) {
1796
+ throw new LiveBrowserFrameProtocolError(`${nameArg} physical pixel area must not exceed ${maxFramePixelArea}`);
1797
+ }
1798
+ }
1799
+ validateProtocolInteger(valueArg, nameArg, minimumArg, maximumArg = Number.MAX_SAFE_INTEGER) {
1800
+ if (!Number.isSafeInteger(valueArg)
1801
+ || valueArg < minimumArg
1802
+ || valueArg > maximumArg) {
1803
+ throw new LiveBrowserFrameProtocolError(`${nameArg} must be an integer between ${minimumArg} and ${maximumArg}`);
1804
+ }
1805
+ }
1806
+ validateProtocolNumber(valueArg, nameArg, positiveArg = false) {
1807
+ if (!Number.isFinite(valueArg) || (positiveArg && valueArg <= 0)) {
1808
+ throw new LiveBrowserFrameProtocolError(`${nameArg} must be a ${positiveArg ? 'positive ' : ''}finite number`);
1809
+ }
1810
+ }
1811
+ releasePointerCapture(pointerIdArg) {
1812
+ this.capturedPointerIds.delete(pointerIdArg);
1813
+ try {
1814
+ if (this.canvas.hasPointerCapture(pointerIdArg)) {
1815
+ this.canvas.releasePointerCapture(pointerIdArg);
1816
+ }
1817
+ }
1818
+ catch {
1819
+ // Pointer capture may already have been released by the browser.
1820
+ }
1821
+ }
1822
+ releasePointerCaptures() {
1823
+ const pointerIds = [...this.capturedPointerIds];
1824
+ this.capturedPointerIds.clear();
1825
+ for (const pointerId of pointerIds) {
1826
+ this.releasePointerCapture(pointerId);
1827
+ }
1828
+ }
1829
+ }
1830
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5saXZlYnJvd3NlcnJlbmRlcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViL2NsYXNzZXMubGl2ZWJyb3dzZXJyZW5kZXJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFvQkEsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFHakYsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLENBQUM7QUFDaEMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLENBQUM7QUFDbkMsTUFBTSw0QkFBNEIsR0FBRyxFQUFFLENBQUM7QUFDeEMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDO0FBQzlCLE1BQU0sd0JBQXdCLEdBQUcsRUFBRSxDQUFDO0FBQ3BDLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO0FBQzdCLE1BQU0sMEJBQTBCLEdBQUcsRUFBRSxDQUFDO0FBQ3RDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDO0FBQ2hDLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDO0FBQ2xDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7QUFDOUIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUM7QUFDL0IsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUM7QUFDbEMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFDL0IsTUFBTSxtQkFBbUIsR0FBRyxLQUFLLENBQUM7QUFDbEMsTUFBTSx5QkFBeUIsR0FBRyxLQUFLLENBQUM7QUFFeEMsTUFBTSxnQ0FBaUMsU0FBUSxLQUFLO0NBQUc7QUFDdkQsTUFBTSwwQkFBMkIsU0FBUSxLQUFLO0NBQUc7QUFDakQsTUFBTSw2QkFBOEIsU0FBUSxLQUFLO0NBQUc7QUFDcEQsTUFBTSw4QkFBK0Is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