Blocks an incoming stream will hold unread before it starts withholding
acks. This is the receiver's half of the window: whatever the sender
keeps in flight, the effective count is the smaller of the two, with no
negotiation needed — the receiver simply stops acking. Per manager (so
per session) because an
Blocks in flight across every sending stream of this session — the fair scheduler's budget (design §5.2, item 3). Per manager because it is per session: it bounds what all the streams together put into the one XMPP connection. When it is full, freed slots go to the waiting streams in turn, one block each, so a stream that has been sending for a minute and one that just started alternate rather than queue. A stream's own window still applies; one larger than this is capped by it.
The accepting side of openDuplex(): waits for the peer's sid
and answers it with a stream we can also send on. Our sending half
adopts the peer's sid and block-size — it never sends an
Optionaloptions: DuplexOptions & { timeoutMs?: number }Announces that an sid from from (bare-JID matched) is
expected and returns the stream once it arrives. If the
timeoutMs bounds the wait for the idleTimeoutMs is the
stream's own watchdog afterwards. Both default to the manager's
idleTimeoutMs, which is what every stream used before either existed.
Optionaloptions: { idleTimeoutMs?: IbbIdleTimeout; timeoutMs?: number }Opens a stream that carries bytes both ways (design: one sid, two
directions, each with its own seq counter — XEP-0047's seq is per
sender). The inbound half is registered before the
There is no half-close: close() from either side ends both directions, which is what a CONNECT tunnel needs (TLS never half-closes).
Optionaloptions: DuplexOptions & { blockSize?: number; sid?: string }Optionaloptions: { blockSize?: number; from?: string; sid?: string; window?: number }
OptionalblockSize?: numberOptionalfrom?: stringOptionalsid?: stringOptionalwindow?: numberBlocks allowed in flight at once; the ack of block k releases block k+window. Default DEFAULT_IBB_WINDOW, clamped to [1, MAX_IBB_WINDOW]; a window of 1 is exactly the old block-at-a-time sender.
Per stream, never a manager field: one IbbManager is shared by the client, the server, sipub and jingle on a session, and a download's window is not an upload's.
StaticacquireOne manager per session: @xmpp/iq routes each (namespace, tag) pair to the first registered handler, so the IBB handlers must be singletons.
The shortest a block must go unanswered before it counts as parked at the receiver and stops holding a session slot; see DEFAULT_IBB_PARK_FLOOR_MS. The working threshold also scales with the measured ack latency, so a congested link (slow acks for everyone) keeps its fairness while a stalled consumer (one stream's acks withheld) does not freeze the rest.