matterbridge 3.3.3-dev-20251014-44bcdc0 → 3.3.3-dev-20251015-19d1be8
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/CHANGELOG.md +11 -0
- package/README-MACOS-PLIST.md +242 -0
- package/README-SERVICE.md +7 -1
- package/README.md +5 -5
- package/dist/cliHistory.js +134 -7
- package/frontend/build/assets/index.css +1 -1
- package/frontend/build/assets/index.js +4 -4
- package/frontend/build/assets/vendor_mui.js +6 -6
- package/frontend/package.json +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -25,9 +25,20 @@ Advantages:
|
|
|
25
25
|
|
|
26
26
|
## [3.3.3] - Not released
|
|
27
27
|
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- [thread]: Added timestamp to WorkerMessage.
|
|
31
|
+
- [macOS]: Added the [plist configuration guide](README-MACOS-PLIST.md).
|
|
32
|
+
|
|
28
33
|
### Changed
|
|
29
34
|
|
|
30
35
|
- [package]: Updated dependencies.
|
|
36
|
+
- [frontend]: Bumped `frontend` version to 3.2.2.
|
|
37
|
+
- [frontend]: Added update check on start.
|
|
38
|
+
- [frontend]: Added icon to update dev in the Header and removed the yellow badges.
|
|
39
|
+
- [frontend]: Added icon to update plugin latest and dev and removed the yellow badges.
|
|
40
|
+
- [frontend]: Added plugin Path in the Name Tooltip.
|
|
41
|
+
- [history]: Added external and array buffers to the history chart.
|
|
31
42
|
|
|
32
43
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
33
44
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# <img src="frontend/public/matterbridge.svg" alt="Matterbridge Logo" width="64px" height="64px"> Matterbridge launchctl configuration (macOS)
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/matterbridge)
|
|
4
|
+
[](https://www.npmjs.com/package/matterbridge)
|
|
5
|
+
[](https://hub.docker.com/r/luligu/matterbridge)
|
|
6
|
+
[](https://hub.docker.com/r/luligu/matterbridge)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
[](https://codecov.io/gh/Luligu/matterbridge)
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/matter-history)
|
|
12
|
+
[](https://www.npmjs.com/package/node-ansi-logger)
|
|
13
|
+
[](https://www.npmjs.com/package/node-persist-manager)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Advanced configuration
|
|
18
|
+
|
|
19
|
+
## Run matterbridge as system service with launchctl (macOS) and its own global node_modules directory
|
|
20
|
+
|
|
21
|
+
### Optional: cleanup all previous setups
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
sudo rm -rf ~/Matterbridge
|
|
25
|
+
sudo rm -rf ~/.matterbridge
|
|
26
|
+
sudo rm -rf ~/.mattercert
|
|
27
|
+
sudo rm -rf /usr/local/etc/matterbridge
|
|
28
|
+
sudo rm -f /Library/LaunchDaemons/matterbridge.plist
|
|
29
|
+
sudo rm -f /var/log/matterbridge.log /var/log/matterbridge.err
|
|
30
|
+
sudo npm uninstall matterbridge -g
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Verify node setup
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
node -v
|
|
37
|
+
npm -v
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
It should output something like:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
v22.20.0
|
|
44
|
+
10.9.3
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Check node path
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
which node
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
It should output something like:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
/usr/local/bin/node
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
In this case you will need in the step below to replace **_MYNODEPATH_** with /usr/local/bin
|
|
60
|
+
|
|
61
|
+
### First create the Matterbridge directories
|
|
62
|
+
|
|
63
|
+
This will create the required directories if they don't exist and install matterbridge in the matterbridge global node_modules directory
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
sudo mkdir -p /usr/local/etc/matterbridge
|
|
67
|
+
sudo mkdir -p /usr/local/etc/matterbridge/.npm-global
|
|
68
|
+
sudo mkdir -p /usr/local/etc/matterbridge/Matterbridge
|
|
69
|
+
sudo mkdir -p /usr/local/etc/matterbridge/.matterbridge
|
|
70
|
+
sudo mkdir -p /usr/local/etc/matterbridge/.mattercert
|
|
71
|
+
sudo chown -R root:wheel /usr/local/etc/matterbridge
|
|
72
|
+
sudo chown -R root:wheel /usr/local/etc/matterbridge/.npm-global
|
|
73
|
+
sudo chmod -R 755 /usr/local/etc/matterbridge/.npm-global
|
|
74
|
+
sudo NPM_CONFIG_PREFIX=/usr/local/etc/matterbridge/.npm-global npm install -g matterbridge --omit=dev
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Then create a system launchctl configuration file for Matterbridge
|
|
78
|
+
|
|
79
|
+
- create a launchctl configuration file for Matterbridge
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
sudo nano /Library/LaunchDaemons/matterbridge.plist
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- add the following to the file, replacing **_MYNODEPATH_** with the path found in the step before:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
89
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
90
|
+
<plist version="1.0">
|
|
91
|
+
<dict>
|
|
92
|
+
<key>EnvironmentVariables</key>
|
|
93
|
+
<dict>
|
|
94
|
+
<key>PATH</key>
|
|
95
|
+
<string>/usr/local/etc/matterbridge/.npm-global/bin:MYNODEPATH</string>
|
|
96
|
+
<key>NPM_CONFIG_PREFIX</key>
|
|
97
|
+
<string>/usr/local/etc/matterbridge/.npm-global</string>
|
|
98
|
+
<key>HOME</key>
|
|
99
|
+
<string>/var/root</string>
|
|
100
|
+
<key>NODE_PATH</key>
|
|
101
|
+
<string>/usr/local/etc/matterbridge/.npm-global/lib/node_modules</string>
|
|
102
|
+
</dict>
|
|
103
|
+
<key>KeepAlive</key>
|
|
104
|
+
<true/>
|
|
105
|
+
<key>Label</key>
|
|
106
|
+
<string>matterbridge</string>
|
|
107
|
+
<key>ProgramArguments</key>
|
|
108
|
+
<array>
|
|
109
|
+
<string>/usr/local/etc/matterbridge/.npm-global/bin/matterbridge</string>
|
|
110
|
+
<string>--homedir</string>
|
|
111
|
+
<string>/usr/local/etc/matterbridge</string>
|
|
112
|
+
<string>--service</string>
|
|
113
|
+
<string>--nosudo</string>
|
|
114
|
+
</array>
|
|
115
|
+
<key>RunAtLoad</key>
|
|
116
|
+
<true/>
|
|
117
|
+
<key>StandardErrorPath</key>
|
|
118
|
+
<string>/var/log/matterbridge.err</string>
|
|
119
|
+
<key>StandardOutPath</key>
|
|
120
|
+
<string>/var/log/matterbridge.log</string>
|
|
121
|
+
<key>WorkingDirectory</key>
|
|
122
|
+
<string>/usr/local/etc/matterbridge</string>
|
|
123
|
+
</dict>
|
|
124
|
+
</plist>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- stop matterbridge
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
sudo launchctl bootout system/matterbridge
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- check the plist
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
sudo chown root:wheel /Library/LaunchDaemons/matterbridge.plist
|
|
137
|
+
sudo chmod 644 /Library/LaunchDaemons/matterbridge.plist
|
|
138
|
+
sudo plutil -lint /Library/LaunchDaemons/matterbridge.plist
|
|
139
|
+
sudo plutil -convert xml1 /Library/LaunchDaemons/matterbridge.plist
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
- bootstrap matterbridge and enable it
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
sudo rm -f /var/log/matterbridge.log /var/log/matterbridge.err
|
|
146
|
+
sudo launchctl bootstrap system /Library/LaunchDaemons/matterbridge.plist
|
|
147
|
+
sudo launchctl enable system/matterbridge
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Start Matterbridge
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
sudo launchctl kickstart -k system/matterbridge
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Stop Matterbridge
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
sudo launchctl bootout system/matterbridge
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Restart Matterbridge
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
sudo launchctl kickstart -k system/matterbridge
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Show Matterbridge status
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
sudo launchctl print system/matterbridge
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Show Matterbridge status (only essentials)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
sudo launchctl print system/matterbridge | grep -E "pid|state"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Enable Matterbridge to start automatically on boot
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
sudo launchctl enable system/matterbridge
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Disable Matterbridge from starting automatically on boot
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
sudo launchctl disable system/matterbridge
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### View the log of Matterbridge in real time (this will show the log with colors)
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
sudo tail -n 1000 -f /var/log/matterbridge.log /var/log/matterbridge.err
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Automatically rotate logs (every 5 days or at 100 MB, keep 5 compressed backups)
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
sudo tee /etc/newsyslog.d/matterbridge.conf <<'EOF'
|
|
202
|
+
/var/log/matterbridge.log root:wheel 640 5 102400 5 Z
|
|
203
|
+
/var/log/matterbridge.err root:wheel 640 5 102400 5 Z
|
|
204
|
+
EOF
|
|
205
|
+
sudo newsyslog -v
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Optional: remove the password prompt for sudo
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
sudo EDITOR=nano visudo
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Add this line at the end of the file (replace USER with your macOS username):
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
USER ALL=(ALL) NOPASSWD: ALL
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Save and validate syntax:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
sudo visudo -c
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Optional: ask for password only each 60 minutes
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
sudo EDITOR=nano visudo
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Add (or edit) this line anywhere in the file:
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
Defaults timestamp_timeout = 60
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Save and validate syntax:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
sudo visudo -c
|
|
242
|
+
```
|
package/README-SERVICE.md
CHANGED
|
@@ -169,7 +169,7 @@ sudo systemctl restart systemd-journald
|
|
|
169
169
|
Run the following command to verify if you can install Matterbridge globally without being prompted for a password:
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
sudo npm install -g matterbridge
|
|
172
|
+
sudo npm install -g matterbridge --omit=dev
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
If you are not prompted for a password, no further action is required.
|
|
@@ -210,3 +210,9 @@ save the file and reload the settings with:
|
|
|
210
210
|
sudo chmod 0440 /etc/sudoers.d/matterbridge
|
|
211
211
|
sudo visudo -c
|
|
212
212
|
```
|
|
213
|
+
|
|
214
|
+
Verify if you can install Matterbridge globally without being prompted for a password:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
sudo npm install -g matterbridge --omit=dev
|
|
218
|
+
```
|
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ Since Matter is designed as "a universal IPv6-based communication protocol for s
|
|
|
84
84
|
|
|
85
85
|
Avoid using VLAN and firewall blocking the communications between the controllers and Matterbridge.
|
|
86
86
|
|
|
87
|
-
To pair matterbridge, you need a matter enabled controller (Apple Home, Smart Things, Google Home, Alexa,
|
|
87
|
+
To pair matterbridge, you need a matter enabled controller (Apple Home, Smart Things, Google Home, Alexa, Home Assistant etc.).
|
|
88
88
|
|
|
89
89
|
## Installation
|
|
90
90
|
|
|
@@ -172,6 +172,10 @@ Config editor:
|
|
|
172
172
|
|
|
173
173
|
[Service configurations](README-SERVICE.md)
|
|
174
174
|
|
|
175
|
+
### Run matterbridge as a system service with launchctl (macOS only)
|
|
176
|
+
|
|
177
|
+
[Launchctl configurations](README-MACOS-PLIST.md)
|
|
178
|
+
|
|
175
179
|
### Run matterbridge with docker and docker compose
|
|
176
180
|
|
|
177
181
|
[Docker configurations](README-DOCKER.md)
|
|
@@ -180,10 +184,6 @@ Config editor:
|
|
|
180
184
|
|
|
181
185
|
[Podman configurations](README-PODMAN.md)
|
|
182
186
|
|
|
183
|
-
### Run matterbridge as a service on macOS with mb-service (by [Michael Ahern](https://github.com/michaelahern))
|
|
184
|
-
|
|
185
|
-
[Matterbridge Service Command for macOS](https://github.com/michaelahern/mb-service)
|
|
186
|
-
|
|
187
187
|
### Run matterbridge with nginx
|
|
188
188
|
|
|
189
189
|
[Nginx configurations](README-NGINX.md)
|
package/dist/cliHistory.js
CHANGED
|
@@ -2,7 +2,7 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
|
|
|
2
2
|
console.log('\u001B[32mCli history loaded.\u001B[40;0m');
|
|
3
3
|
import { writeFileSync } from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
export const historySize =
|
|
5
|
+
export const historySize = 2880;
|
|
6
6
|
export let historyIndex = 0;
|
|
7
7
|
export function setHistoryIndex(index) {
|
|
8
8
|
if (!Number.isFinite(index) || !Number.isSafeInteger(index)) {
|
|
@@ -70,10 +70,12 @@ export function generateHistoryPage(options = {}) {
|
|
|
70
70
|
peakArrayBuffers,
|
|
71
71
|
};
|
|
72
72
|
const html = `<!DOCTYPE html>
|
|
73
|
-
<html lang="en">
|
|
73
|
+
<html lang="en" translate="no">
|
|
74
74
|
<head>
|
|
75
75
|
<meta charset="UTF-8" />
|
|
76
76
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
77
|
+
<meta name="google" content="notranslate" />
|
|
78
|
+
<meta http-equiv="Content-Language" content="en" />
|
|
77
79
|
<title>${escapeHtml(pageTitle)}</title>
|
|
78
80
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
79
81
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
@@ -251,6 +253,11 @@ export function generateHistoryPage(options = {}) {
|
|
|
251
253
|
<canvas id="memoryChart"></canvas>
|
|
252
254
|
</section>
|
|
253
255
|
|
|
256
|
+
<section class="card">
|
|
257
|
+
<h2>External and Array Buffers (MB)</h2>
|
|
258
|
+
<canvas id="extArrayChart"></canvas>
|
|
259
|
+
</section>
|
|
260
|
+
|
|
254
261
|
<section class="card">
|
|
255
262
|
<h2>Samples</h2>
|
|
256
263
|
<div class="table-wrapper">
|
|
@@ -371,6 +378,31 @@ export function generateHistoryPage(options = {}) {
|
|
|
371
378
|
}, 0);
|
|
372
379
|
const memoryMaxYAxis = Number.isFinite(memoryMaxMb) && memoryMaxMb > 0 ? memoryMaxMb * 1.05 : undefined;
|
|
373
380
|
|
|
381
|
+
// Compute External/ArrayBuffers chart dynamic min/max
|
|
382
|
+
const extArrayMinMb = HISTORY_DATA.reduce(function (acc, entry) {
|
|
383
|
+
const values = [entry.external, entry.arrayBuffers].map(bytesToMb);
|
|
384
|
+
const finiteValues = values.filter(function (v) { return Number.isFinite(v); });
|
|
385
|
+
const minEntry = finiteValues.length ? Math.min.apply(Math, finiteValues) : acc;
|
|
386
|
+
return Math.min(acc, minEntry);
|
|
387
|
+
}, Number.POSITIVE_INFINITY);
|
|
388
|
+
|
|
389
|
+
const extArrayMinYAxis = Number.isFinite(extArrayMinMb) && extArrayMinMb > 0
|
|
390
|
+
? Math.max(0, extArrayMinMb - extArrayMinMb * 0.1)
|
|
391
|
+
: 0;
|
|
392
|
+
|
|
393
|
+
const extArrayMaxMb = HISTORY_DATA.reduce(function (acc, entry) {
|
|
394
|
+
const values = [
|
|
395
|
+
entry.external,
|
|
396
|
+
entry.arrayBuffers,
|
|
397
|
+
entry.peakExternal,
|
|
398
|
+
entry.peakArrayBuffers,
|
|
399
|
+
].map(bytesToMb);
|
|
400
|
+
const finiteValues = values.filter(function (v) { return Number.isFinite(v); });
|
|
401
|
+
const maxEntry = finiteValues.length ? Math.max.apply(Math, finiteValues) : acc;
|
|
402
|
+
return Math.max(acc, maxEntry);
|
|
403
|
+
}, 0);
|
|
404
|
+
const extArrayMaxYAxis = Number.isFinite(extArrayMaxMb) && extArrayMaxMb > 0 ? extArrayMaxMb * 1.05 : undefined;
|
|
405
|
+
|
|
374
406
|
renderCharts();
|
|
375
407
|
|
|
376
408
|
function renderCharts() {
|
|
@@ -386,7 +418,14 @@ export function generateHistoryPage(options = {}) {
|
|
|
386
418
|
return Number.isFinite(entry.cpu) ? Number(entry.cpu.toFixed(2)) : 0;
|
|
387
419
|
}),
|
|
388
420
|
color: '#38bdf8',
|
|
389
|
-
fill: 'rgba(56, 189, 248, 0.18)'
|
|
421
|
+
fill: 'rgba(56, 189, 248, 0.18)',
|
|
422
|
+
markPeaks: true,
|
|
423
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
424
|
+
if (Number.isFinite(entry.peakCpu)) return entry.peakCpu;
|
|
425
|
+
if (Number.isFinite(entry.cpu)) return entry.cpu;
|
|
426
|
+
return Number.NEGATIVE_INFINITY;
|
|
427
|
+
}),
|
|
428
|
+
markerRadius: 2.5
|
|
390
429
|
},
|
|
391
430
|
{
|
|
392
431
|
label: 'Host Peak CPU %',
|
|
@@ -413,7 +452,14 @@ export function generateHistoryPage(options = {}) {
|
|
|
413
452
|
return Number.isFinite(entry.processCpu) ? Number(entry.processCpu.toFixed(2)) : 0;
|
|
414
453
|
}),
|
|
415
454
|
color: '#a855f7',
|
|
416
|
-
fill: 'rgba(168, 85, 247, 0.18)'
|
|
455
|
+
fill: 'rgba(168, 85, 247, 0.18)',
|
|
456
|
+
markPeaks: true,
|
|
457
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
458
|
+
if (Number.isFinite(entry.peakProcessCpu)) return entry.peakProcessCpu;
|
|
459
|
+
if (Number.isFinite(entry.processCpu)) return entry.processCpu;
|
|
460
|
+
return Number.NEGATIVE_INFINITY;
|
|
461
|
+
}),
|
|
462
|
+
markerRadius: 2.5
|
|
417
463
|
},
|
|
418
464
|
{
|
|
419
465
|
label: 'Process Peak CPU %',
|
|
@@ -444,17 +490,38 @@ export function generateHistoryPage(options = {}) {
|
|
|
444
490
|
label: 'RSS (MB)',
|
|
445
491
|
values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.rss); }),
|
|
446
492
|
color: '#34d399',
|
|
447
|
-
fill: 'rgba(52, 211, 153, 0.18)'
|
|
493
|
+
fill: 'rgba(52, 211, 153, 0.18)',
|
|
494
|
+
markPeaks: true,
|
|
495
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
496
|
+
if (Number.isFinite(entry.peakRss)) return entry.peakRss;
|
|
497
|
+
if (Number.isFinite(entry.rss)) return entry.rss;
|
|
498
|
+
return Number.NEGATIVE_INFINITY;
|
|
499
|
+
}),
|
|
500
|
+
markerRadius: 2.5
|
|
448
501
|
},
|
|
449
502
|
{
|
|
450
503
|
label: 'Heap Total (MB)',
|
|
451
504
|
values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.heapTotal); }),
|
|
452
|
-
color: '#fb923c'
|
|
505
|
+
color: '#fb923c',
|
|
506
|
+
markPeaks: true,
|
|
507
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
508
|
+
if (Number.isFinite(entry.peakHeapTotal)) return entry.peakHeapTotal;
|
|
509
|
+
if (Number.isFinite(entry.heapTotal)) return entry.heapTotal;
|
|
510
|
+
return Number.NEGATIVE_INFINITY;
|
|
511
|
+
}),
|
|
512
|
+
markerRadius: 2.5
|
|
453
513
|
},
|
|
454
514
|
{
|
|
455
515
|
label: 'Heap Used (MB)',
|
|
456
516
|
values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.heapUsed); }),
|
|
457
|
-
color: '#f472b6'
|
|
517
|
+
color: '#f472b6',
|
|
518
|
+
markPeaks: true,
|
|
519
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
520
|
+
if (Number.isFinite(entry.peakHeapUsed)) return entry.peakHeapUsed;
|
|
521
|
+
if (Number.isFinite(entry.heapUsed)) return entry.heapUsed;
|
|
522
|
+
return Number.NEGATIVE_INFINITY;
|
|
523
|
+
}),
|
|
524
|
+
markerRadius: 2.5
|
|
458
525
|
}
|
|
459
526
|
],
|
|
460
527
|
minY: memoryMinYAxis,
|
|
@@ -463,6 +530,43 @@ export function generateHistoryPage(options = {}) {
|
|
|
463
530
|
return value.toFixed(0) + ' MB';
|
|
464
531
|
}
|
|
465
532
|
});
|
|
533
|
+
|
|
534
|
+
// External and Array Buffers chart
|
|
535
|
+
renderLineChart('extArrayChart', {
|
|
536
|
+
labels: labels,
|
|
537
|
+
datasets: [
|
|
538
|
+
{
|
|
539
|
+
label: 'External (MB)',
|
|
540
|
+
values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.external); }),
|
|
541
|
+
color: '#60a5fa',
|
|
542
|
+
fill: 'rgba(96, 165, 250, 0.18)',
|
|
543
|
+
markPeaks: true,
|
|
544
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
545
|
+
if (Number.isFinite(entry.peakExternal)) return entry.peakExternal;
|
|
546
|
+
if (Number.isFinite(entry.external)) return entry.external;
|
|
547
|
+
return Number.NEGATIVE_INFINITY;
|
|
548
|
+
}),
|
|
549
|
+
markerRadius: 2.5
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
label: 'Array Buffers (MB)',
|
|
553
|
+
values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.arrayBuffers); }),
|
|
554
|
+
color: '#22d3ee',
|
|
555
|
+
markPeaks: true,
|
|
556
|
+
markerPeakValues: HISTORY_DATA.map(function (entry) {
|
|
557
|
+
if (Number.isFinite(entry.peakArrayBuffers)) return entry.peakArrayBuffers;
|
|
558
|
+
if (Number.isFinite(entry.arrayBuffers)) return entry.arrayBuffers;
|
|
559
|
+
return Number.NEGATIVE_INFINITY;
|
|
560
|
+
}),
|
|
561
|
+
markerRadius: 2.5
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
minY: extArrayMinYAxis,
|
|
565
|
+
maxY: extArrayMaxYAxis,
|
|
566
|
+
yFormatter: function (value) {
|
|
567
|
+
return value.toFixed(0) + ' MB';
|
|
568
|
+
}
|
|
569
|
+
});
|
|
466
570
|
}
|
|
467
571
|
|
|
468
572
|
draw();
|
|
@@ -634,6 +738,29 @@ export function generateHistoryPage(options = {}) {
|
|
|
634
738
|
});
|
|
635
739
|
ctx.stroke();
|
|
636
740
|
ctx.setLineDash([]);
|
|
741
|
+
|
|
742
|
+
// Draw new-peak markers if enabled
|
|
743
|
+
if (dataset.markPeaks) {
|
|
744
|
+
let runningMax = -Infinity;
|
|
745
|
+
const radius = Number.isFinite(dataset.markerRadius) ? dataset.markerRadius : 2.5;
|
|
746
|
+
ctx.save();
|
|
747
|
+
ctx.fillStyle = dataset.markerColor || dataset.color;
|
|
748
|
+
ctx.strokeStyle = 'rgba(255, 255, 255, 0.85)';
|
|
749
|
+
ctx.lineWidth = 1;
|
|
750
|
+
const peakSeries = Array.isArray(dataset.markerPeakValues) ? dataset.markerPeakValues : dataset.values;
|
|
751
|
+
peakSeries.forEach(function (value, idx) {
|
|
752
|
+
if (!Number.isFinite(value)) return;
|
|
753
|
+
if (value > runningMax) {
|
|
754
|
+
runningMax = value;
|
|
755
|
+
const p = points[idx];
|
|
756
|
+
ctx.beginPath();
|
|
757
|
+
ctx.arc(p.x, p.y, radius, 0, Math.PI * 2);
|
|
758
|
+
ctx.fill();
|
|
759
|
+
ctx.stroke();
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
ctx.restore();
|
|
763
|
+
}
|
|
637
764
|
});
|
|
638
765
|
|
|
639
766
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center}.nav-link{margin:0
|
|
1
|
+
body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center;gap:10px}.nav-link{margin:0;font-size:20px;text-decoration:none;color:var(--main-icon-color);transition:color .3s ease}.nav-link:hover{color:var(--primary-color)}table{border-collapse:collapse;width:100%;table-layout:auto}thead{position:sticky;top:0;border:1px solid var(--table-border-color);z-index:10}thead th{border:1px solid var(--table-border-color);padding:5px 10px;color:var(--header-text-color);background:var(--header-bg-color);text-align:left;z-index:10}tbody td{border:1px solid var(--table-border-color);margin:0;padding:5px 10px;text-align:left;font-size:14px}tbody tr:hover{color:var(--table-text-color);background-color:var(--table-hover-bg-color)}.table-content-even{color:var(--table-text-color);background-color:var(--table-even-bg-color)}.table-content-odd{color:var(--table-text-color);background-color:var(--table-odd-bg-color)}.table-content-selected{color:var(--table-text-color);background-color:var(--table-selected-bg-color)}h3{margin:0}.MbfScreen{display:flex;flex-direction:column;width:calc(100vw - 40px);height:calc(100vh - 40px);gap:20px;margin:0;padding:20px;background-color:var(--main-bg-color)}.MbfPageDiv{display:flex;flex-direction:column;height:100%;width:100%;margin:0;padding:0;gap:20px}.MbfWindowDiv{display:flex;flex-direction:column;box-shadow:5px 5px 10px var(--div-shadow-color);border:1px solid var(--table-border-color);border-radius:var(--div-border-radius);box-sizing:border-box;background-color:var(--div-bg-color)}.MbfWindowDivTable{display:flex;flex-direction:column;flex:1 1 auto;margin:-1px;padding:0;gap:0;overflow:auto;display:block}.MbfWindowHeaderFooterIcons{display:flex;flex-direction:row;margin:0;padding:0 10px;gap:10px}.MbfWindowHeader{display:flex;flex-direction:row;align-items:center;width:100%;border-bottom:1px solid var(--table-border-color);color:var(--header-text-color);background-color:var(--header-bg-color);margin:0;padding:0;box-sizing:border-box}.MbfWindowHeaderText{color:var(--header-text-color);font-weight:700;margin:0;padding:5px 10px}.MbfWindowFooter{display:flex;flex-direction:row;align-items:center;justify-content:center;color:var(--footer-text-color);background-color:var(--footer-bg-color);margin:0;padding:0}.MbfWindowFooterText{color:var(--footer-text-color);background-color:var(--footer-bg-color);font-weight:700;text-align:center;margin:0;padding:5px 10px}.MbfWindowBody{display:flex;flex:1 1 auto;margin:0;padding:10px;gap:10px}.MbfWindowBodyColumn{display:flex;flex-direction:column;flex:1 1 auto;width:100%;margin:0;padding:10px 0;gap:0px;overflow:auto}.MbfWindowBodyRow{display:flex;flex-direction:row;flex:1 1 auto;height:100%;margin:0;padding:0 10px;gap:0px;overflow:auto}.configSubmitButton{display:flex;flex-direction:row;justify-content:center;width:auto;margin:20px}.configSubmitButton button{width:auto}@media (max-width: 1300px){.MbfScreen{width:1300px;height:1024px}.xxxheader{flex-direction:column;align-items:start;justify-content:start}.xxxsub-header{align-items:start;justify-content:start}}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}
|