harshapitla/github-actions-analytics
0
1import { useCallback, useEffect, useRef, useState } from "react";2import { loadExtensionsCSV } from "../components/data/dataLoader";3 4const emptyMetadata = { rowsCount: 0, columns: [] };5 6const initialState = {7 status: "idle",8 rows: [],9 metadata: emptyMetadata,10 error: null,11};12 13export function useMarketplaceDataset(datasetPath) {14 const [state, setState] = useState(initialState);15 const controllerRef = useRef(null);16 17 const computeMetadata = useCallback((rows) => {18 if (!Array.isArray(rows) || rows.length === 0) return emptyMetadata;19 const columnSet = new Set();20 let displayableCount = 0;21 rows.forEach((row) => {22 if (!row) return;23 Object.keys(row).forEach((key) => columnSet.add(key));24 const name = row.name ? String(row.name).trim() : "";25 if (name && name.toLowerCase() !== "name") {26 displayableCount += 1;27 }28 });29 return {30 rowsCount: displayableCount,31 columns: Array.from(columnSet),32 };33 }, []);34 35 const fetchRows = useCallback(async () => {36 controllerRef.current?.abort();37 const controller = new AbortController();38 controllerRef.current = controller;39 setState((prev) => ({ ...prev, status: "loading", error: null }));40 41 try {42 const { rows } = await loadExtensionsCSV(datasetPath, { signal: controller.signal });43 if (controller.signal.aborted) return;44 setState({45 status: "success",46 rows,47 metadata: computeMetadata(rows),48 error: null,49 });50 } catch (err) {51 if (err?.name === "AbortError") return;52 setState((prev) => ({53 ...prev,54 status: prev.rows.length ? "success" : "error",55 error: err,56 }));57 }58 }, [computeMetadata, datasetPath]);59 60 useEffect(() => {61 fetchRows();62 return () => controllerRef.current?.abort();63 }, [fetchRows]);64 65 return {66 ...state,67 refresh: fetchRows,68 hasData: state.rows.length > 0,69 };70}71 