@@ -2,9 +2,7 @@ import { Metadata } from "next";
22import { Card , CardContent } from "@/components/ui/card" ;
33import { Button } from "@/components/ui/button" ;
44import Link from "next/link" ;
5- import { readFileSync , readdirSync , statSync , existsSync } from 'fs' ;
6- import { join , extname } from 'path' ;
7- import matter from 'gray-matter' ;
5+ import { getAllBenchmarks } from "@/lib/benchmarks" ;
86
97export const metadata : Metadata = {
108 title : "RunMat Benchmarks - Performance Comparisons" ,
@@ -16,164 +14,6 @@ export const metadata: Metadata = {
1614 } ,
1715} ;
1816
19- interface Benchmark {
20- slug : string ;
21- title : string ;
22- description : string ;
23- summary : string ;
24- imageUrl ?: string ;
25- date : string ;
26- readTime : string ;
27- author : string ;
28- tags : string [ ] ;
29- }
30-
31- function extractTitleFromMarkdown ( content : string ) : string {
32- const lines = content . split ( '\n' ) ;
33- for ( const line of lines ) {
34- const trimmed = line . trim ( ) ;
35- if ( trimmed . startsWith ( '# ' ) ) {
36- return trimmed . substring ( 2 ) . trim ( ) ;
37- }
38- }
39- return 'Untitled Benchmark' ;
40- }
41-
42- function extractFirstParagraph ( content : string ) : string {
43- const lines = content . split ( '\n' ) ;
44- let inParagraph = false ;
45- const paragraphLines : string [ ] = [ ] ;
46-
47- for ( const line of lines ) {
48- const trimmed = line . trim ( ) ;
49- if ( trimmed . startsWith ( '#' ) ) {
50- if ( inParagraph ) break ;
51- continue ;
52- }
53- if ( ! trimmed && ! inParagraph ) continue ;
54- if ( trimmed ) {
55- inParagraph = true ;
56- paragraphLines . push ( trimmed ) ;
57- } else if ( inParagraph ) {
58- break ;
59- }
60- }
61-
62- const paragraph = paragraphLines . join ( ' ' ) ;
63- return paragraph || 'Performance benchmark comparing RunMat against alternatives.' ;
64- }
65-
66- function truncateText ( text : string , limit : number = 200 ) : string {
67- if ( text . length <= limit ) {
68- return text ;
69- }
70- return text . substring ( 0 , limit ) . trimEnd ( ) + '...' ;
71- }
72-
73- function extractFirstImageUrl ( content : string ) : string | undefined {
74- const imageRegex = / ! \[ [ ^ \] ] * \] \( ( [ ^ ) \s ] + ) (?: \s + " [ ^ " ] * " ) ? \) / ;
75- const match = imageRegex . exec ( content ) ;
76- return match ? match [ 1 ] : undefined ;
77- }
78-
79- function getMimeTypeFromExtension ( extension : string ) : string | undefined {
80- switch ( extension . toLowerCase ( ) ) {
81- case '.png' :
82- return 'image/png' ;
83- case '.jpg' :
84- case '.jpeg' :
85- return 'image/jpeg' ;
86- case '.svg' :
87- return 'image/svg+xml' ;
88- case '.webp' :
89- return 'image/webp' ;
90- default :
91- return undefined ;
92- }
93- }
94-
95- function getAllBenchmarks ( ) : Benchmark [ ] {
96- try {
97- const benchmarksDir = join ( process . cwd ( ) , '..' , 'benchmarks' ) ;
98- const entries = readdirSync ( benchmarksDir , { withFileTypes : true } ) ;
99-
100- const benchmarks = entries
101- . filter ( entry => entry . isDirectory ( ) && entry . name !== '.harness' && entry . name !== 'wgpu_profile' )
102- . map ( ( entry ) : Benchmark | null => {
103- const slug = entry . name ;
104- const readmePath = join ( benchmarksDir , slug , 'README.md' ) ;
105-
106- try {
107- const fileContent = readFileSync ( readmePath , 'utf-8' ) ;
108- const { data : frontmatter , content } = matter ( fileContent ) ;
109-
110- // Extract title from frontmatter or first heading
111- const title = frontmatter . title || extractTitleFromMarkdown ( content ) ;
112-
113- // Extract description from frontmatter or first paragraph
114- const rawDescription = frontmatter . description || frontmatter . excerpt || extractFirstParagraph ( content ) ;
115- const description = rawDescription || 'Performance benchmark comparing RunMat against alternatives.' ;
116- const summary = truncateText ( description ) ;
117-
118- const frontmatterImage = typeof frontmatter . image === 'string' ? frontmatter . image : undefined ;
119- const markdownImage = extractFirstImageUrl ( content ) ;
120- const resolvedImagePath = frontmatterImage || markdownImage ;
121-
122- let imageUrl : string | undefined ;
123- if ( resolvedImagePath ) {
124- if ( resolvedImagePath . startsWith ( 'http://' ) || resolvedImagePath . startsWith ( 'https://' ) ) {
125- imageUrl = resolvedImagePath ;
126- } else {
127- const sanitizedPath = resolvedImagePath . replace ( / ^ \. ? \/ / , '' ) ;
128- const absolutePath = join ( benchmarksDir , slug , sanitizedPath ) ;
129- if ( existsSync ( absolutePath ) ) {
130- const mimeType = getMimeTypeFromExtension ( extname ( absolutePath ) ) ;
131- if ( mimeType ) {
132- const fileBuffer = readFileSync ( absolutePath ) ;
133- const base64 = fileBuffer . toString ( 'base64' ) ;
134- imageUrl = `data:${ mimeType } ;base64,${ base64 } ` ;
135- }
136- }
137- }
138- }
139-
140- // Get file modification date as fallback
141- const stats = statSync ( readmePath ) ;
142- const defaultDate = stats . mtime . toISOString ( ) ;
143-
144- return {
145- slug,
146- title,
147- description,
148- summary,
149- imageUrl,
150- date : frontmatter . date || defaultDate ,
151- readTime : frontmatter . readTime || '5 min read' ,
152- author : frontmatter . author || 'RunMat Team' ,
153- tags : frontmatter . tags || [ ]
154- } ;
155- } catch ( error ) {
156- console . error ( `Error reading benchmark ${ slug } :` , error ) ;
157- return null ;
158- }
159- } )
160- . filter ( ( benchmark ) : benchmark is Benchmark => benchmark !== null ) ;
161-
162- // Sort by date (newest first) or alphabetically if no date
163- return benchmarks . sort ( ( a , b ) => {
164- const dateA = new Date ( a . date ) . getTime ( ) ;
165- const dateB = new Date ( b . date ) . getTime ( ) ;
166- if ( dateA !== dateB ) {
167- return dateB - dateA ;
168- }
169- return a . title . localeCompare ( b . title ) ;
170- } ) ;
171- } catch ( error ) {
172- console . error ( 'Error reading benchmarks:' , error ) ;
173- return [ ] ;
174- }
175- }
176-
17717export default function BenchmarksPage ( ) {
17818 const benchmarks = getAllBenchmarks ( ) ;
17919
@@ -270,4 +110,3 @@ export default function BenchmarksPage() {
270110 </ div >
271111 ) ;
272112}
273-
0 commit comments