starknet 10.6.5 → 10.6.7
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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.global.js +81 -25
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +81 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +81 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [10.6.7](https://github.com/starknet-io/starknet.js/compare/v10.6.6...v10.6.7) (2026-08-06)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **ws:** settle in-flight requests when the connection drops ([8eae9c9](https://github.com/starknet-io/starknet.js/commit/8eae9c9457befe6e0c3f4fd30a56025fe5455fd8))
|
|
6
|
+
|
|
7
|
+
## [10.6.6](https://github.com/starknet-io/starknet.js/compare/v10.6.5...v10.6.6) (2026-08-05)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **ws:** reject queued requests instead of hanging ([82ced97](https://github.com/starknet-io/starknet.js/commit/82ced97dc6dc409131bc5650db076efedf467101))
|
|
12
|
+
|
|
1
13
|
## [10.6.5](https://github.com/starknet-io/starknet.js/compare/v10.6.4...v10.6.5) (2026-08-05)
|
|
2
14
|
|
|
3
15
|
### Bug Fixes
|
package/dist/index.d.ts
CHANGED
|
@@ -5151,6 +5151,8 @@ declare class WebSocketChannel {
|
|
|
5151
5151
|
private reconnectTimeoutId;
|
|
5152
5152
|
private reconnectStabilityTimeoutId;
|
|
5153
5153
|
private requestQueue;
|
|
5154
|
+
/** Abort handles for the requests currently on the wire, one per pending `sendReceive`. */
|
|
5155
|
+
private inFlight;
|
|
5154
5156
|
private events;
|
|
5155
5157
|
private openListener;
|
|
5156
5158
|
private closeListener;
|
|
@@ -5243,6 +5245,25 @@ declare class WebSocketChannel {
|
|
|
5243
5245
|
*/
|
|
5244
5246
|
reconnect(): void;
|
|
5245
5247
|
private _processRequestQueue;
|
|
5248
|
+
/**
|
|
5249
|
+
* Reject every request still waiting in the queue.
|
|
5250
|
+
*
|
|
5251
|
+
* A queued request carries no timeout of its own: the `requestTimeout` timer is only
|
|
5252
|
+
* armed once the request is actually put on the wire. So once the channel reaches a state
|
|
5253
|
+
* where the queue can never be flushed — reconnection gave up, or the user closed the
|
|
5254
|
+
* connection — the queued promises would stay pending forever, and no caller-side timeout
|
|
5255
|
+
* could rescue them. Settling them here is the only way out.
|
|
5256
|
+
*/
|
|
5257
|
+
private _rejectRequestQueue;
|
|
5258
|
+
/**
|
|
5259
|
+
* Settle every request already on the wire.
|
|
5260
|
+
*
|
|
5261
|
+
* The counterpart of `_rejectRequestQueue`, for requests past the queue. Their only other
|
|
5262
|
+
* exit is the `requestTimeout` timer, so without this the caller waits the whole timeout —
|
|
5263
|
+
* 60s by default — for a reply that can no longer arrive, and that pending timer keeps the
|
|
5264
|
+
* Node event loop alive for just as long.
|
|
5265
|
+
*/
|
|
5266
|
+
private _rejectInFlight;
|
|
5246
5267
|
private _restoreSubscriptions;
|
|
5247
5268
|
/**
|
|
5248
5269
|
* Reset the reconnection attempt counter, but only once the current connection has
|
package/dist/index.global.js
CHANGED
|
@@ -12618,6 +12618,8 @@ ${indent}}` : "}";
|
|
|
12618
12618
|
// resetting the reconnection attempt counter.
|
|
12619
12619
|
reconnectStabilityTimeoutId = null;
|
|
12620
12620
|
requestQueue = [];
|
|
12621
|
+
/** Abort handles for the requests currently on the wire, one per pending `sendReceive`. */
|
|
12622
|
+
inFlight = /* @__PURE__ */ new Set();
|
|
12621
12623
|
events = new EventEmitter();
|
|
12622
12624
|
openListener = (ev) => {
|
|
12623
12625
|
this.scheduleReconnectAttemptsReset();
|
|
@@ -12701,12 +12703,19 @@ ${indent}}` : "}";
|
|
|
12701
12703
|
});
|
|
12702
12704
|
}
|
|
12703
12705
|
const sendId = this.send(method, params);
|
|
12706
|
+
const socket = this.websocket;
|
|
12704
12707
|
return new Promise((resolve, reject) => {
|
|
12705
|
-
|
|
12706
|
-
if (!this.websocket || this.websocket.readyState !== ws_default.OPEN) {
|
|
12708
|
+
if (socket.readyState !== ws_default.OPEN) {
|
|
12707
12709
|
reject(new WebSocketNotConnectedError("WebSocket not available or not connected."));
|
|
12708
12710
|
return;
|
|
12709
12711
|
}
|
|
12712
|
+
let timeoutId;
|
|
12713
|
+
const settle = () => {
|
|
12714
|
+
clearTimeout(timeoutId);
|
|
12715
|
+
socket.removeEventListener("message", messageHandler);
|
|
12716
|
+
socket.removeEventListener("error", errorHandler);
|
|
12717
|
+
this.inFlight.delete(abort);
|
|
12718
|
+
};
|
|
12710
12719
|
const messageHandler = (event) => {
|
|
12711
12720
|
if (!isString(event.data)) {
|
|
12712
12721
|
logger.warn("WebSocket received non-string message data:", event.data);
|
|
@@ -12721,34 +12730,35 @@ ${indent}}` : "}";
|
|
|
12721
12730
|
);
|
|
12722
12731
|
return;
|
|
12723
12732
|
}
|
|
12724
|
-
if (message.id
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
} else {
|
|
12731
|
-
reject(
|
|
12732
|
-
new Error(`Error on ${method} (id: ${sendId}): ${JSON.stringify(message.error)}`)
|
|
12733
|
-
);
|
|
12734
|
-
}
|
|
12733
|
+
if (message.id !== sendId) return;
|
|
12734
|
+
settle();
|
|
12735
|
+
if ("result" in message) {
|
|
12736
|
+
resolve(message.result);
|
|
12737
|
+
} else {
|
|
12738
|
+
reject(new Error(`Error on ${method} (id: ${sendId}): ${JSON.stringify(message.error)}`));
|
|
12735
12739
|
}
|
|
12736
12740
|
};
|
|
12737
12741
|
const errorHandler = (event) => {
|
|
12738
|
-
|
|
12739
|
-
this.websocket.removeEventListener("message", messageHandler);
|
|
12740
|
-
this.websocket.removeEventListener("error", errorHandler);
|
|
12742
|
+
settle();
|
|
12741
12743
|
reject(
|
|
12742
12744
|
new Error(
|
|
12743
12745
|
`WebSocket error during ${method} (id: ${sendId}): ${event.type || "Unknown error"}`
|
|
12744
12746
|
)
|
|
12745
12747
|
);
|
|
12746
12748
|
};
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
+
const abort = (reason) => {
|
|
12750
|
+
settle();
|
|
12751
|
+
reject(
|
|
12752
|
+
new WebSocketNotConnectedError(
|
|
12753
|
+
`Request ${method} (id: ${sendId}) went unanswered: ${reason}`
|
|
12754
|
+
)
|
|
12755
|
+
);
|
|
12756
|
+
};
|
|
12757
|
+
socket.addEventListener("message", messageHandler);
|
|
12758
|
+
socket.addEventListener("error", errorHandler);
|
|
12759
|
+
this.inFlight.add(abort);
|
|
12749
12760
|
timeoutId = setTimeout(() => {
|
|
12750
|
-
|
|
12751
|
-
this.websocket.removeEventListener("error", errorHandler);
|
|
12761
|
+
settle();
|
|
12752
12762
|
reject(
|
|
12753
12763
|
new TimeoutError(
|
|
12754
12764
|
`Request ${method} (id: ${sendId}) timed out after ${this.requestTimeout}ms`
|
|
@@ -12803,6 +12813,9 @@ ${indent}}` : "}";
|
|
|
12803
12813
|
this.reconnectStabilityTimeoutId = null;
|
|
12804
12814
|
}
|
|
12805
12815
|
this.userInitiatedClose = true;
|
|
12816
|
+
this.isReconnecting = false;
|
|
12817
|
+
this._rejectRequestQueue("the connection was closed by the user");
|
|
12818
|
+
this._rejectInFlight("the connection was closed by the user");
|
|
12806
12819
|
this.websocket.close(code, reason);
|
|
12807
12820
|
}
|
|
12808
12821
|
/**
|
|
@@ -12876,6 +12889,39 @@ ${indent}}` : "}";
|
|
|
12876
12889
|
this.sendReceive(method, params).then(resolve).catch(reject);
|
|
12877
12890
|
});
|
|
12878
12891
|
}
|
|
12892
|
+
/**
|
|
12893
|
+
* Reject every request still waiting in the queue.
|
|
12894
|
+
*
|
|
12895
|
+
* A queued request carries no timeout of its own: the `requestTimeout` timer is only
|
|
12896
|
+
* armed once the request is actually put on the wire. So once the channel reaches a state
|
|
12897
|
+
* where the queue can never be flushed — reconnection gave up, or the user closed the
|
|
12898
|
+
* connection — the queued promises would stay pending forever, and no caller-side timeout
|
|
12899
|
+
* could rescue them. Settling them here is the only way out.
|
|
12900
|
+
*/
|
|
12901
|
+
_rejectRequestQueue(reason) {
|
|
12902
|
+
if (this.requestQueue.length === 0) return;
|
|
12903
|
+
const pending = this.requestQueue;
|
|
12904
|
+
this.requestQueue = [];
|
|
12905
|
+
logger.info(`WebSocket: Rejecting ${pending.length} queued request(s). Reason: ${reason}.`);
|
|
12906
|
+
pending.forEach(({ method, reject }) => {
|
|
12907
|
+
reject(new WebSocketNotConnectedError(`Request ${method} was never sent: ${reason}`));
|
|
12908
|
+
});
|
|
12909
|
+
}
|
|
12910
|
+
/**
|
|
12911
|
+
* Settle every request already on the wire.
|
|
12912
|
+
*
|
|
12913
|
+
* The counterpart of `_rejectRequestQueue`, for requests past the queue. Their only other
|
|
12914
|
+
* exit is the `requestTimeout` timer, so without this the caller waits the whole timeout —
|
|
12915
|
+
* 60s by default — for a reply that can no longer arrive, and that pending timer keeps the
|
|
12916
|
+
* Node event loop alive for just as long.
|
|
12917
|
+
*/
|
|
12918
|
+
_rejectInFlight(reason) {
|
|
12919
|
+
if (this.inFlight.size === 0) return;
|
|
12920
|
+
const pending = Array.from(this.inFlight);
|
|
12921
|
+
this.inFlight.clear();
|
|
12922
|
+
logger.info(`WebSocket: Rejecting ${pending.length} in-flight request(s). Reason: ${reason}.`);
|
|
12923
|
+
pending.forEach((abort) => abort(reason));
|
|
12924
|
+
}
|
|
12879
12925
|
async _restoreSubscriptions() {
|
|
12880
12926
|
const oldSubscriptions = Array.from(this.activeSubscriptions.values());
|
|
12881
12927
|
this.activeSubscriptions.clear();
|
|
@@ -12919,6 +12965,9 @@ ${indent}}` : "}";
|
|
|
12919
12965
|
if (this.reconnectAttempts >= this.reconnectOptions.retries) {
|
|
12920
12966
|
logger.error("WebSocket: Maximum reconnection retries reached. Giving up.");
|
|
12921
12967
|
this.isReconnecting = false;
|
|
12968
|
+
this._rejectRequestQueue(
|
|
12969
|
+
`reconnection gave up after ${this.reconnectOptions.retries} attempts`
|
|
12970
|
+
);
|
|
12922
12971
|
return;
|
|
12923
12972
|
}
|
|
12924
12973
|
this.reconnectAttempts += 1;
|
|
@@ -12926,18 +12975,24 @@ ${indent}}` : "}";
|
|
|
12926
12975
|
`WebSocket: Connection lost. Attempting to reconnect... (${this.reconnectAttempts}/${this.reconnectOptions.retries})`
|
|
12927
12976
|
);
|
|
12928
12977
|
this.reconnect();
|
|
12978
|
+
let attemptSettled = false;
|
|
12979
|
+
const scheduleRetry = () => {
|
|
12980
|
+
if (attemptSettled || !this.isReconnecting) return;
|
|
12981
|
+
attemptSettled = true;
|
|
12982
|
+
const delay = this.reconnectOptions.exponential ? this.reconnectOptions.delay * 2 ** (this.reconnectAttempts - 1) : this.reconnectOptions.delay;
|
|
12983
|
+
logger.info(`WebSocket: Reconnect attempt failed. Retrying in ${delay}ms.`);
|
|
12984
|
+
this.reconnectTimeoutId = setTimeout(tryReconnect, delay);
|
|
12985
|
+
};
|
|
12929
12986
|
this.websocket.onopen = async () => {
|
|
12930
12987
|
logger.info("WebSocket: Reconnection successful.");
|
|
12988
|
+
attemptSettled = true;
|
|
12931
12989
|
this.isReconnecting = false;
|
|
12932
12990
|
await this._restoreSubscriptions();
|
|
12933
12991
|
this._processRequestQueue();
|
|
12934
12992
|
this.events.emit("open", new Event("open"));
|
|
12935
12993
|
};
|
|
12936
|
-
this.websocket.onerror =
|
|
12937
|
-
|
|
12938
|
-
logger.info(`WebSocket: Reconnect attempt failed. Retrying in ${delay}ms.`);
|
|
12939
|
-
this.reconnectTimeoutId = setTimeout(tryReconnect, delay);
|
|
12940
|
-
};
|
|
12994
|
+
this.websocket.onerror = scheduleRetry;
|
|
12995
|
+
this.websocket.addEventListener("close", scheduleRetry);
|
|
12941
12996
|
};
|
|
12942
12997
|
tryReconnect();
|
|
12943
12998
|
}
|
|
@@ -12946,6 +13001,7 @@ ${indent}}` : "}";
|
|
|
12946
13001
|
this.websocket.removeEventListener("close", this.closeListener);
|
|
12947
13002
|
this.websocket.removeEventListener("message", this.messageListener);
|
|
12948
13003
|
this.websocket.removeEventListener("error", this.errorListener);
|
|
13004
|
+
this._rejectInFlight("the connection was closed");
|
|
12949
13005
|
this.events.emit("close", ev);
|
|
12950
13006
|
if (!this.userInitiatedClose) {
|
|
12951
13007
|
this._startReconnect();
|