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