Skip to content

Commit 5a4b329

Browse files
committed
chore(docs): update benchmarks and migrate to bun
Signed-off-by: azjezz <[email protected]>
1 parent af57901 commit 5a4b329

File tree

8 files changed

+621
-1454
lines changed

8 files changed

+621
-1454
lines changed

.github/workflows/cd.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,6 @@ jobs:
199199
if [[ "${{ matrix.job.pgo }}" == "true" ]]; then
200200
cargo pgo build -- --target=${{ matrix.job.target }}
201201
cargo pgo run -- -- --workspace corpus/ analyze --reporting-format count || true
202-
cargo pgo run --keep-profiles -- -- --workspace corpus/ lint --reporting-format count || true
203-
cargo pgo run --keep-profiles -- -- --workspace corpus/ fmt --check || true
204202
cargo pgo optimize -- build --target=${{ matrix.job.target }}
205203
else
206204
$BUILD_CMD build --locked --release --target=${{ matrix.job.target }}

.github/workflows/docs.yml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,15 @@ jobs:
4949
cp crates/wasm/pkg-web/mago_wasm.js docs/public/wasm/
5050
cp crates/wasm/pkg-web/mago_wasm_bg.wasm docs/public/wasm/
5151
52-
- name: Setup Node
53-
uses: actions/setup-node@v4
52+
- uses: oven-sh/setup-bun@v2
5453
with:
55-
node-version: 24
56-
57-
- name: Setup PNPM
58-
uses: pnpm/action-setup@v4
59-
with:
60-
version: 9
54+
bun-version: latest
6155

6256
- name: Install dependencies
63-
run: cd docs && pnpm install --frozen-lockfile
57+
run: cd docs && bun install --frozen-lockfile
6458

6559
- name: Build docs
66-
run: cd docs && pnpm build
60+
run: cd docs && bun build
6761

