Public
Edited
May 30, 2023
8 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
parseName(name)
Insert cell
function parseName(name) {
const [repo, pkg = repo] = name.split(":");
return [repo.replace(/^@/, ""), pkg];
}
Insert cell
stargazers = fetchStargazers({name, token})
Insert cell
versions = {
try {
const info = await d3.json(`https://registry.npmjs.org/${encodeURIComponent(parseName(name)[1])}`);
return Object.values(info.versions).map(({version}) => ({version, date: new Date(info.time[version])}));
} catch {
return [];
}
}
Insert cell
async function* fetchStargazers({ name, token, delay = 150, maxPage = Infinity } = {}) {
const [repo] = parseName(name);
let url = `https://api.github.com/repos/${repo}/stargazers?per_page=100&page=1`;
let headers = {
...(token && { Authorization: `token ${token}` }),
accept: "application/vnd.github.v3.star+json" // necessary to get the starred_at field
};
const stargazers = [];
yield stargazers;
let page = 0;
while (url && (++page <= maxPage)) {
const response = await fetch(`${url}`, {headers});
if (!response.ok) throw new Error(response.status);
for (const stargazer of await response.json()) stargazers.push(coerceStargazer(stargazer));
yield stargazers;
url = findRelLink(response.headers, "next");
await Promises.delay(delay);
}
}
Insert cell
function coerceStargazer({starred_at, user}) {
return {starred_at: new Date(starred_at), user};
}
Insert cell
Insert cell
function isPrerelease(version) {
return /-/.test(version);
}
Insert cell
function isMajor(version) {
return /^\d+\.0\.0$/.test(version);
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more