'use client'; import { useState, useEffect } from 'react'; import * as duckdb from '@duckdb/duckdb-wasm'; type ModelData = { ancestor: string; direct_children: string[] | null; all_children: string[]; all_children_count: number; direct_children_count: number | null; }; export default function Home() { const [allModels, setAllModels] = useState([]); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(100); const [filterText, setFilterText] = useState(''); const [isLoading, setIsLoading] = useState(true); const [orderBy, setOrderBy] = useState<'all_children' | 'direct_children'>('all_children'); useEffect(() => { async function fetchData() { const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles(); // Select a bundle based on browser checks const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES); const worker_url = URL.createObjectURL( new Blob([`importScripts("${bundle.mainWorker!}");`], { type: 'text/javascript' }) ); // Instantiate the asynchronous version of DuckDB-Wasm const worker = new Worker(worker_url); const logger = new duckdb.ConsoleLogger(); const db = new duckdb.AsyncDuckDB(logger, worker); await db.instantiate(bundle.mainModule, bundle.pthreadWorker); // Register the Parquet file using the URL await db.registerFileURL( 'ancestor_children.parquet', `${window.location.origin}/ancestor_children.parquet`, duckdb.DuckDBDataProtocol.HTTP, false ); // Execute the SQL query using the registered Parquet file const query = ` SELECT ancestor, direct_children, all_children, CAST(all_children_count AS INTEGER) AS all_children_count, CAST(direct_children_count AS INTEGER) AS direct_children_count FROM 'ancestor_children.parquet' `; const conn = await db.connect(); const result = await conn.query(query); // Convert the result to a JavaScript array const data: ModelData[] = result.toArray(); // Close the connection and terminate the worker await conn.close(); await db.terminate(); setAllModels(data); setIsLoading(false); } fetchData(); }, []); const filteredModels = allModels.filter((model) => model.ancestor.toLowerCase().includes(filterText.toLowerCase()) ); const sortedModels = filteredModels.sort((a, b) => { if (orderBy === 'all_children') { return b.all_children_count - a.all_children_count; } else { return (b.direct_children_count ?? 0) - (a.direct_children_count ?? 0); } }); const totalPages = Math.ceil(sortedModels.length / pageSize); const paginatedModels = sortedModels.slice( (currentPage - 1) * pageSize, currentPage * pageSize ); const handleOrderByClick = (column: 'all_children' | 'direct_children') => { setOrderBy(column); setCurrentPage(1); }; return (

All Models

setFilterText(e.target.value)} className="px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-white" />
{isLoading ? (

Loading data...

) : paginatedModels.length > 0 ? ( <> {paginatedModels.map((model, index) => ( ))}
Model handleOrderByClick('direct_children')} > Direct Children {orderBy === 'direct_children' && '▼'} handleOrderByClick('all_children')} > All Children {orderBy === 'all_children' && '▼'}
{model.ancestor} {model.direct_children_count ?? 0} {model.all_children_count}
{currentPage > 1 && ( <> {currentPage > 2 && ...} )} {[...Array(5)].map((_, i) => { const page = currentPage + i - 2; if (page >= 1 && page <= totalPages) { return ( ); } return null; })} {currentPage < totalPages && ( <> {currentPage < totalPages - 1 && ...} )}
) : (

No data found.

)}
); }