6862
- name: Upload GitHub Pages artifact
6963
uses: actions/upload-pages-artifact@v3
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
<template>
2+
<div class="benchmark-chart-container" :style="{ height: containerHeight }">
3+
<canvas ref="chartCanvas"></canvas>
4+
</div>
5+
</template>
6+
7+
<script setup>
8+
import { ref, computed, onMounted, watch, onUnmounted } from "vue";
9+
import { Chart, registerables } from "chart.js";
10+
11+
Chart.register(...registerables);
12+
13+
const props = defineProps({
14+
data: {
15+
type: Array,
16+
required: true,
17+
},
18+
unit: {
19+
type: String,
20+
default: "seconds",
21+
},
22+
title: {
23+
type: String,
24+
default: "",
25+
},
26+
});
27+
28+
const chartCanvas = ref(null);
29+
let chartInstance = null;
30+
31+
const containerHeight = computed(() => {
32+
const barHeight = 40;
33+
const titleHeight = props.title ? 50 : 0;
34+
const axisHeight = 40;
35+
const padding = 32;
36+
return `${props.data.length * barHeight + titleHeight + axisHeight + padding}px`;
37+
});
38+
39+
const brandGreen = "#3c8d58";
40+
const brandGreenLight = "#47a467";
41+
const mutedGray = "#6b7280";
42+
const mutedGrayLight = "#9ca3af";
43+
44+
const getColors = (isDark) => {
45+
return props.data.map((item) =>
46+
item.highlight
47+
? isDark
48+
? brandGreenLight
49+
: brandGreen
50+
: isDark
51+
? mutedGrayLight
52+
: mutedGray,
53+
);
54+
};
55+
56+
const createChart = () => {
57+
if (!chartCanvas.value) return;
58+
59+
const isDark = document.documentElement.classList.contains("dark");
60+
const textColor = isDark ? "#e5e7eb" : "#374151";
61+
const gridColor = isDark
62+
? "rgba(255, 255, 255, 0.1)"
63+
: "rgba(0, 0, 0, 0.1)";
64+
65+
const labels = props.data.map((item) => item.label);
66+
const values = props.data.map((item) => item.value);
67+
const colors = getColors(isDark);
68+
69+
if (chartInstance) {
70+
chartInstance.destroy();
71+
}
72+
73+
chartInstance = new Chart(chartCanvas.value, {
74+
type: "bar",
75+
data: {
76+
labels,
77+
datasets: [
78+
{
79+
data: values,
80+
backgroundColor: colors,
81+
borderColor: colors,
82+
borderWidth: 1,
83+
borderRadius: 4,
84+
barThickness: 28,
85+
maxBarThickness: 28,
86+
minBarLength: 8,
87+
},
88+
],
89+
},
90+
options: {
91+
indexAxis: "y",
92+
responsive: true,
93+
maintainAspectRatio: false,
94+
plugins: {
95+
legend: {
96+
display: false,
97+
},
98+
title: {
99+
display: !!props.title,
100+
text: props.title,
101+
color: textColor,
102+
font: {
103+
size: 16,
104+
weight: "600",
105+
},
106+
padding: {
107+
bottom: 16,
108+
},
109+
},
110+
tooltip: {
111+
callbacks: {
112+
label: (context) => {
113+
const value = context.raw;
114+
if (props.unit === "mb") {
115+
return value >= 1000
116+
? `${(value / 1000).toFixed(2)} GB`
117+
: `${value} MB`;
118+
}
119+
if (props.unit === "million") {
120+
return `~${value.toFixed(1)} Million`;
121+
}
122+
// seconds
123+
if (value < 1) {
124+
return `${(value * 1000).toFixed(1)}ms`;
125+
}
126+
return `${value.toFixed(2)}s`;
127+
},
128+
},
129+
},
130+
},
131+
scales: {
132+
x: {
133+
beginAtZero: true,
134+
grid: {
135+
color: gridColor,
136+
},
137+
ticks: {
138+
color: textColor,
139+
callback: (value) => {
140+
if (props.unit === "mb") {
141+
return value >= 1000
142+
? `${(value / 1000).toFixed(1)}GB`
143+
: `${value}MB`;
144+
}
145+
if (props.unit === "million") {
146+
return `${value}M`;
147+
}
148+
// seconds
149+
if (value < 1) {
150+
return `${(value * 1000).toFixed(0)}ms`;
151+
}
152+
return `${value}s`;
153+
},
154+
},
155+
title: {
156+
display: true,
157+
text:
158+
props.unit === "mb"
159+
? "Memory"
160+
: props.unit === "million"
161+
? "Cycles"
162+
: "Time",
163+
color: textColor,
164+
},
165+
},
166+
y: {
167+
grid: {
168+
display: false,
169+
},
170+
ticks: {
171+
color: textColor,
172+
font: {
173+
size: 13,
174+
weight: "500",
175+
},
176+
},
177+
},
178+
},
179+
},
180+
});
181+
};
182+
183+
let observer = null;
184+
185+
onMounted(() => {
186+
createChart();
187+
188+
observer = new MutationObserver((mutations) => {
189+
mutations.forEach((mutation) => {
190+
if (mutation.attributeName === "class") {
191+
createChart();
192+
}
193+
});
194+
});
195+
196+
observer.observe(document.documentElement, {
197+
attributes: true,
198+
attributeFilter: ["class"],
199+
});
200+
});
201+
202+
onUnmounted(() => {
203+
if (chartInstance) {
204+
chartInstance.destroy();
205+
}
206+
if (observer) {
207+
observer.disconnect();
208+
}
209+
});
210+
211+
watch(() => props.data, createChart, { deep: true });
212+
</script>
213+
214+
<style scoped>
215+
.benchmark-chart-container {
216+
width: 100%;
217+
margin: 1.5rem 0;
218+
padding: 1rem;
219+
background: var(--vp-c-bg-soft);
220+
border-radius: 8px;
221+
}
222+
</style>

docs/.vitepress/theme/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import DefaultTheme from "vitepress/theme";
22
import "./custom.css";
33
import MagoPlayground from "./components/playground/MagoPlayground.vue";
4+
import BenchmarkChart from "./components/BenchmarkChart.vue";
45

56
export default {
67
...DefaultTheme,
78
enhanceApp({ app }) {
89
app.component("MagoPlayground", MagoPlayground);
10+
app.component("BenchmarkChart", BenchmarkChart);
911
},
1012
};

0 commit comments

Comments
 (0)