@pulsepairs/sdk 0.8.0 → 0.8.1
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/dist/ws.js +42 -1
- package/package.json +3 -3
package/dist/ws.js
CHANGED
|
@@ -212,7 +212,48 @@ export class UpDownWsClient {
|
|
|
212
212
|
const delay = attempt > 12 ? 30_000 : Math.min(30_000, 1000 * 2 ** Math.min(attempt, 5));
|
|
213
213
|
this.timer = setTimeout(() => this.openSocket(), delay);
|
|
214
214
|
};
|
|
215
|
-
|
|
215
|
+
// NEVER call close() synchronously from here.
|
|
216
|
+
//
|
|
217
|
+
// `onerror = () => ws.close()` stood here through 0.8.0 and took
|
|
218
|
+
// LedgerCore's process down twice against our 502s:
|
|
219
|
+
// "RangeError: Maximum call stack size exceeded" at dist/ws.js:215. On a
|
|
220
|
+
// WebSocket implementation that fails a CONNECTING socket SYNCHRONOUSLY,
|
|
221
|
+
// close() dispatches `error` before it returns, which re-enters this
|
|
222
|
+
// handler, which calls close() again — unbounded recursion on the stack
|
|
223
|
+
// rather than a loop that backoff could ever slow down. A handshake that
|
|
224
|
+
// fails fast, like a 502 from a load balancer, is exactly the trigger.
|
|
225
|
+
//
|
|
226
|
+
// Node's built-in WebSocket and the `ws` package both defer that error to a
|
|
227
|
+
// later tick and so survive it, which is why this went unnoticed here: the
|
|
228
|
+
// bug is invisible on the runtimes we test on and fatal on the ones we
|
|
229
|
+
// don't. The guard below therefore does not depend on knowing which
|
|
230
|
+
// implementation is underneath.
|
|
231
|
+
//
|
|
232
|
+
// The close is also redundant on every conforming implementation: a socket
|
|
233
|
+
// that emits `error` emits `close` afterwards, and `onclose` already owns
|
|
234
|
+
// reconnect. It is kept only for an implementation that errors without ever
|
|
235
|
+
// closing, deferred to a later tick where re-entry cannot grow the stack.
|
|
236
|
+
let errorHandled = false;
|
|
237
|
+
ws.onerror = () => {
|
|
238
|
+
if (errorHandled)
|
|
239
|
+
return; // re-entry is the bug; make it impossible
|
|
240
|
+
errorHandled = true;
|
|
241
|
+
if (this.closed || this.ws !== ws)
|
|
242
|
+
return;
|
|
243
|
+
setTimeout(() => {
|
|
244
|
+
// `onclose` normally fires on its own and has already scheduled the
|
|
245
|
+
// reconnect. Only force it if this socket errored and then just sat
|
|
246
|
+
// there, which would otherwise strand the client with no retry.
|
|
247
|
+
if (ws.readyState === 3 /* CLOSED */)
|
|
248
|
+
return;
|
|
249
|
+
try {
|
|
250
|
+
ws.close();
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
/* ignore */
|
|
254
|
+
}
|
|
255
|
+
}, 0);
|
|
256
|
+
};
|
|
216
257
|
}
|
|
217
258
|
async startHandshake() {
|
|
218
259
|
if (!this.mode || !this.ws)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulsepairs/sdk",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "Standalone SDK for the UpDown (PulsePairs) up/down prediction markets
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "Standalone SDK for the UpDown (PulsePairs) up/down prediction markets \u2014 matcher REST/WS client, EIP-712 order signing, trade-math, and Alchemy Account Kit (smart-account) order signing for rain.trade integration.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"scripts": {
|
|
35
35
|
"clean": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\"",
|
|
36
36
|
"build": "npm run clean && tsc",
|
|
37
|
-
"test": "node scripts/eip712-golden.test.mjs && node scripts/rawtx-tier.test.mjs && node scripts/hot-key-safety.test.mjs && node scripts/reconcile.test.mjs && node scripts/pnl.test.mjs && node scripts/ws-subscribe.test.mjs",
|
|
37
|
+
"test": "node scripts/eip712-golden.test.mjs && node scripts/rawtx-tier.test.mjs && node scripts/hot-key-safety.test.mjs && node scripts/reconcile.test.mjs && node scripts/pnl.test.mjs && node scripts/ws-subscribe.test.mjs && node scripts/ws-onerror.test.mjs",
|
|
38
38
|
"prepublishOnly": "npm run build && npm test",
|
|
39
39
|
"example:taker": "npx tsx examples/simple-taker.ts",
|
|
40
40
|
"example:maker": "npx tsx examples/simple-maker.ts",
|