@livedesk/hub 0.1.71 → 0.1.72

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/hub",
3
- "version": "0.1.71",
3
+ "version": "0.1.72",
4
4
  "description": "VuvoDesk local Hub API and browser frame bridge",
5
5
  "type": "module",
6
6
  "main": "src/server.js",
@@ -1343,7 +1343,11 @@ export function createHubConsoleDirect(options = {}) {
1343
1343
  iceTransportPolicy: 'all',
1344
1344
  disableAutoNegotiation: false,
1345
1345
  disableFingerprintVerification: false,
1346
- maxMessageSize: MAX_FRAME_MESSAGE_BYTES
1346
+ // Each native send is one wire chunk. libdatachannel also uses this
1347
+ // setting as the minimum SCTP socket buffer size, below bufferedAmount.
1348
+ // A whole-frame limit here hides megabytes from our admission gate.
1349
+ // Complete frame/HTTP limits remain enforced by the wire assemblers.
1350
+ maxMessageSize: DIRECT_CONSOLE_WIRE_CHUNK_BYTES
1347
1351
  });
1348
1352
  } catch (error) {
1349
1353
  lastError = error instanceof Error ? error.message : String(error);
@@ -4,6 +4,7 @@ import { readFileSync } from 'node:fs';
4
4
  import test from 'node:test';
5
5
  import nodeDataChannel from 'node-datachannel';
6
6
  import {
7
+ DIRECT_CONSOLE_WIRE_CHUNK_BYTES,
7
8
  createDirectConsoleWireAssembler,
8
9
  encodeDirectConsoleWireMessage
9
10
  } from '../../runtime-core/src/console-direct-wire.js';
@@ -358,6 +359,8 @@ test('STUN-only peer answers and rejects stale owner callbacks after replacement
358
359
  assert.deepEqual(firstPeer.config.iceServers, ['stun:stun.example.test:3478']);
359
360
  assert.equal(firstPeer.config.iceTransportPolicy, 'all');
360
361
  assert.equal(firstPeer.config.disableFingerprintVerification, false);
362
+ assert.equal(firstPeer.config.maxMessageSize, DIRECT_CONSOLE_WIRE_CHUNK_BYTES,
363
+ 'native SCTP accepts wire chunks, not whole frames; a frame-sized setting silently enlarges its hidden buffers');
361
364
  assert.equal(signalingMessages(signal).some(message => (
362
365
  message.type === 'rtc-answer' && message.connectionId === CONNECTION_ONE
363
366
  )), true);
@@ -1566,18 +1569,19 @@ test('server session refresh preserves peers while logout uses the revoking clos
1566
1569
  assert.doesNotMatch(logoutBlock, /hubConsoleDirect\?\.refresh\(\)/);
1567
1570
  });
1568
1571
 
1569
- test('native node-datachannel buffered sends deliver the complete fragmented wire over loopback', { timeout: 8_000 }, async t => {
1572
+ test('native chunk-sized SCTP accepts a full-size fragmented frame over loopback', { timeout: 8_000 }, async t => {
1570
1573
  let offerer = null;
1571
1574
  let answerer = null;
1572
1575
  let offerChannel = null;
1573
1576
  let answerChannel = null;
1574
- const assembler = createDirectConsoleWireAssembler();
1577
+ const assembler = createDirectConsoleWireAssembler({ maxMessageBytes: consoleDirectContract.maxFrameMessageBytes });
1575
1578
  let openTimer = null;
1576
1579
  let messageTimer = null;
1577
1580
  try {
1578
1581
  nodeDataChannel.setSctpSettings({ sendBufferSize: 64 * 1024 });
1579
- offerer = new nodeDataChannel.PeerConnection('console-direct-native-offerer', { iceServers: [] });
1580
- answerer = new nodeDataChannel.PeerConnection('console-direct-native-answerer', { iceServers: [] });
1582
+ const config = { iceServers: [], maxMessageSize: DIRECT_CONSOLE_WIRE_CHUNK_BYTES };
1583
+ offerer = new nodeDataChannel.PeerConnection('console-direct-native-offerer', config);
1584
+ answerer = new nodeDataChannel.PeerConnection('console-direct-native-answerer', config);
1581
1585
  offerer.onLocalDescription((sdp, type) => {
1582
1586
  answerer.setRemoteDescription(sdp, type);
1583
1587
  });
@@ -1611,11 +1615,16 @@ test('native node-datachannel buffered sends deliver the complete fragmented wir
1611
1615
  await opened;
1612
1616
  clearTimeout(openTimer);
1613
1617
  openTimer = null;
1614
- const payload = JSON.stringify({ type: 'direct-ready', connectionId: CONNECTION_ONE, hubEpoch: HUB_EPOCH });
1615
- const expected = payload.repeat(20_000);
1618
+ assert.match(offerer.localDescription().sdp, /a=max-message-size:16384(?:\r?\n|$)/);
1619
+ assert.match(answerer.localDescription().sdp, /a=max-message-size:16384(?:\r?\n|$)/);
1620
+ assert.throws(() => offerChannel.sendMessageBinary(Buffer.alloc(DIRECT_CONSOLE_WIRE_CHUNK_BYTES + 1)),
1621
+ /[Mm]essage.*large|[Ss]ize/);
1622
+ const expected = Buffer.alloc(consoleDirectContract.maxFrameMessageBytes);
1623
+ for (let n = 0; n < expected.length; n += 1) expected[n] = n % 251;
1616
1624
  const chunks = encodeDirectConsoleWireMessage(expected, {
1617
1625
  messageId: 77,
1618
- kind: 'control'
1626
+ kind: 'binary',
1627
+ maxMessageBytes: consoleDirectContract.maxFrameMessageBytes
1619
1628
  });
1620
1629
  assert.ok(chunks.length > 1);
1621
1630
  let bufferedSends = 0;
@@ -1626,8 +1635,8 @@ test('native node-datachannel buffered sends deliver the complete fragmented wir
1626
1635
  const message = await received;
1627
1636
  clearTimeout(messageTimer);
1628
1637
  messageTimer = null;
1629
- assert.equal(message.kind, 'control');
1630
- assert.equal(message.data, expected);
1638
+ assert.equal(message.kind, 'binary');
1639
+ assert.deepEqual(Buffer.from(message.data), expected);
1631
1640
  t.diagnostic(`native buffered sends=${bufferedSends}; complete bytes=${message.byteLength}; chunks=${chunks.length}`);
1632
1641
  } finally {
1633
1642
  if (openTimer) clearTimeout(openTimer);