wispjs 3.0.0 → 3.1.0

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.
@@ -220,8 +220,13 @@ export class WispSocket {
220
220
  const logger = worker.logger;
221
221
  logger.log("Running setupConsoleListener");
222
222
  return new Promise((resolve) => {
223
- worker.socket.on("console output", (line) => {
223
+ const cleanup = () => {
224
+ worker.socket.off("console output", handleLine);
225
+ worker.socket.off("disconnect", handleDisconnect);
226
+ };
227
+ const handleLine = (line) => {
224
228
  if (this.consoleCallbacks.length == 0) {
229
+ cleanup();
225
230
  return resolve();
226
231
  }
227
232
  this.consoleCallbacks.forEach((callback) => {
@@ -232,7 +237,16 @@ export class WispSocket {
232
237
  logger.error("Failed to run console callback", e);
233
238
  }
234
239
  });
235
- });
240
+ };
241
+ const handleDisconnect = () => {
242
+ cleanup();
243
+ resolve();
244
+ if (this.consoleCallbacks.length > 0) {
245
+ this.setupConsoleListener();
246
+ }
247
+ };
248
+ worker.socket.on("console output", handleLine);
249
+ worker.socket.once("disconnect", handleDisconnect);
236
250
  });
237
251
  });
238
252
  });
@@ -266,10 +266,13 @@ declare class PoolWorker {
266
266
  private intentionalDisconnect;
267
267
  private reconnectAttempts;
268
268
  private readonly maxReconnectAttempts;
269
+ private reauthTimer?;
269
270
  constructor(pool: WebsocketPool);
270
271
  private createSocket;
271
272
  private start;
272
273
  connect(): Promise<void>;
274
+ private scheduleReauth;
275
+ private reauth;
273
276
  private handleDisconnect;
274
277
  disconnect(): Promise<void>;
275
278
  private processWork;
@@ -1,5 +1,10 @@
1
1
  import { WispWebSocket } from "./ws_adapter.js";
2
2
  const WISP_DEBUG = process.env.WISP_DEBUG === "true";
3
+ const REAUTH_INTERVAL = (() => {
4
+ const parsed = process.env.WISP_REAUTH_INTERVAL ? parseInt(process.env.WISP_REAUTH_INTERVAL) : NaN;
5
+ return Number.isFinite(parsed) ? parsed : 9 * 60 * 1000;
6
+ })();
7
+ const REAUTH_TIMEOUT = 10000;
3
8
  /**
4
9
  * A single Worker within a {@link WebsocketPool}
5
10
  *
@@ -78,16 +83,59 @@ class PoolWorker {
78
83
  this.reconnectAttempts = 0;
79
84
  this.connected = true;
80
85
  clearTimeout(timeout);
86
+ this.scheduleReauth();
81
87
  resolve();
82
88
  });
83
89
  socket.connect();
84
90
  });
85
91
  }
92
+ // Resets the re-auth clock. Runs on every successful auth.
93
+ scheduleReauth() {
94
+ clearTimeout(this.reauthTimer);
95
+ this.reauthTimer = setTimeout(() => this.reauth(), REAUTH_INTERVAL);
96
+ }
97
+ // Re-auths the live socket with a fresh token. A failed re-auth is treated
98
+ // as a dead connection and handed to the reconnect path.
99
+ async reauth() {
100
+ if (!this.connected || this.intentionalDisconnect || this.done) {
101
+ return;
102
+ }
103
+ if (this.pool.refreshDetails) {
104
+ try {
105
+ const details = await this.pool.refreshDetails();
106
+ this.url = details.url;
107
+ this.token = details.token;
108
+ }
109
+ catch (e) {
110
+ this.logger.error("Re-auth: failed to refresh details", e);
111
+ return this.handleDisconnect("reauth refresh failure");
112
+ }
113
+ }
114
+ const socket = this.socket;
115
+ const ok = await new Promise((resolve) => {
116
+ const onSuccess = () => {
117
+ clearTimeout(timeout);
118
+ resolve(true);
119
+ };
120
+ const timeout = setTimeout(() => {
121
+ socket.off("auth success", onSuccess);
122
+ resolve(false);
123
+ }, REAUTH_TIMEOUT);
124
+ socket.once("auth success", onSuccess);
125
+ socket.emit("auth", this.token);
126
+ });
127
+ if (!ok) {
128
+ this.logger.error("Re-auth: no auth success in time");
129
+ return this.handleDisconnect("reauth failure");
130
+ }
131
+ this.scheduleReauth();
132
+ }
86
133
  // Recovers from an unexpected disconnect by reconnecting with a freshly
87
134
  // fetched token (the JWT is short-lived). After maxReconnectAttempts the
88
135
  // worker is marked dead so the pool stops handing it work.
89
136
  async handleDisconnect(reason) {
90
137
  this.connected = false;
138
+ clearTimeout(this.reauthTimer);
91
139
  if (this.intentionalDisconnect || this.done) {
92
140
  return;
93
141
  }
@@ -119,6 +167,7 @@ class PoolWorker {
119
167
  disconnect() {
120
168
  this.intentionalDisconnect = true;
121
169
  this.connected = false;
170
+ clearTimeout(this.reauthTimer);
122
171
  return new Promise((resolve) => {
123
172
  const timeout = setTimeout(() => {
124
173
  this.logger.error("Socket didn't disconnect in time");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wispjs",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "description": "A package for interacting with Wisp-based server panels",
6
6
  "main": "dist/wisp.js",