On every websocket reconnect, FailoverProxy.connectWs's ws.onopen re-established subscriptions by calling the public subscribeToScript/LokadId/TokenId/Txid methods. Each of those pushes into this.subs before sending, but the subs were already recorded when the app first subscribed — so every reconnect appended a second copy of every subscription and re-sent a duplicate frame. Lists doubled per reconnect (2^N after N), and pause()/resume() is a reconnect.
Separately, that same replay never restored subs.plugins (plugin ws subs were added at 1.1.0, after the replay was written), so a plugin subscription went silent after the first reconnect with no error.
Fix: send-only WsEndpoint._resubscribeAll() that replays every sub kind — including plugins — via the private _subUnsub* senders (no re-push). The onopen replay becomes one call to it. Underscored and @internal: public only because failoverProxy.ts cannot call private methods.
Unit tests cover three _resubscribeAll reconnects (lists stay length 1, four script and four plugin frames) and pause/resume not growing this.subs. The websocket integration test asserts this.subs.scripts is still one entry after pause/resume.
Found building a downstream consumer (Stall, an Agora storefront) which carries regression tests for both halves and had to work around each.