cfahlgren1 HF staff commited on
Commit
17388ad
1 Parent(s): 7512661

use static regeneration

Browse files
Files changed (1) hide show
  1. src/pages/index.tsx +100 -79
src/pages/index.tsx CHANGED
@@ -35,95 +35,114 @@ interface Activity {
35
  level: number;
36
  }
37
 
38
- export default function OpenSourceHeatmap() {
39
- const [calendarData, setCalendarData] = useState<Record<string, Activity[]>>({});
40
- const [isLoading, setIsLoading] = useState(true);
41
 
42
- const generateCalendarData = (modelData: ModelData[]) => {
43
- const data: Record<string, Activity[]> = Object.fromEntries(
44
- Object.keys(PROVIDERS_MAP).map(provider => [provider, []])
45
- );
46
 
47
- const today = new Date();
48
- const startDate = new Date(today);
49
- startDate.setMonth(today.getMonth() - 11);
50
- startDate.setDate(1);
51
-
52
- // create a map to store counts for each provider and date
53
- const countMap: Record<string, Record<string, number>> = {};
54
-
55
- modelData.forEach(item => {
56
- const dateString = item.createdAt.split('T')[0];
57
- Object.entries(PROVIDERS_MAP).forEach(([provider, { authors }]) => {
58
- if (authors.some(author => item.id.startsWith(author))) {
59
- countMap[provider] = countMap[provider] || {};
60
- countMap[provider][dateString] = (countMap[provider][dateString] || 0) + 1;
61
- }
62
- });
63
  });
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- // fill in with 0s for days with no activity
66
- for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
67
- const dateString = d.toISOString().split('T')[0];
68
-
69
- Object.entries(PROVIDERS_MAP).forEach(([provider]) => {
70
- const count = countMap[provider]?.[dateString] || 0;
71
- data[provider].push({ date: dateString, count, level: 0 });
72
- });
73
- }
74
-
75
- // calculate average counts for each provider
76
- const avgCounts = Object.fromEntries(
77
- Object.entries(data).map(([provider, days]) => [
78
- provider,
79
- days.reduce((sum, day) => sum + day.count, 0) / days.length || 0
80
- ])
81
- );
82
 
83
- // assign levels based on count relative to average
84
- Object.entries(data).forEach(([provider, days]) => {
85
- const avgCount = avgCounts[provider];
86
- days.forEach(day => {
87
- day.level =
88
- day.count === 0 ? 0 :
89
- day.count <= avgCount * 0.5 ? 1 :
90
- day.count <= avgCount ? 2 :
91
- day.count <= avgCount * 1.5 ? 3 : 4;
92
- });
93
  });
 
94
 
95
- return data;
96
- }
97
 
98
- const initData = async () => {
99
- try {
100
- const allAuthors = Object.values(PROVIDERS_MAP).flatMap(({ authors }) => authors);
101
- const uniqueAuthors = Array.from(new Set(allAuthors));
102
-
103
- const allModelData = await Promise.all(
104
- uniqueAuthors.map(async (author) => {
105
- const response = await fetch(`https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`);
106
- const data = await response.json();
107
- return data.map((item: any) => ({
108
- createdAt: item.createdAt,
109
- id: item.id,
110
- }));
111
- })
112
- );
113
-
114
- const flatModelData = allModelData.flat();
115
- const calendarData = generateCalendarData(flatModelData);
116
- setCalendarData(calendarData);
117
- } catch (error) {
118
- console.error("Error fetching data:", error);
119
- } finally {
120
- setIsLoading(false);
121
- }
 
 
 
 
 
 
 
 
 
122
  }
 
 
 
 
 
 
 
 
123
 
124
  useEffect(() => {
125
- initData();
126
- }, []);
 
 
127
 
128
  return (
129
  <div className="w-full max-w-screen-lg mx-auto p-4">
@@ -178,4 +197,6 @@ export default function OpenSourceHeatmap() {
178
  )}
179
  </div>
180
  );
181
- }
 
 
 
35
  level: number;
36
  }
37
 
38
+ interface CalendarData {
39
+ [key: string]: Activity[];
40
+ }
41
 
