mixi2-js 1.4.0 → 1.4.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/index.cjs CHANGED
@@ -530,27 +530,29 @@ var StreamWatcher = class {
530
530
  if (!fn) throw new Error("subscribeEvents method not found on stream client");
531
531
  return fn.call(this.streamClient, {}, metadata);
532
532
  }
533
- async reconnect() {
534
- const maxRetries = this.maxRetries;
535
- let lastError;
536
- for (let i = 0; i < maxRetries; i++) {
537
- if (this.aborted) throw new Error("Watcher aborted");
538
- await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1e3));
539
- try {
540
- return await this.connect();
541
- } catch (err) {
542
- lastError = err instanceof Error ? err : new Error(String(err));
543
- console.warn(`Reconnect attempt ${i + 1}/${maxRetries} failed:`, lastError.message);
544
- }
545
- }
546
- throw lastError || /* @__PURE__ */ new Error("Failed to reconnect");
533
+ async reconnect(retryIndex) {
534
+ if (this.aborted) throw new Error("Watcher aborted");
535
+ const backoff = Math.min(Math.pow(2, retryIndex) * 1e3, 3e4);
536
+ await new Promise((resolve) => setTimeout(resolve, backoff));
537
+ if (this.aborted) throw new Error("Watcher aborted");
538
+ return this.connect();
547
539
  }
548
540
  async watch(handler) {
549
541
  this.aborted = false;
550
542
  let stream = await this.connect();
543
+ let consecutiveFailures = 0;
551
544
  return new Promise((resolve, reject) => {
552
545
  const setupStream = (s) => {
546
+ let receivedData = false;
547
+ const connectionTimeout = setTimeout(() => {
548
+ if (!receivedData && !this.aborted) s.destroy(/* @__PURE__ */ new Error("Connection timeout: no data received"));
549
+ }, 3e4);
553
550
  s.on("data", (response) => {
551
+ if (!receivedData) {
552
+ receivedData = true;
553
+ clearTimeout(connectionTimeout);
554
+ consecutiveFailures = 0;
555
+ }
554
556
  const events = (response.events || []).map(convertEvent);
555
557
  for (const event of events) {
556
558
  if (event.eventType === require_types.EventType.PING) continue;
@@ -559,14 +561,20 @@ var StreamWatcher = class {
559
561
  });
560
562
  let disconnected = false;
561
563
  const handleDisconnect = async () => {
564
+ clearTimeout(connectionTimeout);
562
565
  if (disconnected) return;
563
566
  disconnected = true;
564
567
  if (this.aborted) {
565
568
  resolve();
566
569
  return;
567
570
  }
571
+ if (!receivedData) consecutiveFailures++;
572
+ if (consecutiveFailures >= this.maxRetries) {
573
+ reject(/* @__PURE__ */ new Error(`Failed to reconnect after ${this.maxRetries} consecutive attempts`));
574
+ return;
575
+ }
568
576
  try {
569
- stream = await this.reconnect();
577
+ stream = await this.reconnect(consecutiveFailures);
570
578
  setupStream(stream);
571
579
  } catch (reconnectErr) {
572
580
  reject(reconnectErr);
package/dist/index.mjs CHANGED
@@ -502,27 +502,29 @@ var StreamWatcher = class {
502
502
  if (!fn) throw new Error("subscribeEvents method not found on stream client");
503
503
  return fn.call(this.streamClient, {}, metadata);
504
504
  }
505
- async reconnect() {
506
- const maxRetries = this.maxRetries;
507
- let lastError;
508
- for (let i = 0; i < maxRetries; i++) {
509
- if (this.aborted) throw new Error("Watcher aborted");
510
- await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1e3));
511
- try {
512
- return await this.connect();
513
- } catch (err) {
514
- lastError = err instanceof Error ? err : new Error(String(err));
515
- console.warn(`Reconnect attempt ${i + 1}/${maxRetries} failed:`, lastError.message);
516
- }
517
- }
518
- throw lastError || /* @__PURE__ */ new Error("Failed to reconnect");
505
+ async reconnect(retryIndex) {
506
+ if (this.aborted) throw new Error("Watcher aborted");
507
+ const backoff = Math.min(Math.pow(2, retryIndex) * 1e3, 3e4);
508
+ await new Promise((resolve) => setTimeout(resolve, backoff));
509
+ if (this.aborted) throw new Error("Watcher aborted");
510
+ return this.connect();
519
511
  }
520
512
  async watch(handler) {
521
513
  this.aborted = false;
522
514
  let stream = await this.connect();
515
+ let consecutiveFailures = 0;
523
516
  return new Promise((resolve, reject) => {
524
517
  const setupStream = (s) => {
518
+ let receivedData = false;
519
+ const connectionTimeout = setTimeout(() => {
520
+ if (!receivedData && !this.aborted) s.destroy(/* @__PURE__ */ new Error("Connection timeout: no data received"));
521
+ }, 3e4);
525
522
  s.on("data", (response) => {
523
+ if (!receivedData) {
524
+ receivedData = true;
525
+ clearTimeout(connectionTimeout);
526
+ consecutiveFailures = 0;
527
+ }
526
528
  const events = (response.events || []).map(convertEvent);
527
529
  for (const event of events) {
528
530
  if (event.eventType === EventType.PING) continue;
@@ -531,14 +533,20 @@ var StreamWatcher = class {
531
533
  });
532
534
  let disconnected = false;
533
535
  const handleDisconnect = async () => {
536
+ clearTimeout(connectionTimeout);
534
537
  if (disconnected) return;
535
538
  disconnected = true;
536
539
  if (this.aborted) {
537
540
  resolve();
538
541
  return;
539
542
  }
543
+ if (!receivedData) consecutiveFailures++;
544
+ if (consecutiveFailures >= this.maxRetries) {
545
+ reject(/* @__PURE__ */ new Error(`Failed to reconnect after ${this.maxRetries} consecutive attempts`));
546
+ return;
547
+ }
540
548
  try {
541
- stream = await this.reconnect();
549
+ stream = await this.reconnect(consecutiveFailures);
542
550
  setupStream(stream);
543
551
  } catch (reconnectErr) {
544
552
  reject(reconnectErr);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixi2-js",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "TypeScript/JavaScript SDK for mixi2 Application API",
5
5
  "keywords": [
6
6
  "api",