@axa-fr/slimfaas-planet-saver 0.30.5 → 0.30.7

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/README.md CHANGED
@@ -24,16 +24,19 @@ npm install @axa-fr/slimfaas-planet-saver
24
24
 
25
25
  Example usage with react :
26
26
  ```javascript
27
- import React, { useState, useEffect } from 'react';
28
- import SlimFaasPlanetSaver from "@axa-fr/slimfaas-planet-saver";
27
+ import React, { useState, useEffect, useRef } from 'react';
28
+ import SlimFaasPlanetSaver from "./SlimFaasPlanetSaver.js";
29
29
 
30
30
  const PlanetSaver = ({ children, baseUrl, fetch }) => {
31
- const [isFirstStart, setIsFirstStart] = useState(true); // State for first start
31
+ const [isFirstStart, setIsFirstStart] = useState(true);
32
+ const environmentStarterRef = useRef(null);
32
33
 
33
34
  useEffect(() => {
34
35
  if (!baseUrl) return;
35
36
 
36
- const environmentStarter = new SlimFaasPlanetSaver(baseUrl, {
37
+ if (environmentStarterRef.current) return;
38
+
39
+ const instance = new SlimFaasPlanetSaver(baseUrl, {
37
40
  interval: 2000,
38
41
  fetch,
39
42
  updateCallback: (data) => {
@@ -45,31 +48,36 @@ const PlanetSaver = ({ children, baseUrl, fetch }) => {
45
48
  errorCallback: (error) => {
46
49
  console.error('Error detected :', error);
47
50
  },
48
- overlayStartingMessage: '🌍 Starting the environment.... 🌳',
51
+ overlayStartingMessage: '🌳 Starting the environment.... 🌳',
49
52
  overlayNoActivityMessage: 'Waiting activity to start environment...',
50
- overlayErrorMessage: 'An error occured when starting environment. Please contact an administrator.',
53
+ overlayErrorMessage: 'An error occurred when starting environment. Please contact an administrator.',
51
54
  overlaySecondaryMessage: 'Startup should be fast, but if no machines are available it can take several minutes.',
55
+ overlayLoadingIcon: '🌍',
56
+ overlayErrorSecondaryMessage: 'If the error persists, please contact an administrator.'
52
57
  });
53
58
 
54
- // Start polling
55
- environmentStarter.startPolling();
59
+ environmentStarterRef.current = instance;
60
+
61
+ // Initialiser les effets de bord
62
+ instance.initialize();
63
+ instance.startPolling();
56
64
 
57
- // Cleanup
58
- return () => environmentStarter.cleanup();
59
- }, [baseUrl, isFirstStart]);
65
+ return () => {
66
+ instance.cleanup();
67
+ environmentStarterRef.current = null;
68
+ };
69
+ }, [baseUrl]);
60
70
 
61
- // During the first start, display a loading message
62
71
  if (isFirstStart) {
63
72
  return null;
64
73
  }
65
74
 
66
- // Once the environment is started, display the children
67
75
  return <>{children}</>;
68
-
69
76
  };
70
77
 
71
78
  export default PlanetSaver;
72
79
 
80
+
73
81
  ```
74
82
 
75
83
  ## Run the demo
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@axa-fr/slimfaas-planet-saver",
3
3
  "private": false,
4
- "version": "0.30.5",
4
+ "version": "0.30.7",
5
5
  "type": "module",
6
6
  "module": "./src/SlimFaasPlanetSaver.js",
7
7
  "description": "Pure vanilla javascript which call SlimFaas API to convert infrastructures resilience to an UX resilience and help to save the planet",
@@ -4,25 +4,33 @@
4
4
  return tempUrl;
5
5
  }
6
6
 