42
+ const generateCalendarData = (modelData: ModelData[]): CalendarData => {
43
+ const data: Record<string, Activity[]> = Object.fromEntries(
44
+ Object.keys(PROVIDERS_MAP).map(provider => [provider, []])
45
+ );
46
 
47
+ const today = new Date();
48
+ const startDate = new Date(today);
49
+ startDate.setMonth(today.getMonth() - 11);
50
+ startDate.setDate(1);
51
+
52
+ // create a map to store counts for each provider and date
53
+ const countMap: Record<string, Record<string, number>> = {};
54
+
55
+ modelData.forEach(item => {
56
+ const dateString = item.createdAt.split('T')[0];
57
+ Object.entries(PROVIDERS_MAP).forEach(([provider, { authors }]) => {
58
+ if (authors.some(author => item.id.startsWith(author))) {
59
+ countMap[provider] = countMap[provider] || {};
60
+ countMap[provider][dateString] = (countMap[provider][dateString] || 0) + 1;
61
+ }
 
62
  });
63
+ });
64
+
65
+ // fill in with 0s for days with no activity
66
+ for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
67
+ const dateString = d.toISOString().split('T')[0];
68
+
69
+ Object.entries(PROVIDERS_MAP).forEach(([provider]) => {
70
+ const count = countMap[provider]?.[dateString] || 0;
71
+ data[provider].push({ date: dateString, count, level: 0 });
72
+ });
73
+ }
74
 
75
+ // calculate average counts for each provider
76
+ const avgCounts = Object.fromEntries(
77
+ Object.entries(data).map(([provider, days]) => [
78
+ provider,
79
+ days.reduce((sum, day) => sum + day.count, 0) / days.length || 0
80
+ ])
81
+ );
 
 
 
 
 
 
 
 
 
 
82
 
83
+ // assign levels based on count relative to average
84
+ Object.entries(data).forEach(([provider, days]) => {
85
+ const avgCount = avgCounts[provider];
86
+ days.forEach(day => {
87
+ day.level =
88
+ day.count === 0 ? 0 :
89
+ day.count <= avgCount * 0.5 ? 1 :
90
+ day.count <= avgCount ? 2 :
91
+ day.count <= avgCount * 1.5 ? 3 : 4;
 
92
  });
93
+ });
94
 
95
+ return data;
96
+ }
97
 
98
+ export async function getStaticProps() {
99
+ try {
100
+ const allAuthors = Object.values(PROVIDERS_MAP).flatMap(({ authors }) => authors);
101
+ const uniqueAuthors = Array.from(new Set(allAuthors));
102
+
103
+ const allModelData = await Promise.all(
104
+ uniqueAuthors.map(async (author) => {
105
+ const response = await fetch(`https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`);
106
+ const data = await response.json();
107
+ return data.map((item: any) => ({
108
+ createdAt: item.createdAt,
109
+ id: item.id,
110
+ }));
111
+ })
112
+ );
113
+
114
+ const flatModelData = allModelData.flat();
115
+ const calendarData = generateCalendarData(flatModelData);
116
+
117
+ return {
118
+ props: {
119
+ calendarData,
120
+ },
121
+ revalidate: 3600, // regenerate every hour
122
+ };
123
+ } catch (error) {
124
+ console.error("Error fetching data:", error);
125
+ return {
126
+ props: {
127
+ calendarData: {},
128
+ },
129
+ revalidate: 60, // retry after 1 minute if there was an error
130
+ };
131
  }
132
+ }
133
+
134
+ interface OpenSourceHeatmapProps {
135
+ calendarData: CalendarData;
136
+ }
137
+
138
+ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({ calendarData }) => {
139
+ const [isLoading, setIsLoading] = useState(true);
140
 
141
  useEffect(() => {
142
+ if (calendarData && Object.keys(calendarData).length > 0) {
143
+ setIsLoading(false);
144
+ }
145
+ }, [calendarData]);
146
 
147
  return (
148
  <div className="w-full max-w-screen-lg mx-auto p-4">
 
197
  )}
198
  </div>
199
  );
200
+ }
201
+
202
+ export default OpenSourceHeatmap;