releasebird-javascript-sdk 1.0.65 → 1.0.66

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.
@@ -92,6 +92,19 @@ export default class RbirdScreenshotManager {
92
92
  let that = this;
93
93
  const loader = this.showLoader();
94
94
 
95
+ // Global timeout for entire screenshot process (45 seconds)
96
+ const SCREENSHOT_TIMEOUT = 45000;
97
+ let screenshotCompleted = false;
98
+
99
+ const timeoutId = setTimeout(() => {
100
+ if (!screenshotCompleted) {
101
+ console.error('[Screenshot] Timeout - screenshot took too long');
102
+ that.hideLoader();
103
+ that.deactivateMarker();
104
+ alert('Screenshot took too long to generate. Please try again with a simpler page or contact support.');
105
+ }
106
+ }, SCREENSHOT_TIMEOUT);
107
+
95
108
  // Wait a moment for the loader to render, then hide our UI elements
96
109
  setTimeout(() => {
97
110
  console.log('[Screenshot] Starting HTML export method...');
@@ -124,6 +137,8 @@ export default class RbirdScreenshotManager {
124
137
  that.renderScreenshotOnBackend(htmlData)
125
138
  .then((screenshotDataUrl) => {
126
139
  console.log('[Screenshot] Screenshot received from backend!');
140
+ screenshotCompleted = true;
141
+ clearTimeout(timeoutId);
127
142
 
128
143
  // Restore visibility
129
144
  loader.style.visibility = 'visible';
@@ -148,6 +163,8 @@ export default class RbirdScreenshotManager {
148
163
  })
149
164
  .catch((error) => {
150
165
  console.error('[Screenshot] Backend rendering failed:', error);
166
+ screenshotCompleted = true;
167
+ clearTimeout(timeoutId);
151
168
 
152
169
  // Restore visibility
153
170
  loader.style.visibility = 'visible';
@@ -159,10 +176,13 @@ export default class RbirdScreenshotManager {
159
176
  }
160
177
 
161
178
  that.hideLoader();
179
+ that.deactivateMarker();
162
180
  alert('Screenshot could not be created. Please try again or contact support.');
163
181
  });
164
182
  } catch (error) {
165
183
  console.error('[Screenshot] HTML export failed:', error);
184
+ screenshotCompleted = true;
185
+ clearTimeout(timeoutId);
166
186
 
167
187
  // Restore visibility
168
188
  loader.style.visibility = 'visible';
@@ -174,6 +194,7 @@ export default class RbirdScreenshotManager {
174
194
  }
175
195
 
176
196
  that.hideLoader();
197
+ that.deactivateMarker();
177
198
  alert('Screenshot could not be created. Please try again or contact support.');
178
199
  }
179
200
  });
@@ -553,14 +574,26 @@ export default class RbirdScreenshotManager {
553
574
 
554
575
  const widgetInstance = this.getRbirdWebsiteWidget().getInstance();
555
576
 
577
+ // Create abort controller for timeout
578
+ const controller1 = new AbortController();
579
+ const timeout1 = setTimeout(() => controller1.abort(), 10000); // 10s timeout
580
+
556
581
  // 1. Get presigned URL
557
582
  const urlResponse = await fetch(`${API}/images/screenshot/upload-url`, {
558
583
  method: 'POST',
559
584
  headers: {
560
585
  'Content-Type': 'application/json',
561
586
  'apiKey': widgetInstance.apiKey || ''
587
+ },
588
+ signal: controller1.signal
589
+ }).catch(err => {
590
+ clearTimeout(timeout1);
591
+ if (err.name === 'AbortError') {
592
+ throw new Error('Timeout getting upload URL');
562
593
  }
594
+ throw err;
563
595
  });
596
+ clearTimeout(timeout1);
564
597
 
565
598
  if (!urlResponse.ok) {
566
599
  throw new Error(`Failed to get upload URL: ${urlResponse.status}`);
@@ -570,13 +603,24 @@ export default class RbirdScreenshotManager {
570
603
  console.log(`[Screenshot] Step 2: Uploading HTML to S3 (key: ${key})...`);
571
604
 
572
605
  // 2. Upload HTML directly to S3
606
+ const controller2 = new AbortController();
607
+ const timeout2 = setTimeout(() => controller2.abort(), 15000); // 15s timeout
608
+
573
609
  const s3Response = await fetch(uploadUrl, {
574
610
  method: 'PUT',
575
611
  body: html,
576
612
  headers: {
577
613
  'Content-Type': 'text/html'
614
+ },
615
+ signal: controller2.signal
616
+ }).catch(err => {
617
+ clearTimeout(timeout2);
618
+ if (err.name === 'AbortError') {
619
+ throw new Error('Timeout uploading to S3');
578
620
  }
621
+ throw err;
579
622
  });
623
+ clearTimeout(timeout2);
580
624
 
581
625
  if (!s3Response.ok) {
582
626
  throw new Error(`Failed to upload to S3: ${s3Response.status}`);
@@ -585,6 +629,9 @@ export default class RbirdScreenshotManager {
585
629
  console.log('[Screenshot] Step 3: Requesting screenshot render from backend...');
586
630
 
587
631
  // 3. Request screenshot render via backend
632
+ const controller3 = new AbortController();
633
+ const timeout3 = setTimeout(() => controller3.abort(), 20000); // 20s timeout
634
+
588
635
  const renderResponse = await fetch(`${API}/images/screenshot/render`, {
589
636
  method: 'POST',
590
637
  headers: {
@@ -596,8 +643,16 @@ export default class RbirdScreenshotManager {
596
643
  width: window.innerWidth,
597
644
  height: window.innerHeight,
598
645
  url: window.location.href
599
- })
646
+ }),
647
+ signal: controller3.signal
648
+ }).catch(err => {
649
+ clearTimeout(timeout3);
650
+ if (err.name === 'AbortError') {
651
+ throw new Error('Timeout rendering screenshot');
652
+ }
653
+ throw err;
600
654
  });
655
+ clearTimeout(timeout3);
601
656
 
602
657
  if (!renderResponse.ok) {
603
658
  const errorText = await renderResponse.text();
@@ -627,6 +682,13 @@ export default class RbirdScreenshotManager {
627
682
  http.open('POST', `${API}/images/screenshot/render`);
628
683
  http.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
629
684
 
685
+ // Add timeout for XHR request (20 seconds)
686
+ http.timeout = 20000;
687
+ http.ontimeout = function() {
688
+ console.error('[Screenshot] Request timeout');
689
+ reject(new Error('Screenshot render timeout'));
690
+ };
691
+
630
692
  // Add API key if available
631
693
  const widgetInstance = this.getRbirdWebsiteWidget().getInstance();
632
694
  if (widgetInstance.apiKey) {
@@ -49,7 +49,7 @@ export default class RbirdWebsiteWidget {
49
49
 
50
50
  isMobileDevice = () => {
51
51
  if (typeof window === 'undefined') return false;
52
- const mobileMaxWidth = 768; // Definiert die maximale Breite für mobile Geräte, z.B. Tablets und Smartphones
52
+ const mobileMaxWidth = 768;
53
53
  return window.innerWidth <= mobileMaxWidth;
54
54
  }
55
55
 
@@ -60,16 +60,14 @@ export default class RbirdWebsiteWidget {
60
60
  return;
61
61
  }
62
62
 
63
- // Überprüfen, ob das Widget bereits sichtbar ist
64
63
  if (this.websiteWidgetVisible) {
65
- resolve(); // Wenn das Widget bereits sichtbar ist, wird das Promise sofort aufgelöst
64
+ resolve();
66
65
  return;
67
66
  }
68
67
 
69
68
  this.websiteWidgetVisible = true;
70
69
 
71
70
  try {
72
- // Widget-Element erstellen und zum DOM hinzufügen
73
71
  let elem = document.createElement("div");
74
72
  elem.onclick = () => {
75
73
  this.openWebsiteWidget();
@@ -77,7 +75,6 @@ export default class RbirdWebsiteWidget {
77
75
  document.body.appendChild(elem);
78
76
  this.websiteWidget = elem;
79
77
 
80
- // Überprüfen, ob das Schließen des Widgets erlaubt ist
81
78
  if (RbirdSessionManager.getInstance().widgetSettings?.allowClose && !this.noButton) {
82
79
  this.hideWidgetButton = document.createElement("div");
83
80
  this.hideWidgetButton.className = "hideWidgetButton";
@@ -87,19 +84,15 @@ export default class RbirdWebsiteWidget {
87
84
  document.body.appendChild(this.hideWidgetButton);
88
85
  }
89
86
 
90
- // Badge erstellen und zum DOM hinzufügen
91
87
  this.countBadge = document.createElement("span");
92
88
  this.countBadge.className = "rbird_badge";
93
89
  this.countBadge.style.display = "none";
94
90
  document.body.appendChild(this.countBadge);
95
91
 
96
- // Stil des Widgets anpassen
97
92
  this.styleWidget();
98
93
 
99
- // Erfolgreich aufgelöst, nachdem das Widget hinzugefügt und gestylt wurde
100
94
  resolve();
101
95
  } catch (error) {
102
- // Falls ein Fehler während der Widget-Erstellung oder des DOM-Manipulationsprozesses auftritt, wird das Promise abgelehnt
103
96
  reject(new Error("Error rendering the website widget: " + error.message));
104
97
  }
105
98
  });