7
+ let id =1;
8
+
7
9
  export default class SlimFaasPlanetSaver {
8
10
  constructor(baseUrl, options = {}) {
9
11
  this.baseUrl = normalizeBaseUrl(baseUrl);
10
12
  this.updateCallback = options.updateCallback || (() => {});
11
13
  this.errorCallback = options.errorCallback || (() => {});
12
14
  this.interval = options.interval || 5000;
13
- this.overlayStartingMessage = options.overlayStartingMessage || '🌍 Starting the environment.... 🌳';
15
+ this.overlayStartingMessage = options.overlayStartingMessage || '🌳 Starting the environment.... 🌳';
14
16
  this.overlayNoActivityMessage = options.overlayNoActivityMessage || 'Waiting activity to start environment...';
15
- this.overlayErrorMessage = options.overlayErrorMessage || 'Une erreur est survenue lors du démarrage de l\'environnement. Veuillez contacter un administrateur.';
17
+ this.overlayErrorMessage = options.overlayErrorMessage || 'An error occurred while starting the environment.';
16
18
  this.overlaySecondaryMessage = options.overlaySecondaryMessage || 'Startup should be fast, but if no machines are available it can take several minutes.';
19
+ this.overlayErrorSecondaryMessage = options.overlayErrorSecondaryMessage || 'If the error persists, please contact an administrator.';
20
+ this.overlayLoadingIcon = options.overlayLoadingIcon || '🌍';
17
21
  this.fetch = options.fetch || fetch;
18
22
  this.intervalId = null;
19
23
  this.isDocumentVisible = !document.hidden;
20
24
  this.overlayElement = null;
21
- this.spanElement = null; // Nouvel élément pour le <span>
25
+ this.spanElement = null;
22
26
  this.styleElement = null;
23
27
  this.isReady = false;
28
+ this.id = id++;
29
+ this.cleanned = false;
30
+ }
24
31
 
25
- // Initialisation du temps du dernier mouvement de souris et liaison du gestionnaire
32
+ initialize() {
33
+ this.cleanned = false;
26
34
  this.lastMouseMoveTime = Date.now();
27
35
  this.handleMouseMove = this.handleMouseMove.bind(this);
28
36
  this.handleVisibilityChange = this.handleVisibilityChange.bind(this);
@@ -33,43 +41,41 @@ export default class SlimFaasPlanetSaver {
33
41
  this.createOverlay();
34
42
  this.injectStyles();
35
43
 
36
- this.events = document.createElement('div');
37
44
  }
38
-
39
45
  handleMouseMove() {
40
46
  this.lastMouseMoveTime = Date.now();
41
47
  }
42
48
 
43
49
  handleVisibilityChange() {
44
50
  this.isDocumentVisible = !document.hidden;
45
- if (this.isDocumentVisible) {
46
- this.startPolling();
47
- } else {
48
- this.stopPolling();
49
- }
50
51
  }
51
52
 
52
53
  async wakeUpPods(data) {
53
54
  const wakePromises = data
54
55
  .filter((item) => item.NumberReady === 0)
55
- .map((item) =>
56
- this.fetch(`${this.baseUrl}/wake-function/${item.Name}`, {
56
+ .map(async (item) => {
57
+ const response = await this.fetch(`${this.baseUrl}/wake-function/${item.Name}`, {
57
58
  method: 'POST',
58
- })
59
- );
59
+ });
60
+ if (response.status >= 400) {
61
+ throw new Error(`HTTP Error! status: ${response.status} for function ${item.Name}`);
62
+ }
63
+ return response;
64
+ });
60
65
 
61
66
  try {
62
67
  await Promise.all(wakePromises);
63
68
  } catch (error) {
64
- console.error("Erreur lors du réveil des pods :", error);
69
+ console.error("Error waking up pods:", error);
70
+ throw error;
65
71
  }
66
72
  }
67
73
 
68
74
  async fetchStatus() {
69
75
  try {
70
76
  const response = await this.fetch(`${this.baseUrl}/status-functions`);
71
- if (!response.ok) {
72
- throw new Error(`Erreur HTTP ! statut : ${response.status}`);
77
+ if (response.status >= 400) {
78
+ throw new Error(`HTTP Error! status: ${response.status}`);
73
79
  }
74
80
  const data = await response.json();
75
81
 
@@ -79,7 +85,7 @@ export default class SlimFaasPlanetSaver {
79
85
  this.updateCallback(data);
80
86
 
81
87
  const now = Date.now();
82
- const mouseMovedRecently = now - this.lastMouseMoveTime <= 60000; // 1 minute en millisecondes
88
+ const mouseMovedRecently = now - this.lastMouseMoveTime <= 60000; // 1 minute
83
89
 
84
90
  if (!allReady && this.isDocumentVisible && !mouseMovedRecently) {
85
91
  this.updateOverlayMessage(this.overlayNoActivityMessage, 'waiting-action');
@@ -89,11 +95,13 @@ export default class SlimFaasPlanetSaver {
89
95
  }
90
96
  } catch (error) {
91
97
  const errorMessage = error.message;
92
- this.updateOverlayMessage(this.overlayErrorMessage, 'error');
98
+ this.updateOverlayMessage(this.overlayErrorMessage, 'error', this.overlayErrorSecondaryMessage);
93
99
  this.errorCallback(errorMessage);
94
- this.triggerEvent('error', { message: errorMessage });
95
- console.error('Erreur lors de la récupération des données slimfaas :', errorMessage);
100
+ console.error('Error fetching slimfaas data:', errorMessage);
96
101
  } finally {
102
+ if(!this.intervalId) {
103
+ return;
104
+ }
97
105
  this.intervalId = setTimeout(() => {
98
106
  this.fetchStatus();
99
107
  }, this.interval);
@@ -110,7 +118,7 @@ export default class SlimFaasPlanetSaver {
110
118
  }
111
119
 
112
120
  startPolling() {
113
- if (this.intervalId || !this.baseUrl) return;
121
+ if (this.intervalId || !this.baseUrl || this.cleanned) return;
114
122
 
115
123
  this.fetchStatus();
116
124
 
@@ -128,61 +136,67 @@ export default class SlimFaasPlanetSaver {
128
136
 
129
137
  injectStyles() {
130
138
  const cssString = `
131
- .environment-overlay {
132
- position: fixed;
133
- top: 0;
134
- left: 0;
135
- width: 100%;
136
- cursor: not-allowed;
137
- height: 100%;
138
- background-color: rgba(0, 0, 0, 0.8);
139
- display: flex;
140
- flex-direction: column;
141
- justify-content: center;
142
- align-items: center;
143
- color: white;
144
- font-size: 2rem;
145
- font-weight: bold;
146
- z-index: 1000;
147
- visibility: hidden;
148
- text-align: center;
149
- }
150
-
151
- .environment-overlay.visible {
152
- visibility: visible;
153
- }
154
-
155
- .environment-overlay .main-message {
156
- display: flex;
157
- align-items: center;
158
- gap: 0.5rem;
159
- color: white;
160
- }
161
-
162
- .environment-overlay .secondary-message {
163
- font-size: 1.2rem;
164
- font-weight: normal;
165
- margin-top: 1rem;
166
- }
167
-
168
- .environment-overlay--waiting{
169
- color: white;
170
- }
171
-
172
- .environment-overlay--waiting-action {
173
- color: lightyellow;
174
- }
175
- .environment-overlay--waiting-action .secondary-message {
176
- visibility: hidden;
177
- }
178
-
179
- .environment-overlay--error {
180
- color: lightred;
181
- }
182
- .environment-overlay--error .secondary-message {
183
- visibility: hidden;
184
- }
139
+ .slimfaas-environment-overlay {
140
+ position: fixed;
141
+ top: 0;
142
+ left: 0;
143
+ width: 100%;
144
+ cursor: not-allowed;
145
+ height: 100%;
146
+ background-color: rgba(0, 0, 0, 0.8);
147
+ display: flex;
148
+ flex-direction: column;
149
+ justify-content: center;
150
+ align-items: center;
151
+ font-size: 2rem;
152
+ font-weight: bold;
153
+ z-index: 1000;
154
+ text-align: center;
155
+ }
156
+
157
+ .slimfaas-environment-overlay__icon {
158
+ font-size: 4rem;
159
+ animation: slimfaas-environment-overlay__icon-spin 0.5s linear infinite;
160
+ }
161
+
162
+ @keyframes slimfaas-environment-overlay__icon-spin {
163
+ from {
164
+ transform: rotate(0deg);
165
+ }
166
+ to {
167
+ transform: rotate(360deg);
168
+ }
169
+ }
170
+
171
+ .slimfaas-environment-overlay__main-message {
172
+ display: flex;
173
+ align-items: center;
174
+ gap: 0.5rem;
175
+ }
176
+
177
+ .slimfaas-environment-overlay__secondary-message {
178
+ font-size: 1.2rem;
179
+ font-weight: normal;
180
+ margin-top: 1rem;
181
+ }
182
+
183
+ .slimfaas-environment-overlay--waiting {
184
+ color: white;
185
+ }
185
186
 
187
+ .slimfaas-environment-overlay--waiting-action {
188
+ color: lightyellow;
189
+ }
190
+ .slimfaas-environment-overlay--waiting-action .slimfaas-environment-overlay__secondary-message {
191
+ visibility: hidden;
192
+ }
193
+ .slimfaas-environment-overlay--waiting-action .slimfaas-environment-overlay__icon {
194
+ animation: none;
195
+ }
196
+
197
+ .slimfaas-environment-overlay--error {
198
+ color: lightcoral;
199
+ }
186
200
  `;
187
201
 
188
202
  this.styleElement = document.createElement('style');
@@ -192,59 +206,77 @@ export default class SlimFaasPlanetSaver {
192
206
 
193
207
  createOverlay() {
194
208
  this.overlayElement = document.createElement('div');
195
- this.overlayElement.className = 'environment-overlay';
209
+ this.overlayElement.className = 'slimfaas-environment-overlay';
210
+ this.overlayElement.id = `slimfaas-environment-overlay-${this.id}`;
196
211
 
197
- // Créer un élément <span> pour le texte et les icônes
212
+ // Créer l'élément icône
213
+ this.iconElement = document.createElement('div');
214
+ this.iconElement.className = 'slimfaas-environment-overlay__icon';
215
+ this.iconElement.innerText = this.overlayLoadingIcon;
216
+
217
+ // Créer l'élément du message principal
198
218
  this.spanElement = document.createElement('span');
219
+ this.spanElement.className = 'slimfaas-environment-overlay__main-message';
199
220
  this.spanElement.innerHTML = `${this.overlayStartingMessage}`;
200
221
 
201
- // Créer un élément <span> pour le second message
222
+ // Créer l'élément du message secondaire
202
223
  this.secondarySpanElement = document.createElement('span');
203
- this.secondarySpanElement.className = 'secondary-message';
224
+ this.secondarySpanElement.className = 'slimfaas-environment-overlay__secondary-message';
204
225
  this.secondarySpanElement.innerText = this.overlaySecondaryMessage;
205
226
 
206
- // Ajouter le <span> à l'overlay
227
+ // Ajouter les éléments à l'overlay
228
+ this.overlayElement.appendChild(this.iconElement);
207
229
  this.overlayElement.appendChild(this.spanElement);
208
230
  this.overlayElement.appendChild(this.secondarySpanElement);
209
231
 
210
- document.body.appendChild(this.overlayElement);
232
+ // Ne pas ajouter l'overlay au DOM ici
233
+ // document.body.appendChild(this.overlayElement);
211
234
  }
212
235
 
213
236
  showOverlay() {
214
- if (this.overlayElement) {
215
- this.overlayElement.classList.add('visible');
237
+ if(this.cleanned) return;
238
+ if (this.overlayElement && !document.body.contains(this.overlayElement)) {
239
+ document.body.appendChild(this.overlayElement);
216
240
  }
217
241
  }
218
242
 
219
243
  hideOverlay() {
220
- if (this.overlayElement) {
221
- this.overlayElement.classList.remove('visible');
244
+ if (this.overlayElement && document.body.contains(this.overlayElement)) {
245
+ document.body.removeChild(this.overlayElement);
222
246
  }
223
247
  }
224
248
 
225
- updateOverlayMessage(newMessage, status = 'waiting') {
249
+ updateOverlayMessage(newMessage, status = 'waiting', secondaryMessage = null) {
226
250
  if (this.spanElement) {
227
251
  this.spanElement.innerHTML = `${newMessage}`;
228
252
  }
253
+ if (this.secondarySpanElement && secondaryMessage !== null) {
254
+ this.secondarySpanElement.innerText = secondaryMessage;
255
+ } else {
256
+ this.secondarySpanElement.innerText = this.overlaySecondaryMessage;
257
+ }
229
258
  if (this.overlayElement) {
230
- this.overlayElement.classList.remove('environment-overlay--error', 'environment--overlay-waiting', 'environment-overlay--waiting-action');
231
- this.overlayElement.classList.add("environment-overlay--"+status);
259
+ this.overlayElement.classList.remove(
260
+ 'slimfaas-environment-overlay--error',
261
+ 'slimfaas-environment-overlay--waiting',
262
+ 'slimfaas-environment-overlay--waiting-action'
263
+ );
264
+ this.overlayElement.classList.add('slimfaas-environment-overlay--' + status);
232
265
  }
233
266
  }
234
267
 
235
- triggerEvent(eventName, detail) {
236
- const event = new CustomEvent(eventName, { detail });
237
- this.events.dispatchEvent(event);
238
- }
239
-
240
268
  cleanup() {
269
+ this.cleanned = true;
241
270
  this.stopPolling();
242
271
  document.removeEventListener('visibilitychange', this.handleVisibilityChange);
243
272
  document.removeEventListener('mousemove', this.handleMouseMove);
244
- if (this.overlayElement) {
273
+
274
+ document.getElementById(`slimfaas-environment-overlay-${this.id}`)?.remove();
275
+
276
+ if (this.overlayElement && document.body.contains(this.overlayElement)) {
245
277
  document.body.removeChild(this.overlayElement);
246
278
  }
247
- if (this.styleElement) {
279
+ if (this.styleElement && document.head.contains(this.styleElement)) {
248
280
  document.head.removeChild(this.styleElement);
249
281
  }
250
282
  }