Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Deploy

on:
push: {branches: [main]}
schedule: [{cron: "15 10 * * *"}]
workflow_dispatch: {}

jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: yarn --frozen-lockfile
- run: yarn build
- uses: actions/configure-pages@v4
- uses: actions/upload-pages-artifact@v3
with:
path: dist
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@

This project collects [npm download counts](https://github.com/npm/registry/blob/main/docs/download-counts.md) for [Observable’s open-source projects](https://github.com/observablehq) and [D3](https://github.com/d3). These charts are built with [Observable Framework](https://observablehq.com/framework/) and updated daily on [Observable Cloud](https://observablehq.com/platform/cloud) so they can be [embedded](https://observablehq.com/framework/embeds) in our GitHub READMEs.

<a href="https://observablehq.observablehq.cloud/oss-analytics/@observablehq/plot">
<a href="https://observablehq.github.io/oss-analytics/@observablehq/plot">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://observablehq.observablehq.cloud/oss-analytics/@observablehq/plot/downloads-dark.svg">
<img alt="Daily downloads of Observable Plot" src="https://observablehq.observablehq.cloud/oss-analytics/@observablehq/plot/downloads.svg">
<source media="(prefers-color-scheme: dark)" srcset="https://observablehq.github.io/oss-analytics/@observablehq/plot/downloads-dark.svg">
<img alt="Daily downloads of Observable Plot" src="https://observablehq.github.io/oss-analytics/@observablehq/plot/downloads.svg">
</picture>
</a>

<sub>Daily downloads of Observable Plot · [oss-analytics](https://observablehq.observablehq.cloud/oss-analytics/)</sub>
<sub>Daily downloads of Observable Plot · [oss-analytics](https://observablehq.github.io/oss-analytics/)</sub>

## How to use for your own packages

This project is [open-source](https://github.com/observablehq/oss-analytics/); you can use it to build embeddable charts of your own packages.

1. [Fork this repository.](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)
2. Edit [`observablehq.config.js`](https://github.com/observablehq/oss-analytics/blob/main/observablehq.config.js) to list your npm packages, comitting your changes.
3. In your [Observable workspace](https://observablehq.com), create a new data app and link it to your forked repository.
4. In your new data app’s **Automation** tab, enable the `daily` build schedule.
5. Tweak [`index.md.js`](https://github.com/observablehq/oss-analytics/blob/main/src/index.md.js) to personalize the page.
3. Tweak [`index.md.js`](https://github.com/observablehq/oss-analytics/blob/main/src/index.md.js) to personalize the page.
1 change: 0 additions & 1 deletion observablehq.cloud.yaml

This file was deleted.

17 changes: 15 additions & 2 deletions src/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,21 @@ import {today} from "./today.js";

export async function fetchNpm(path) {
const url = new URL(path, "https://api.npmjs.org");
const response = await fetch(url);
if (!response.ok) throw new Error(`failed to fetch ${url}: ${response.status}`);
let response;
let headers;
for (let attempt = 0, maxAttempts = 3; attempt < maxAttempts; ++attempt) {
response = await fetch(url);
headers = response.headers;
if (response.ok) break;
console.warn(Object.fromEntries(headers));
if (headers.get("retry-after")) {
const retryDelay = headers.get("retry-after") * 1000;
console.warn(`retry-after ${headers.get("retry-after")}`, retryDelay);
await new Promise((resolve) => setTimeout(resolve, retryDelay));
continue;
}
throw new Error(`failed to fetch ${url}: ${response.status}`);
}
return await response.json();
}

Expand Down