@oas-tools/oas-telemetry 0.2.2 → 0.3.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.
- package/LICENSE +200 -200
- package/README.md +133 -133
- package/dist/exporters/InMemoryDbExporter.cjs +32 -31
- package/dist/index.cjs +56 -19
- package/dist/telemetry.cjs +0 -0
- package/dist/ui.cjs +387 -97
- package/package.json +71 -69
- package/src/exporters/InMemoryDbExporter.js +175 -174
- package/src/index.js +307 -255
- package/src/telemetry.js +25 -25
- package/src/ui.js +387 -97
package/dist/ui.cjs
CHANGED
|
@@ -16,12 +16,98 @@ function ui() {
|
|
|
16
16
|
<style>
|
|
17
17
|
body {
|
|
18
18
|
font-family: Arial, sans-serif;
|
|
19
|
-
margin:
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
background-color: #f5f5f5;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.header {
|
|
25
|
+
background-color: #333;
|
|
26
|
+
color: #fff;
|
|
27
|
+
padding: 20px;
|
|
28
|
+
text-align: left;
|
|
29
|
+
display: flex;
|
|
30
|
+
justify-content: space-between;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.header h1 {
|
|
34
|
+
display: inline-block;
|
|
35
|
+
margin: 0;
|
|
36
|
+
font-size: 24px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.header .links {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
}
|
|
43
|
+
.links a {
|
|
44
|
+
color: #fff;
|
|
45
|
+
text-decoration: none;
|
|
46
|
+
margin-left: 30px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.page {
|
|
50
|
+
margin: 0;
|
|
51
|
+
padding: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.panel-conainer {
|
|
55
|
+
min-width: 60%;
|
|
56
|
+
width: fit-content;
|
|
57
|
+
margin: 20px auto;
|
|
58
|
+
}
|
|
59
|
+
.panel {
|
|
60
|
+
background-color: #fff;
|
|
61
|
+
border: 1px solid #ddd;
|
|
62
|
+
margin: 10px;
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.panel-header {
|
|
67
|
+
background-color: #f1f1f1;
|
|
68
|
+
padding: 10px;
|
|
69
|
+
font-weight: bold;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.panel-content {
|
|
74
|
+
display: none;
|
|
75
|
+
padding: 15px;
|
|
76
|
+
|
|
77
|
+
/* items margin */
|
|
78
|
+
>* {
|
|
79
|
+
margin: 5px 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.panel.open .panel-content {
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: column;
|
|
87
|
+
padding: 15px;
|
|
88
|
+
justify-content: center;
|
|
89
|
+
align-items: center;
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
button {
|
|
95
|
+
background-color: #007bff;
|
|
96
|
+
color: white;
|
|
97
|
+
border: none;
|
|
98
|
+
padding: 10px 15px;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
border-radius: 4px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
button:hover {
|
|
104
|
+
background-color: #0056b3;
|
|
20
105
|
}
|
|
21
106
|
|
|
22
107
|
table {
|
|
23
|
-
width:
|
|
108
|
+
width: fit-content;
|
|
24
109
|
border-collapse: collapse;
|
|
110
|
+
margin: 100%;
|
|
25
111
|
}
|
|
26
112
|
|
|
27
113
|
th,
|
|
@@ -35,40 +121,221 @@ function ui() {
|
|
|
35
121
|
background-color: #f2f2f2;
|
|
36
122
|
}
|
|
37
123
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
.spaced-row {
|
|
127
|
+
display: flex;
|
|
128
|
+
align-items: center;
|
|
129
|
+
justify-content: space-between;
|
|
130
|
+
width: 100%;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.row {
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
}
|
|
137
|
+
</style>
|
|
138
|
+
<style>
|
|
139
|
+
.toggle-container {
|
|
140
|
+
display: flex;
|
|
141
|
+
flex: none;
|
|
142
|
+
width: max-content;
|
|
143
|
+
align-items: center;
|
|
144
|
+
margin: 10px 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.toggle {
|
|
148
|
+
display: flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
min-width: 40px;
|
|
151
|
+
min-height: 20px;
|
|
152
|
+
border-radius: 12px;
|
|
153
|
+
background-color: gray;
|
|
154
|
+
position: relative;
|
|
155
|
+
cursor: pointer;
|
|
156
|
+
transition: background-color 0.3s;
|
|
157
|
+
margin: 0 10px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.toggle.circle {
|
|
161
|
+
border-radius: 50%;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.toggle.active {
|
|
165
|
+
background-color: green;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.circle-indicator {
|
|
169
|
+
width: 16px;
|
|
170
|
+
height: 16px;
|
|
171
|
+
margin: 0px 2px;
|
|
172
|
+
background-color: white;
|
|
173
|
+
border-radius: 50%;
|
|
174
|
+
transition: transform 0.3s;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.toggle.active .circle-indicator {
|
|
178
|
+
transform: translateX(20px);
|
|
179
|
+
/* Move the circle to the right when active */
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.option-text {
|
|
183
|
+
transition: color 0.3s;
|
|
184
|
+
margin: 0 5px;
|
|
41
185
|
}
|
|
42
186
|
</style>
|
|
43
187
|
</head>
|
|
44
188
|
|
|
45
189
|
<body>
|
|
46
|
-
<h1>Telemetry <span id="telemetryStatusSpan"></span></h1>
|
|
47
|
-
|
|
48
|
-
<label><input type="checkbox" id="toggleTelemetry"> Allow Server Telemetry</label>
|
|
49
|
-
<br><br>
|
|
50
|
-
<button onclick="fetch('/telemetry/reset');showTelemetryStatus();">Reset Telemetry Data</button>
|
|
51
|
-
<br><br>
|
|
52
|
-
<label><input type="checkbox" id="autoUpdate"> Allow Client Auto Update</label>
|
|
53
|
-
<br><br>
|
|
54
|
-
<table id="apiTable">
|
|
55
|
-
<thead>
|
|
56
|
-
<tr>
|
|
57
|
-
<th onclick="sortTable(0)">Path</th>
|
|
58
|
-
<th onclick="sortTable(1)">Method</th>
|
|
59
|
-
<th onclick="sortTable(2)">Status</th>
|
|
60
|
-
<th onclick="sortTable(3)">Description</th>
|
|
61
|
-
<th onclick="sortTable(4)" style="text-align: center;">Request <br> Count</th>
|
|
62
|
-
<th onclick="sortTable(5)" style="text-align: center;">Average response time<br> (sec)</th>
|
|
63
|
-
<th style="text-align: center;">Auto<br>Update</th>
|
|
64
|
-
</tr>
|
|
65
|
-
</thead>
|
|
66
|
-
<tbody>
|
|
67
|
-
</tbody>
|
|
68
|
-
</table>
|
|
69
190
|
|
|
191
|
+
<div class="header">
|
|
192
|
+
<h1>OAS-Telemetry</h1>
|
|
193
|
+
<div class="links">
|
|
194
|
+
<a target="_blank" href="https://github.com/oas-tools/oas-telemetry">Documentation</a>
|
|
195
|
+
<a target="_blank" href="https://www.npmjs.com/package/@oas-tools/oas-telemetry">NPM</a>
|
|
196
|
+
<a target="_blank" href="https://github.com/oas-tools/oas-telemetry">GitHub</a>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="page">
|
|
200
|
+
<div class="panel-conainer">
|
|
201
|
+
<!-- Panel 1 -->
|
|
202
|
+
<div class="panel open" id="panel1">
|
|
203
|
+
<div class="panel-header" onclick="togglePanel('panel1')">Telemetry Management</div>
|
|
204
|
+
<div class="panel-content">
|
|
205
|
+
<div class="spaced-row">
|
|
206
|
+
<div id="toggleTelemetry"></div>
|
|
207
|
+
<button onclick="fetch('/telemetry/reset');fetchTelemetryStatus();">Reset Telemetry
|
|
208
|
+
Data</button>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
213
|
+
<!-- Panel 2 -->
|
|
214
|
+
<div class="panel open" id="panel2">
|
|
215
|
+
<div class="panel-header" onclick="togglePanel('panel2')">Heap Stats</div>
|
|
216
|
+
<div class="panel-content">
|
|
217
|
+
<div class="spaced-row">
|
|
218
|
+
<div id="heapAutoUpdate"></div>
|
|
219
|
+
<button onclick="populateHeapStats()">Update</button>
|
|
220
|
+
</div>
|
|
221
|
+
<table id="heapStatsTable">
|
|
222
|
+
<thead>
|
|
223
|
+
<tr>
|
|
224
|
+
<th>Stat Name</th>
|
|
225
|
+
<th>Value</th>
|
|
226
|
+
</tr>
|
|
227
|
+
</thead>
|
|
228
|
+
<tbody>
|
|
229
|
+
</tbody>
|
|
230
|
+
</table>
|
|
231
|
+
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
<!-- Panel 3 -->
|
|
236
|
+
<div class="panel no-user-select open" id="panel3">
|
|
237
|
+
<div class="panel-header" onclick="togglePanel('panel3')">Telemetry Endpoints</div>
|
|
238
|
+
<div class="panel-content">
|
|
239
|
+
<div class="spaced-row">
|
|
240
|
+
<div id="autoUpdateApiTable"></div>
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<table id="apiTable">
|
|
244
|
+
<thead>
|
|
245
|
+
<tr>
|
|
246
|
+
<th onclick="sortTable(0)">Path</th>
|
|
247
|
+
<th onclick="sortTable(1)">Method</th>
|
|
248
|
+
<th onclick="sortTable(2)">Status</th>
|
|
249
|
+
<th onclick="sortTable(3)">Description</th>
|
|
250
|
+
<th onclick="sortTable(4)" style="text-align: center;">Request Count</th>
|
|
251
|
+
<th onclick="sortTable(5)" style="text-align: center;">Average response time (sec)
|
|
252
|
+
</th>
|
|
253
|
+
<th style="text-align: center;">Options</th>
|
|
254
|
+
</tr>
|
|
255
|
+
</thead>
|
|
256
|
+
<tbody>
|
|
257
|
+
</tbody>
|
|
258
|
+
</table>
|
|
259
|
+
</table>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
<!-- Scripts -->
|
|
265
|
+
<script>
|
|
266
|
+
// Open Close Panel
|
|
267
|
+
function togglePanel(panelId) {
|
|
268
|
+
const panel = document.getElementById(panelId);
|
|
269
|
+
panel.classList.toggle('open');
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Create a toggle component
|
|
273
|
+
* @param {string} title - Title of the toggle
|
|
274
|
+
* @param {string} falseText - Text to display when false
|
|
275
|
+
* @param {string} falseColor - Color of the text when false
|
|
276
|
+
* @param {string} trueText - Text to display when true
|
|
277
|
+
* @param {string} trueColor - Color of the text when true
|
|
278
|
+
* @param {function} handler - Function to call when the toggle is clicked
|
|
279
|
+
* @param {boolean} defaultValue - Default value of the toggle
|
|
280
|
+
* @returns {HTMLDivElement} - The toggle component
|
|
281
|
+
*/
|
|
282
|
+
function createToggle(title, falseText, falseColor, trueText, trueColor, handler, defaultValue = false) {
|
|
283
|
+
const container = document.createElement('div');
|
|
284
|
+
container.className = 'toggle-container';
|
|
285
|
+
|
|
286
|
+
const label = document.createElement('span');
|
|
287
|
+
label.textContent = title + ':';
|
|
288
|
+
label.style.marginRight = '10px';
|
|
289
|
+
|
|
290
|
+
const falseTextSpan = document.createElement('span');
|
|
291
|
+
falseTextSpan.className = 'option-text';
|
|
292
|
+
falseTextSpan.textContent = falseText;
|
|
293
|
+
falseTextSpan.style.color = defaultValue ? 'gray' : falseColor;
|
|
294
|
+
|
|
295
|
+
const toggle = document.createElement('div');
|
|
296
|
+
toggle.className = 'toggle';
|
|
297
|
+
const circleIndicator = document.createElement('div');
|
|
298
|
+
circleIndicator.className = 'circle-indicator';
|
|
299
|
+
toggle.appendChild(circleIndicator);
|
|
300
|
+
|
|
301
|
+
toggle.addEventListener('click', () => {
|
|
302
|
+
toggle.classList.toggle('active');
|
|
303
|
+
const isActive = toggle.classList.contains('active');
|
|
304
|
+
|
|
305
|
+
// Update colors. Not selected option to default color, selected option to active color
|
|
306
|
+
falseTextSpan.style.color = isActive ? 'gray' : falseColor;
|
|
307
|
+
trueTextSpan.style.color = isActive ? trueColor : 'gray';
|
|
308
|
+
|
|
309
|
+
handler(isActive);
|
|
310
|
+
});
|
|
311
|
+
toggle.classList.toggle('active', defaultValue);
|
|
312
|
+
|
|
313
|
+
const trueTextSpan = document.createElement('span');
|
|
314
|
+
trueTextSpan.className = 'option-text';
|
|
315
|
+
trueTextSpan.textContent = trueText; // Always display trueText
|
|
316
|
+
trueTextSpan.style.color = defaultValue ? trueColor : 'gray';
|
|
317
|
+
|
|
318
|
+
container.appendChild(label);
|
|
319
|
+
container.appendChild(falseTextSpan);
|
|
320
|
+
container.appendChild(toggle);
|
|
321
|
+
container.appendChild(trueTextSpan);
|
|
322
|
+
|
|
323
|
+
return container;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const localStorageManager = {
|
|
327
|
+
get: (key) => {
|
|
328
|
+
const value = localStorage.getItem(key);
|
|
329
|
+
return value ? JSON.parse(value) : null;
|
|
330
|
+
},
|
|
331
|
+
set: (key, value) => {
|
|
332
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
</script>
|
|
70
337
|
<script>
|
|
71
|
-
let LOG =
|
|
338
|
+
let LOG = true;
|
|
72
339
|
|
|
73
340
|
|
|
74
341
|
let intervalTimer = {
|
|
@@ -76,7 +343,14 @@ function ui() {
|
|
|
76
343
|
period: 2000,
|
|
77
344
|
subscribers: [],
|
|
78
345
|
start: function () {
|
|
346
|
+
this.disabled = false;
|
|
79
347
|
this.interval = setInterval(() => this.tick(), this.period);
|
|
348
|
+
log("interval started with period: " + this.period);
|
|
349
|
+
},
|
|
350
|
+
stop: function () {
|
|
351
|
+
this.disabled = true;
|
|
352
|
+
clearInterval(this.interval);
|
|
353
|
+
log("interval stopped");
|
|
80
354
|
},
|
|
81
355
|
tick: function () {
|
|
82
356
|
if (this.disabled) return;
|
|
@@ -91,10 +365,6 @@ function ui() {
|
|
|
91
365
|
}
|
|
92
366
|
}
|
|
93
367
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
368
|
function log(s) {
|
|
99
369
|
if (LOG) console.log(s);
|
|
100
370
|
}
|
|
@@ -114,6 +384,17 @@ function ui() {
|
|
|
114
384
|
}
|
|
115
385
|
}
|
|
116
386
|
|
|
387
|
+
async function fetchTelemetryStatus() {
|
|
388
|
+
const response = await fetch("/telemetry/status");
|
|
389
|
+
if (!response.ok) {
|
|
390
|
+
throw new Error("ERROR getting the Status");
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
tStatus = await response.json();
|
|
394
|
+
|
|
395
|
+
log("tStatus: " + JSON.stringify(tStatus, null, 2));
|
|
396
|
+
return tStatus.active;
|
|
397
|
+
}
|
|
117
398
|
|
|
118
399
|
function getPathRegEx(path) {
|
|
119
400
|
let pathComponents = path.split("/");
|
|
@@ -130,7 +411,7 @@ function ui() {
|
|
|
130
411
|
}
|
|
131
412
|
}
|
|
132
413
|
});
|
|
133
|
-
|
|
414
|
+
|
|
134
415
|
// Allow an optional trailing slash
|
|
135
416
|
pathRegExpStr += "/?\$";
|
|
136
417
|
|
|
@@ -244,11 +525,12 @@ function ui() {
|
|
|
244
525
|
cellRequestCount.textContent = requestCount;
|
|
245
526
|
cellAverageResponseTime.textContent = requestCount ? averageResponseTime.toFixed(3) : "--";
|
|
246
527
|
|
|
247
|
-
// setTimeout(() => loadStats(path, method, status, cellRequestCount, cellAverageResponseTime), 2000);
|
|
248
528
|
}
|
|
249
529
|
|
|
250
|
-
function
|
|
530
|
+
async function populateApiTable() {
|
|
531
|
+
const apiSpec = await fetchSpec()
|
|
251
532
|
const tableBody = document.getElementById('apiTable').getElementsByTagName('tbody')[0];
|
|
533
|
+
tableBody.innerHTML = "";
|
|
252
534
|
Object.keys(apiSpec.paths).forEach(path => {
|
|
253
535
|
Object.keys(apiSpec.paths[path]).forEach(method => {
|
|
254
536
|
Object.keys(apiSpec.paths[path][method].responses).forEach(responseType => {
|
|
@@ -279,28 +561,17 @@ function ui() {
|
|
|
279
561
|
+ apiSpec.paths[path][method].responses[responseType].description;
|
|
280
562
|
|
|
281
563
|
row.detailPath = \`/telemetry/detail/\${responseType}/\${method.toLowerCase()}\${fullPath}\`;
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
// Add event listener to handle checkbox auto-update
|
|
294
|
-
checkbox.addEventListener('change', function () {
|
|
295
|
-
if (this.checked)
|
|
296
|
-
intervalTimer.subscribe(() =>
|
|
297
|
-
loadStats(fullPath, method.toLowerCase(), responseType, cellRequestCount, cellAverageResponseTime)
|
|
298
|
-
);
|
|
299
|
-
else
|
|
300
|
-
intervalTimer.unsubscribe(() =>
|
|
301
|
-
loadStats(fullPath, method.toLowerCase(), responseType, cellRequestCount, cellAverageResponseTime)
|
|
302
|
-
);
|
|
303
|
-
});
|
|
564
|
+
const cellOptions = row.insertCell(6);
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
// Create a button for updating the endpoint spaced row but centered
|
|
568
|
+
const updateButton = document.createElement('button');
|
|
569
|
+
updateButton.textContent = "Update";
|
|
570
|
+
updateButton.onclick = () => loadStats(path, method, responseType, cellRequestCount, cellAverageResponseTime);
|
|
571
|
+
cellOptions.appendChild(updateButton);
|
|
572
|
+
cellOptions.style.display = "flex";
|
|
573
|
+
cellOptions.style.justifyContent = "center";
|
|
574
|
+
loadStats(path, method, responseType, cellRequestCount, cellAverageResponseTime);
|
|
304
575
|
|
|
305
576
|
}
|
|
306
577
|
});
|
|
@@ -308,6 +579,24 @@ function ui() {
|
|
|
308
579
|
});
|
|
309
580
|
}
|
|
310
581
|
|
|
582
|
+
function populateHeapStats() {
|
|
583
|
+
// heapstats at /telemetry/heapstats
|
|
584
|
+
const tableBody = document.getElementById('heapStatsTable').getElementsByTagName('tbody')[0];
|
|
585
|
+
fetch('/telemetry/heapstats').then(response => response.json()).then(heapStats => {
|
|
586
|
+
tableBody.innerHTML = "";
|
|
587
|
+
Object.keys(heapStats).forEach(statName => {
|
|
588
|
+
const row = tableBody.insertRow();
|
|
589
|
+
const cellStatName = row.insertCell(0);
|
|
590
|
+
const cellValue = row.insertCell(1);
|
|
591
|
+
cellStatName.textContent = statName;
|
|
592
|
+
//format always to 3 decimals (if number)
|
|
593
|
+
const formattedValue = typeof heapStats[statName] === 'number' ? heapStats[statName].toFixed(3) : heapStats[statName];
|
|
594
|
+
cellValue.textContent = heapStats[statName];
|
|
595
|
+
cellValue.style.textAlign = "right";
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
311
600
|
function sortTable(column) {
|
|
312
601
|
const table = document.getElementById('apiTable');
|
|
313
602
|
let rows, switching, i, x, y, shouldSwitch;
|
|
@@ -331,50 +620,51 @@ function ui() {
|
|
|
331
620
|
}
|
|
332
621
|
}
|
|
333
622
|
|
|
334
|
-
document.getElementById('
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
async function showTelemetryStatus() {
|
|
345
|
-
const tss = document.getElementById("telemetryStatusSpan");
|
|
346
|
-
const response = await fetch("/telemetry/status");
|
|
347
|
-
if (!response.ok) {
|
|
348
|
-
throw new Error("ERROR getting the Status");
|
|
349
|
-
return false;
|
|
623
|
+
document.getElementById('toggleTelemetry').appendChild(createToggle(
|
|
624
|
+
'Telemetry status',
|
|
625
|
+
'Stopped', 'red', // false state
|
|
626
|
+
'Active', 'green', // true state
|
|
627
|
+
async (status) => {
|
|
628
|
+
const response = await fetch('/telemetry/' + (status ? 'start' : 'stop'));
|
|
629
|
+
if (!response.ok) {
|
|
630
|
+
throw new Error("ERROR setting the Telemetry status");
|
|
631
|
+
}
|
|
350
632
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
633
|
+
));
|
|
634
|
+
|
|
635
|
+
document.getElementById('autoUpdateApiTable').appendChild(createToggle(
|
|
636
|
+
'Auto Update',
|
|
637
|
+
'Manual', 'orange', // false state
|
|
638
|
+
'Auto', 'green', // true state
|
|
639
|
+
(status) => {
|
|
640
|
+
const callback = () => { populateApiTable(); };
|
|
641
|
+
if (status) {
|
|
642
|
+
intervalTimer.subscribe(callback);
|
|
643
|
+
} else {
|
|
644
|
+
intervalTimer.unsubscribe(callback);
|
|
645
|
+
}
|
|
360
646
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
647
|
+
));
|
|
648
|
+
|
|
649
|
+
document.getElementById('heapAutoUpdate').appendChild(createToggle(
|
|
650
|
+
'Auto Update',
|
|
651
|
+
'Manual', 'orange', // false state
|
|
652
|
+
'Auto', 'green', // true state
|
|
653
|
+
(status) => {
|
|
654
|
+
if (status) {
|
|
655
|
+
intervalTimer.subscribe(populateHeapStats);
|
|
656
|
+
} else {
|
|
657
|
+
intervalTimer.unsubscribe(populateHeapStats);
|
|
658
|
+
}
|
|
369
659
|
}
|
|
370
|
-
|
|
660
|
+
));
|
|
371
661
|
|
|
372
662
|
window.onload = async function () {
|
|
373
|
-
document.getElementById('
|
|
374
|
-
const activeTelemetry = await
|
|
375
|
-
document.getElementById('toggleTelemetry').
|
|
376
|
-
|
|
377
|
-
|
|
663
|
+
document.getElementById('autoUpdateApiTable').querySelector('.toggle').classList.toggle('active', localStorageManager.get('autoUpdateApiTable'));
|
|
664
|
+
const activeTelemetry = await fetchTelemetryStatus();
|
|
665
|
+
document.getElementById('toggleTelemetry').querySelector('.toggle').classList.toggle('active', activeTelemetry);
|
|
666
|
+
populateApiTable();
|
|
667
|
+
populateHeapStats();
|
|
378
668
|
intervalTimer.start();
|
|
379
669
|
};
|
|
380
670
|
</script>
|