livekit-client 2.20.2 → 2.21.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.
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +4 -0
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +1993 -791
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.fm.worker.js +1 -1
- package/dist/livekit-client.fm.worker.js.map +1 -1
- package/dist/livekit-client.fm.worker.mjs +4 -0
- package/dist/livekit-client.fm.worker.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +28 -64
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +4 -0
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/data-channel/DataChannelManager.d.ts +62 -0
- package/dist/src/room/data-channel/DataChannelManager.d.ts.map +1 -0
- package/dist/src/room/data-channel/FlowControlledDataChannel.d.ts +95 -0
- package/dist/src/room/data-channel/FlowControlledDataChannel.d.ts.map +1 -0
- package/dist/src/room/data-channel/LossyDataChannel.d.ts +40 -0
- package/dist/src/room/data-channel/LossyDataChannel.d.ts.map +1 -0
- package/dist/src/room/data-channel/ReliableDataChannel.d.ts +56 -0
- package/dist/src/room/data-channel/ReliableDataChannel.d.ts.map +1 -0
- package/dist/src/room/data-channel/types.d.ts +12 -0
- package/dist/src/room/data-channel/types.d.ts.map +1 -0
- package/dist/src/room/data-stream/compression.d.ts +49 -0
- package/dist/src/room/data-stream/compression.d.ts.map +1 -0
- package/dist/src/room/data-stream/constants.d.ts +18 -0
- package/dist/src/room/data-stream/constants.d.ts.map +1 -0
- package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts +4 -0
- package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts.map +1 -1
- package/dist/src/room/data-stream/incoming/StreamReader.d.ts.map +1 -1
- package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts +49 -2
- package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts.map +1 -1
- package/dist/src/room/data-stream/outgoing/header-utils.d.ts +18 -0
- package/dist/src/room/data-stream/outgoing/header-utils.d.ts.map +1 -0
- package/dist/src/room/errors.d.ts +3 -1
- package/dist/src/room/errors.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +9 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +11 -2
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/rpc/client/RpcClientManager.d.ts.map +1 -1
- package/dist/src/room/rpc/server/RpcServerManager.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +17 -0
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +13 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/version.d.ts +5 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/ts4.2/index.d.ts +1 -1
- package/dist/ts4.2/room/RTCEngine.d.ts +28 -64
- package/dist/ts4.2/room/Room.d.ts +4 -0
- package/dist/ts4.2/room/data-channel/DataChannelManager.d.ts +62 -0
- package/dist/ts4.2/room/data-channel/FlowControlledDataChannel.d.ts +95 -0
- package/dist/ts4.2/room/data-channel/LossyDataChannel.d.ts +41 -0
- package/dist/ts4.2/room/data-channel/ReliableDataChannel.d.ts +57 -0
- package/dist/ts4.2/room/data-channel/types.d.ts +12 -0
- package/dist/ts4.2/room/data-stream/compression.d.ts +49 -0
- package/dist/ts4.2/room/data-stream/constants.d.ts +18 -0
- package/dist/ts4.2/room/data-stream/incoming/IncomingDataStreamManager.d.ts +4 -0
- package/dist/ts4.2/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts +49 -2
- package/dist/ts4.2/room/data-stream/outgoing/header-utils.d.ts +18 -0
- package/dist/ts4.2/room/errors.d.ts +3 -1
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +9 -1
- package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +11 -1
- package/dist/ts4.2/room/types.d.ts +17 -0
- package/dist/ts4.2/room/utils.d.ts +13 -0
- package/dist/ts4.2/version.d.ts +5 -1
- package/package.json +2 -2
- package/src/index.ts +2 -0
- package/src/room/RTCEngine.test.ts +58 -99
- package/src/room/RTCEngine.ts +92 -534
- package/src/room/Room.test.ts +4 -1
- package/src/room/Room.ts +40 -8
- package/src/room/data-channel/DataChannelManager.test.ts +152 -0
- package/src/room/data-channel/DataChannelManager.ts +237 -0
- package/src/room/data-channel/FlowControlledDataChannel.test.ts +154 -0
- package/src/room/data-channel/FlowControlledDataChannel.ts +216 -0
- package/src/room/data-channel/LossyDataChannel.test.ts +118 -0
- package/src/room/data-channel/LossyDataChannel.ts +125 -0
- package/src/room/data-channel/ReliableDataChannel.test.ts +158 -0
- package/src/room/data-channel/ReliableDataChannel.ts +153 -0
- package/src/room/data-channel/types.ts +30 -0
- package/src/room/data-stream/compression.ts +117 -0
- package/src/room/data-stream/constants.ts +18 -0
- package/src/room/data-stream/incoming/IncomingDataStreamManager.test.ts +1601 -0
- package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +438 -86
- package/src/room/data-stream/incoming/StreamReader.ts +8 -2
- package/src/room/data-stream/outgoing/OutgoingDataStreamManager.test.ts +1292 -0
- package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +489 -116
- package/src/room/data-stream/outgoing/header-utils.ts +87 -0
- package/src/room/errors.ts +6 -0
- package/src/room/participant/LocalParticipant.ts +13 -0
- package/src/room/participant/RemoteParticipant.ts +19 -5
- package/src/room/rpc/client/RpcClientManager.test.ts +20 -27
- package/src/room/rpc/client/RpcClientManager.ts +1 -4
- package/src/room/rpc/server/RpcServerManager.test.ts +24 -23
- package/src/room/rpc/server/RpcServerManager.ts +1 -3
- package/src/room/types.ts +18 -0
- package/src/room/utils.ts +67 -0
- package/src/version.ts +5 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataPacket, DataPacket_Kind, UserPacket } from '@livekit/protocol';
|
|
2
2
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import type { DataPacketBuffer
|
|
3
|
+
import type { DataPacketBuffer } from '../utils/dataPacketBuffer';
|
|
4
4
|
import RTCEngine, { DataChannelKind } from './RTCEngine';
|
|
5
5
|
import { roomOptionDefaults } from './defaults';
|
|
6
6
|
import { PublishDataError, UnexpectedConnectionState } from './errors';
|
|
@@ -228,17 +228,16 @@ describe('RTCEngine', () => {
|
|
|
228
228
|
engine: RTCEngine,
|
|
229
229
|
maxDataPacketSize: number = MAX_DATA_PACKET_SIZE,
|
|
230
230
|
) {
|
|
231
|
-
const
|
|
231
|
+
const dc = new FakeDataChannel();
|
|
232
232
|
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
233
|
+
_isClosed: false,
|
|
233
234
|
ensurePublisherConnected: vi.fn().mockResolvedValue(undefined),
|
|
234
|
-
waitForBufferHeadroomWithLock: vi.fn().mockResolvedValue(undefined),
|
|
235
|
-
updateAndEmitDCBufferStatus: vi.fn(),
|
|
236
|
-
dataChannelForKind: vi.fn(() => ({ send })),
|
|
237
235
|
pcManager: {
|
|
238
236
|
getMaxPublisherMessageSize: vi.fn(() => maxDataPacketSize),
|
|
239
237
|
},
|
|
240
238
|
});
|
|
241
|
-
|
|
239
|
+
attachFakeChannel(engine, 'reliableChannel', dc);
|
|
240
|
+
return dc.send;
|
|
242
241
|
}
|
|
243
242
|
|
|
244
243
|
it('rejects packets larger than the max data packet size', async () => {
|
|
@@ -309,6 +308,23 @@ describe('RTCEngine', () => {
|
|
|
309
308
|
|
|
310
309
|
const tick = () => new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
311
310
|
|
|
311
|
+
/** The reliable channel's private replay buffer — reached through casts, as tests do for engine privates. */
|
|
312
|
+
const reliableBuffer = (engine: RTCEngine) =>
|
|
313
|
+
(engine as unknown as { reliableChannel: { messageBuffer: DataPacketBuffer } }).reliableChannel
|
|
314
|
+
.messageBuffer;
|
|
315
|
+
|
|
316
|
+
type ChannelField = 'reliableChannel' | 'lossyChannel' | 'dataTrackChannel';
|
|
317
|
+
const engineChannel = (engine: RTCEngine, field: ChannelField) =>
|
|
318
|
+
(
|
|
319
|
+
engine as unknown as Record<
|
|
320
|
+
ChannelField,
|
|
321
|
+
{ attach(dc: RTCDataChannel): void; invalidateWaiters(reason: string): void }
|
|
322
|
+
>
|
|
323
|
+
)[field];
|
|
324
|
+
/** Attach a fake handle to one of the engine's flow-control wrappers. */
|
|
325
|
+
const attachFakeChannel = (engine: RTCEngine, field: ChannelField, dc: FakeDataChannel) =>
|
|
326
|
+
engineChannel(engine, field).attach(dc as unknown as RTCDataChannel);
|
|
327
|
+
|
|
312
328
|
describe('resendReliableMessagesForResume', () => {
|
|
313
329
|
it('does not let a concurrent reliable send interleave into the resume replay', async () => {
|
|
314
330
|
const engine = new RTCEngine(roomOptionDefaults);
|
|
@@ -316,18 +332,17 @@ describe('RTCEngine', () => {
|
|
|
316
332
|
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
317
333
|
_isClosed: false,
|
|
318
334
|
ensurePublisherConnected: vi.fn().mockResolvedValue(undefined),
|
|
319
|
-
dataChannelForKind: vi.fn(() => dc),
|
|
320
335
|
pcManager: {
|
|
321
336
|
getMaxPublisherMessageSize: vi.fn(() => 64 * 1024 - 1),
|
|
322
337
|
},
|
|
323
338
|
});
|
|
339
|
+
attachFakeChannel(engine, 'reliableChannel', dc);
|
|
324
340
|
|
|
325
|
-
// Two messages queued for replay, and a full buffer so the
|
|
341
|
+
// Two messages queued for replay, and a full buffer so the replay parks on
|
|
342
|
+
// waitForBufferHeadroom before its first send.
|
|
326
343
|
const replayed1 = new Uint8Array([1]);
|
|
327
344
|
const replayed2 = new Uint8Array([2]);
|
|
328
|
-
const buffer = (
|
|
329
|
-
engine as unknown as { reliableMessageBuffer: { push: (item: DataPacketItem) => void } }
|
|
330
|
-
).reliableMessageBuffer;
|
|
345
|
+
const buffer = reliableBuffer(engine);
|
|
331
346
|
buffer.push({ data: replayed1, sequence: 1, sent: true });
|
|
332
347
|
buffer.push({ data: replayed2, sequence: 2, sent: true });
|
|
333
348
|
dc.bufferedAmount = 2 * 1024 * 1024; // above the reliable high-water mark
|
|
@@ -359,59 +374,6 @@ describe('RTCEngine', () => {
|
|
|
359
374
|
expect(dc.send.mock.calls[2][0]).not.toBe(replayed1);
|
|
360
375
|
expect(dc.send.mock.calls[2][0]).not.toBe(replayed2);
|
|
361
376
|
});
|
|
362
|
-
|
|
363
|
-
it('transmits a packet deferred mid-replay instead of marking it sent without sending', async () => {
|
|
364
|
-
const engine = new RTCEngine(roomOptionDefaults);
|
|
365
|
-
const dc = new FakeDataChannel();
|
|
366
|
-
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
367
|
-
_isClosed: false,
|
|
368
|
-
// Reconnect still active: a send arriving during replay takes the deferral path.
|
|
369
|
-
attemptingReconnect: true,
|
|
370
|
-
ensurePublisherConnected: vi.fn().mockResolvedValue(undefined),
|
|
371
|
-
dataChannelForKind: vi.fn(() => dc),
|
|
372
|
-
pcManager: {
|
|
373
|
-
getMaxPublisherMessageSize: vi.fn(() => 64 * 1024 - 1),
|
|
374
|
-
},
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
const buffer = (engine as unknown as { reliableMessageBuffer: DataPacketBuffer })
|
|
378
|
-
.reliableMessageBuffer;
|
|
379
|
-
const replayed = new Uint8Array([1]);
|
|
380
|
-
buffer.push({ data: replayed, sequence: 1, sent: true });
|
|
381
|
-
// Full buffer so replay parks on waitForBufferHeadroomWithLock before its first send.
|
|
382
|
-
dc.bufferedAmount = 2 * 1024 * 1024;
|
|
383
|
-
|
|
384
|
-
const replay = (
|
|
385
|
-
engine as unknown as { resendReliableMessagesForResume: (seq: number) => Promise<void> }
|
|
386
|
-
).resendReliableMessagesForResume(0);
|
|
387
|
-
await tick();
|
|
388
|
-
|
|
389
|
-
// A reliable send arrives while replay is parked; attemptingReconnect defers it into the
|
|
390
|
-
// buffer as sent:false, after the replay's first drain pass already started.
|
|
391
|
-
const deferred = new Uint8Array([2]);
|
|
392
|
-
const deferredSend = engine.sendDataPacket(
|
|
393
|
-
new DataPacket({
|
|
394
|
-
kind: DataPacket_Kind.RELIABLE,
|
|
395
|
-
value: { case: 'user', value: new UserPacket({ payload: deferred }) },
|
|
396
|
-
}),
|
|
397
|
-
DataChannelKind.RELIABLE,
|
|
398
|
-
);
|
|
399
|
-
await tick();
|
|
400
|
-
|
|
401
|
-
dc.bufferedAmount = 0;
|
|
402
|
-
dc.dispatchEvent(new Event('bufferedamountlow'));
|
|
403
|
-
await Promise.all([replay, deferredSend]);
|
|
404
|
-
|
|
405
|
-
// Pre-fix, replay sends only its snapshot ([replayed]) and blanket-marks the deferred packet
|
|
406
|
-
// sent without ever transmitting it — one send. The drain loop must transmit both (the
|
|
407
|
-
// deferred packet is serialized through sendDataPacket, so it's distinct from `replayed`),
|
|
408
|
-
// leaving nothing unsent for a later align to strand.
|
|
409
|
-
const sent = dc.send.mock.calls.map(([d]) => d);
|
|
410
|
-
expect(sent).toHaveLength(2);
|
|
411
|
-
expect(sent[0]).toBe(replayed);
|
|
412
|
-
expect(sent[1]).not.toBe(replayed);
|
|
413
|
-
expect(buffer.getUnsent()).toHaveLength(0);
|
|
414
|
-
});
|
|
415
377
|
});
|
|
416
378
|
|
|
417
379
|
describe('reliable sends during teardown windows', () => {
|
|
@@ -425,13 +387,12 @@ describe('RTCEngine', () => {
|
|
|
425
387
|
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
426
388
|
_isClosed: false,
|
|
427
389
|
ensurePublisherConnected: vi.fn().mockResolvedValue(undefined),
|
|
428
|
-
dataChannelForKind: vi.fn(() => dc),
|
|
429
390
|
pcManager: {
|
|
430
391
|
getMaxPublisherMessageSize: vi.fn(() => 64 * 1024 - 1),
|
|
431
392
|
},
|
|
432
393
|
});
|
|
433
|
-
|
|
434
|
-
|
|
394
|
+
attachFakeChannel(engine, 'reliableChannel', dc);
|
|
395
|
+
return reliableBuffer(engine);
|
|
435
396
|
}
|
|
436
397
|
|
|
437
398
|
it('resolves and queues the packet for replay when the wait is torn down transiently', async () => {
|
|
@@ -443,9 +404,7 @@ describe('RTCEngine', () => {
|
|
|
443
404
|
dc.bufferedAmount = 2 * 1024 * 1024;
|
|
444
405
|
const send = engine.sendDataPacket(makePacket(1), DataChannelKind.RELIABLE);
|
|
445
406
|
await tick();
|
|
446
|
-
(
|
|
447
|
-
engine as unknown as { invalidateDataChannelWaiters: (reason: string) => void }
|
|
448
|
-
).invalidateDataChannelWaiters('data channels recreated');
|
|
407
|
+
engineChannel(engine, 'reliableChannel').invalidateWaiters('data channels recreated');
|
|
449
408
|
|
|
450
409
|
// The send must not surface the teardown — the packet is queued for the resume replay.
|
|
451
410
|
await expect(send).resolves.toBeUndefined();
|
|
@@ -471,9 +430,7 @@ describe('RTCEngine', () => {
|
|
|
471
430
|
const send = engine.sendDataPacket(makePacket(1), DataChannelKind.RELIABLE);
|
|
472
431
|
await tick();
|
|
473
432
|
Object.assign(engine as unknown as Record<string, unknown>, { _isClosed: true });
|
|
474
|
-
(
|
|
475
|
-
engine as unknown as { invalidateDataChannelWaiters: (reason: string) => void }
|
|
476
|
-
).invalidateDataChannelWaiters('engine closed');
|
|
433
|
+
engineChannel(engine, 'reliableChannel').invalidateWaiters('engine closed');
|
|
477
434
|
|
|
478
435
|
await expect(send).rejects.toBeInstanceOf(UnexpectedConnectionState);
|
|
479
436
|
expect(dc.send).not.toHaveBeenCalled();
|
|
@@ -496,78 +453,80 @@ describe('RTCEngine', () => {
|
|
|
496
453
|
});
|
|
497
454
|
});
|
|
498
455
|
|
|
499
|
-
describe('
|
|
456
|
+
describe('sendDataTrackFrame', () => {
|
|
500
457
|
it('ensures the publisher is connected before sending (direct data-track path)', async () => {
|
|
501
458
|
const engine = new RTCEngine(roomOptionDefaults);
|
|
502
459
|
const dc = new FakeDataChannel();
|
|
503
460
|
// The channel only becomes available once the publisher connection has been established —
|
|
504
461
|
// mirroring the lazily negotiated publisher case that Room's packetAvailable path hits.
|
|
505
|
-
let connected = false;
|
|
506
462
|
const ensurePublisherConnected = vi.fn(async () => {
|
|
507
|
-
|
|
463
|
+
attachFakeChannel(engine, 'dataTrackChannel', dc);
|
|
508
464
|
});
|
|
509
465
|
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
510
466
|
_isClosed: false,
|
|
511
467
|
ensurePublisherConnected,
|
|
512
|
-
dataChannelForKind: vi.fn(() => (connected ? dc : undefined)),
|
|
513
468
|
});
|
|
514
469
|
|
|
515
|
-
await engine.
|
|
470
|
+
await engine.sendDataTrackFrame(new Uint8Array([1]));
|
|
516
471
|
|
|
517
472
|
expect(ensurePublisherConnected).toHaveBeenCalledWith(DataChannelKind.DATA_TRACK_LOSSY);
|
|
518
473
|
expect(dc.send).toHaveBeenCalledTimes(1);
|
|
519
474
|
});
|
|
520
475
|
|
|
521
|
-
it('
|
|
476
|
+
it('keeps each channel’s byterate stat isolated from the other’s traffic', async () => {
|
|
522
477
|
const engine = new RTCEngine(roomOptionDefaults);
|
|
523
478
|
const dc = new FakeDataChannel();
|
|
524
479
|
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
525
480
|
_isClosed: false,
|
|
526
481
|
ensurePublisherConnected: vi.fn().mockResolvedValue(undefined),
|
|
527
|
-
dataChannelForKind: vi.fn(() => dc),
|
|
528
482
|
});
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
483
|
+
attachFakeChannel(engine, 'lossyChannel', dc);
|
|
484
|
+
attachFakeChannel(engine, 'dataTrackChannel', dc);
|
|
485
|
+
const lossyStat = () =>
|
|
486
|
+
(engine as unknown as { lossyChannel: { statCurrentBytes: number } }).lossyChannel
|
|
487
|
+
.statCurrentBytes;
|
|
488
|
+
|
|
489
|
+
// Data-track traffic (sendDataTrackFrame → data-track channel) must not move the LOSSY channel's
|
|
490
|
+
// stat — it would inflate the lossy channel's dynamically tuned drop threshold with traffic
|
|
491
|
+
// that channel never carries.
|
|
492
|
+
await engine.sendDataTrackFrame(new Uint8Array(1000));
|
|
493
|
+
expect(lossyStat()).toBe(0);
|
|
494
|
+
|
|
495
|
+
// A plain lossy publishData packet goes through sendDataPacket → lossy channel.
|
|
496
|
+
const lossyPacket = new DataPacket({
|
|
497
|
+
kind: DataPacket_Kind.LOSSY,
|
|
498
|
+
value: { case: 'user', value: new UserPacket({ payload: new Uint8Array(100) }) },
|
|
499
|
+
});
|
|
500
|
+
await engine.sendDataPacket(lossyPacket, DataChannelKind.LOSSY);
|
|
501
|
+
expect(lossyStat()).toBeGreaterThan(0);
|
|
539
502
|
});
|
|
540
503
|
});
|
|
541
504
|
|
|
542
|
-
describe('
|
|
505
|
+
describe('waitForBufferHeadroom', () => {
|
|
543
506
|
it('rejects parked waiters and releases the lock when the data channels are invalidated', async () => {
|
|
544
507
|
const engine = new RTCEngine(roomOptionDefaults);
|
|
545
508
|
const dc = new FakeDataChannel();
|
|
546
509
|
Object.assign(engine as unknown as Record<string, unknown>, {
|
|
547
510
|
_isClosed: false,
|
|
548
|
-
dataChannelForKind: vi.fn(() => dc),
|
|
549
511
|
});
|
|
512
|
+
attachFakeChannel(engine, 'reliableChannel', dc);
|
|
550
513
|
|
|
551
514
|
// Park a waiter: buffer above the reliable high-water mark, holding the headroom lock.
|
|
552
515
|
dc.bufferedAmount = 2 * 1024 * 1024;
|
|
553
|
-
const parked = engine.
|
|
516
|
+
const parked = engine.waitForBufferHeadroom(DataChannelKind.RELIABLE);
|
|
554
517
|
// Swallow the expected rejection so it can't surface as unhandled before we assert on it.
|
|
555
518
|
parked.catch(() => {});
|
|
556
519
|
await tick();
|
|
557
520
|
|
|
558
521
|
// The channel object gets abandoned (e.g. createDataChannels on the Safari resume path).
|
|
559
|
-
(
|
|
560
|
-
engine as unknown as { invalidateDataChannelWaiters: (reason: string) => void }
|
|
561
|
-
).invalidateDataChannelWaiters('data channels recreated');
|
|
522
|
+
engineChannel(engine, 'reliableChannel').invalidateWaiters('data channels recreated');
|
|
562
523
|
|
|
563
524
|
await expect(parked).rejects.toBeInstanceOf(UnexpectedConnectionState);
|
|
564
525
|
|
|
565
526
|
// The lock must be free again: a wait against the fresh, drained channel resolves instead
|
|
566
527
|
// of queueing forever behind the stranded waiter.
|
|
567
528
|
dc.bufferedAmount = 0;
|
|
568
|
-
await expect(
|
|
569
|
-
engine.waitForBufferHeadroomWithLock(DataChannelKind.RELIABLE),
|
|
570
|
-
).resolves.toBeUndefined();
|
|
529
|
+
await expect(engine.waitForBufferHeadroom(DataChannelKind.RELIABLE)).resolves.toBeUndefined();
|
|
571
530
|
});
|
|
572
531
|
});
|
|
573
532
|
|