kantban-cli 0.1.19 → 0.1.20

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/index.js CHANGED
@@ -31,10 +31,10 @@ async function main() {
31
31
  }
32
32
  case "pipeline": {
33
33
  if (args[0] === "stop") {
34
- const { stopPipeline } = await import("./pipeline-5LJYH46J.js");
34
+ const { stopPipeline } = await import("./pipeline-FMDQGNHO.js");
35
35
  await stopPipeline(args.slice(1));
36
36
  } else {
37
- const { runPipeline } = await import("./pipeline-5LJYH46J.js");
37
+ const { runPipeline } = await import("./pipeline-FMDQGNHO.js");
38
38
  await runPipeline(client, args);
39
39
  }
40
40
  break;
@@ -2219,6 +2219,9 @@ var PipelineWsClient = class _PipelineWsClient {
2219
2219
  client;
2220
2220
  options;
2221
2221
  pingTimer = null;
2222
+ reconnectTimer = null;
2223
+ reconnectAttempt = 0;
2224
+ lastPong = 0;
2222
2225
  stopped = false;
2223
2226
  sendBuffer = [];
2224
2227
  static CRITICAL_TYPES = /* @__PURE__ */ new Set([
@@ -2230,6 +2233,9 @@ var PipelineWsClient = class _PipelineWsClient {
2230
2233
  static BUFFER_MAX = 100;
2231
2234
  static BUFFER_TTL_MS = 3e4;
2232
2235
  // 30 seconds
2236
+ static PING_INTERVAL_MS = 3e4;
2237
+ static PONG_TIMEOUT_MS = 45e3;
2238
+ // dead if no pong in 45s
2233
2239
  constructor(client, options) {
2234
2240
  this.client = client;
2235
2241
  this.options = options;
@@ -2247,7 +2253,7 @@ var PipelineWsClient = class _PipelineWsClient {
2247
2253
  }
2248
2254
  this.ws = null;
2249
2255
  }
2250
- this.cleanupPing();
2256
+ this.cleanupTimers();
2251
2257
  const { ticket } = await this.client.post("/ws-ticket");
2252
2258
  const wsUrl = this.client.baseUrl.replace(/^http/, "ws") + `/ws?ticket=${ticket}&clientType=cli`;
2253
2259
  return new Promise((resolve, reject) => {
@@ -2255,11 +2261,23 @@ var PipelineWsClient = class _PipelineWsClient {
2255
2261
  this.ws = new WebSocket(wsUrl);
2256
2262
  let subscribed = false;
2257
2263
  this.ws.on("open", () => {
2258
- this.pingTimer = setInterval(() => this.send({ type: "ping", payload: {} }), 3e4);
2264
+ this.lastPong = Date.now();
2265
+ this.reconnectAttempt = 0;
2266
+ this.pingTimer = setInterval(() => {
2267
+ if (Date.now() - this.lastPong > _PipelineWsClient.PONG_TIMEOUT_MS) {
2268
+ console.warn("[WS] No pong in 45s \u2014 connection dead, forcing reconnect");
2269
+ this.ws?.close();
2270
+ return;
2271
+ }
2272
+ this.send({ type: "ping", payload: {} });
2273
+ }, _PipelineWsClient.PING_INTERVAL_MS);
2259
2274
  });
2260
2275
  this.ws.on("message", (data) => {
2261
2276
  try {
2262
2277
  const event = JSON.parse(data.toString());
2278
+ if (event.type === "pong") {
2279
+ this.lastPong = Date.now();
2280
+ }
2263
2281
  if (!subscribed) {
2264
2282
  subscribed = true;
2265
2283
  this.send({ type: "board:subscribe", payload: { boardId: this.options.boardId, projectId: this.options.projectId } });
@@ -2276,11 +2294,13 @@ var PipelineWsClient = class _PipelineWsClient {
2276
2294
  }
2277
2295
  });
2278
2296
  this.ws.on("close", (code) => {
2279
- this.cleanupPing();
2297
+ this.cleanupTimers();
2280
2298
  this.options.onDisconnect();
2281
2299
  if (!resolved) {
2282
2300
  resolved = true;
2283
2301
  reject(new Error(`WebSocket closed before handshake (code ${code})`));
2302
+ } else {
2303
+ this.scheduleReconnect();
2284
2304
  }
2285
2305
  });
2286
2306
  this.ws.on("error", (err) => {
@@ -2307,7 +2327,7 @@ var PipelineWsClient = class _PipelineWsClient {
2307
2327
  stop() {
2308
2328
  this.sendBuffer = [];
2309
2329
  this.stopped = true;
2310
- this.cleanupPing();
2330
+ this.cleanupTimers();
2311
2331
  if (this.ws) {
2312
2332
  try {
2313
2333
  this.ws.removeAllListeners();
@@ -2345,11 +2365,32 @@ var PipelineWsClient = class _PipelineWsClient {
2345
2365
  }
2346
2366
  }
2347
2367
  }
2348
- cleanupPing() {
2368
+ scheduleReconnect() {
2369
+ if (this.stopped || this.reconnectTimer) return;
2370
+ const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempt), 3e4);
2371
+ this.reconnectAttempt++;
2372
+ console.log(`[WS] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt})`);
2373
+ this.reconnectTimer = setTimeout(() => {
2374
+ this.reconnectTimer = null;
2375
+ if (this.stopped) return;
2376
+ this.connect().then(() => {
2377
+ console.log("[WS] Reconnected successfully");
2378
+ }).catch((err) => {
2379
+ const msg = err instanceof Error ? err.message : String(err);
2380
+ console.warn(`[WS] Reconnect failed: ${msg}`);
2381
+ this.scheduleReconnect();
2382
+ });
2383
+ }, delay);
2384
+ }
2385
+ cleanupTimers() {
2349
2386
  if (this.pingTimer) {
2350
2387
  clearInterval(this.pingTimer);
2351
2388
  this.pingTimer = null;
2352
2389
  }
2390
+ if (this.reconnectTimer) {
2391
+ clearTimeout(this.reconnectTimer);
2392
+ this.reconnectTimer = null;
2393
+ }
2353
2394
  }
2354
2395
  };
2355
2396
 
@@ -4288,4 +4329,4 @@ export {
4288
4329
  runPipeline,
4289
4330
  stopPipeline
4290
4331
  };
4291
- //# sourceMappingURL=pipeline-5LJYH46J.js.map
4332
+ //# sourceMappingURL=pipeline-FMDQGNHO.js.map