Class: ReconnectingWsTransport
Defined in: src/channel/transport/reconnectingWs.ts:42
A WsTransport that replaces its socket instead of dying with it.
The policy here is the one WebSocketChannel has shipped since 10.6.8, relocated rather than
redesigned. In particular the split that makes reconnection safe is preserved exactly:
- a request that was never put on the wire is queued and sent once the connection is back, which cannot duplicate anything because the node never saw it;
- a request that was on the wire is rejected by the base class when the socket closes, and never replayed — only the caller knows whether resending it is safe.
Subscription restoration is not done here: the transport does not know what a subscription is.
It exposes onReconnected, awaited after the new connection opens and before the queue is
flushed, so a queued request cannot overtake the re-subscription it was queued behind.
This is the transport to build once at module scope and lend to everything that talks to the same node — one socket then serves them all, and it survives the drops a shared gateway imposes.
Example
const transport = new ReconnectingWsTransport({
nodeUrl: 'wss://your-starknet-node/rpc/v0_10',
});
const myProvider = new WebSocketProvider({ transport });
transport.on('statechange', () => console.log(transport.getState()));
Extends
Constructors
Constructor
new ReconnectingWsTransport(
options):ReconnectingWsTransport
Defined in: src/channel/transport/reconnectingWs.ts:78
Parameters
options
ReconnectingWsTransportOptions
Returns
ReconnectingWsTransport
Overrides
Properties
nodeUrl
readonlynodeUrl:string
Defined in: src/channel/transport/ws.ts:90
The URL of the WebSocket RPC node.
Inherited from
socket
socket:
WebSocket
Defined in: src/channel/transport/ws.ts:98
The underlying socket. Owned by this transport — close it through close().
Not readonly because a subclass may replace it on a reconnection. This class never does:
one WsTransport is one socket, which is what its own tests rely on.
Inherited from
WsImplementation
protectedreadonlyWsImplementation:WebSocketModule
Defined in: src/channel/transport/ws.ts:101
Kept so a subclass can build a replacement socket the same way this one was built.
Inherited from
Accessors
queuesRequests
Get Signature
get queuesRequests():
boolean
Defined in: src/channel/transport/reconnectingWs.ts:95
Whether a request made right now would be held for a reconnection rather than sent.
Exposed so the WebSocketChannel façade can reproduce the refusal its send() used to
raise: it refused only when nothing was going to pick the request up later.
Returns
boolean
Methods
onReconnected()
onReconnected(
hook): () =>void
Defined in: src/channel/transport/reconnectingWs.ts:105
Registers work to run after a reconnection opens, before the request queue is flushed.
Parameters
hook
() => Promise<void>
Returns
the unregister function.
() => void
onOpened()
protectedonOpened():void
Defined in: src/channel/transport/reconnectingWs.ts:112
What happens once a socket is open. Overridden by a reconnecting subclass, which also has a retry counter to reset and a queue to flush.
Returns
void
Overrides
onClosed()
protectedonClosed():void
Defined in: src/channel/transport/reconnectingWs.ts:133
What happens once a socket is gone. This class stays closed; a reconnecting subclass starts an attempt instead.
Returns
void
Overrides
onError()
protectedonError():void
Defined in: src/channel/transport/reconnectingWs.ts:146
What happens on a socket error. This class only logs; a reconnecting subclass treats it as a
failed attempt, because a refused connection may produce an error with no close behind it.
Returns
void
Overrides
request()
Call Signature
request(
body):Promise<ResponseBody>
Defined in: src/channel/transport/reconnectingWs.ts:234
Sends the envelope, queueing it when the connection is down. See RpcTransport.request for the contract every transport honours.
A queued call is never left pending: it goes out when the socket comes back, and rejects with
a WebSocketNotConnectedError if reconnection gives up or close is called. Note that
requestTimeout only starts once the request is on the wire, so the reconnection settings —
not requestTimeout — bound how long a queued call can wait.
Parameters
body
A request envelope, or an array of them for a batch.
Returns
Promise<ResponseBody>
The response envelope, or an array of them.
Overrides
Call Signature
request(
body):Promise<ResponseBody[]>
Defined in: src/channel/transport/reconnectingWs.ts:235
Sends the envelope, queueing it when the connection is down. See RpcTransport.request for the contract every transport honours.
A queued call is never left pending: it goes out when the socket comes back, and rejects with
a WebSocketNotConnectedError if reconnection gives up or close is called. Note that
requestTimeout only starts once the request is on the wire, so the reconnection settings —
not requestTimeout — bound how long a queued call can wait.
Parameters
body
A request envelope, or an array of them for a batch.
Returns
Promise<ResponseBody[]>
The response envelope, or an array of them.
Overrides
reconnect()
reconnect():
void
Defined in: src/channel/transport/reconnectingWs.ts:291
Manually opens a fresh connection, cancelling the effect of an earlier close().
Flagged as a reconnection so onOpened runs completeReconnection(): a manual reconnect owes
the caller exactly what an automatic one delivers — subscriptions restored first, then the
request queue flushed behind them. Without the flag the socket came back empty, which is the
React StrictMode path: mount, cleanup close(), remount reconnect(), subscriptions
silently lost.
Reporting 'reconnecting' rather than 'connecting' is the honest label, and it keeps
queuesRequests true for the gap, so a request issued before the socket opens is queued
instead of refused.
Returns
void
close()
close(
code?,reason?):void
Defined in: src/channel/transport/reconnectingWs.ts:307
Closes the socket for good, and stops the automatic reconnection with it.
Any request still queued is rejected rather than left waiting for a connection that is no longer coming. Call reconnect to start over afterwards.
Parameters
code?
number
WebSocket close code sent to the node.
reason?
string
Human-readable close reason sent to the node.
Returns
void
Overrides
swapSocket()
protectedswapSocket(next):void
Defined in: src/channel/transport/ws.ts:180
Adopts a replacement socket.
The readiness latch is discarded with the old socket: it records that that connection came up, and reusing it would let a request be written to a socket still handshaking.
Requests already on the wire are not settled here — handleClose has done that for the
socket that went away, since nothing on a dead socket can still be answered.
Parameters
next
WebSocket
Returns
void
Inherited from
setState()
protectedsetState(next):void
Defined in: src/channel/transport/ws.ts:284
Parameters
next
Returns
void
Inherited from
getState()
getState():
WsTransportState
Defined in: src/channel/transport/ws.ts:295
The current connection state. The getSnapshot half of the useSyncExternalStore pair.
Returns
Inherited from
isConnected()
isConnected():
boolean
Defined in: src/channel/transport/ws.ts:300
Whether the socket is open right now.
Returns
boolean
Inherited from
allocateRequestId()
allocateRequestId():
number
Defined in: src/channel/transport/ws.ts:312
Allocates the next wire id, starting at 0.
Exposed because a caller may write to the socket itself rather than through request —
WebSocketChannel.send() is fire-and-forget and correlates nothing. Drawing from this same
sequence is what stops such a write from colliding with a request this transport is
tracking, which would hand one caller the other's reply.
Returns
number
Inherited from
on()
on<
K>(event,listener): () =>void
Defined in: src/channel/transport/ws.ts:327
Subscribes to one of the transport's two streams.
'statechange' fires on every connection state transition; 'notification' fires for
every frame the node pushes on its own.
Type Parameters
K
K extends keyof WsTransportEvents
Parameters
event
K
listener
(payload) => void
Returns
the unsubscribe function, which is what useSyncExternalStore requires of its
subscribe argument.
() => void
Inherited from
rejectPending()
protectedrejectPending(reason):void
Defined in: src/channel/transport/ws.ts:482
Fails every request still on the wire.
Their only other exit is the requestTimeout timer, so without this the caller waits the
whole timeout — 60s by default — for a reply that can no longer arrive, and that pending
timer keeps the Node event loop alive for just as long.
Parameters
reason
string
Returns
void