Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ on:
- develop

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Lint all code
run: bunx prettier --check .

build:
env:
GH_TOKEN: ${{ github.token }}
Expand Down
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ This is a great process for bug fixes, simple features and purely additive chang

However, if you are making a significant change to the way Vortex functions, you may need to write an RFC first. Some example changes that would require an RFC:

* Making a risky change to the format, such as adding new required fields to file metadata
* Rearchitecting core components of Vortex, or wide-ranging refactors that might break language bindings
* Creating new libraries or SDKs that we expect others to adopt
* Making changes to subsystems that are likely to affect performance if not done thoughfully, such as the core IO traits
- Making a risky change to the format, such as adding new required fields to file metadata
- Rearchitecting core components of Vortex, or wide-ranging refactors that might break language bindings
- Creating new libraries or SDKs that we expect others to adopt
- Making changes to subsystems that are likely to affect performance if not done thoughfully, such as the core IO traits

## Process

Expand Down Expand Up @@ -70,3 +70,14 @@ Remove the build output:
```sh
bun run clean
```

### Formatting

We use [`prettiest`](https://prettier.io/) to format the code and documents, and check it in CI.

Running it is as easy as:

```sh
bunx prettier --write .
bunx prettier --check .
```
4 changes: 3 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 63 additions & 25 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,17 @@ const LIVE_RELOAD_SCRIPT = `
})();
`;

function baseHTML(title: string, content: string, cssPath: string = "styles.css", liveReload: boolean = false, repoUrl: string | null = null): string {
function baseHTML(
title: string,
content: string,
cssPath: string = "styles.css",
liveReload: boolean = false,
repoUrl: string | null = null,
): string {
const basePath = cssPath === "styles.css" ? "./" : "../";
const githubLink = repoUrl ? `<a href="${repoUrl}" class="github-link" aria-label="View on GitHub" target="_blank" rel="noopener">${ICON_GITHUB}</a>` : "";
const githubLink = repoUrl
? `<a href="${repoUrl}" class="github-link" aria-label="View on GitHub" target="_blank" rel="noopener">${ICON_GITHUB}</a>`
: "";
return `<!DOCTYPE html>
<html lang="en">
<head>
Expand Down Expand Up @@ -119,32 +127,40 @@ function escapeHTML(str: string): string {
.replace(/"/g, "&quot;");
}

function indexPage(rfcs: RFC[], repoUrl: string | null, liveReload: boolean = false): string {
function indexPage(
rfcs: RFC[],
repoUrl: string | null,
liveReload: boolean = false,
): string {
// Sort in reverse numeric order (newest first)
const sorted = [...rfcs].sort((a, b) => b.number.localeCompare(a.number));

const list = sorted.map(rfc => {
const dateStr = rfc.git.accepted ? formatDate(rfc.git.accepted.date) : "";
const list = sorted
.map((rfc) => {
const dateStr = rfc.git.accepted ? formatDate(rfc.git.accepted.date) : "";

let authorHTML = "";
if (rfc.git.author && rfc.git.accepted) {
const commitUrl = repoUrl ? `${repoUrl}/commit/${rfc.git.accepted.hash}` : `https://github.com/${rfc.git.author.login}`;
authorHTML = `
let authorHTML = "";
if (rfc.git.author && rfc.git.accepted) {
const commitUrl = repoUrl
? `${repoUrl}/commit/${rfc.git.accepted.hash}`
: `https://github.com/${rfc.git.author.login}`;
authorHTML = `
<a href="${commitUrl}" class="rfc-author-link" title="${rfc.git.author.login}">
<img src="${rfc.git.author.avatarUrl}" alt="${rfc.git.author.login}" class="rfc-author-avatar">
<span class="rfc-author-name">${rfc.git.author.login}</span>
</a>`;
}
}

return `
return `
<li>
<a href="rfc/${rfc.number}.html" class="rfc-item">
<span class="rfc-number">RFC ${rfc.number}</span>
<span class="rfc-title">${escapeHTML(rfc.title)}</span>
<span class="rfc-date">${dateStr}</span>
</a>${authorHTML}
</li>`;
}).join("\n");
})
.join("\n");

const content = `
<h1>Request for Comments</h1>
Expand All @@ -164,7 +180,11 @@ function formatDate(date: Date): string {
});
}

function rfcPage(rfc: RFC, repoUrl: string | null, liveReload: boolean = false): string {
function rfcPage(
rfc: RFC,
repoUrl: string | null,
liveReload: boolean = false,
): string {
let gitHeader = "";

if (rfc.git.accepted || rfc.git.author) {
Expand Down Expand Up @@ -218,7 +238,13 @@ function rfcPage(rfc: RFC, repoUrl: string | null, liveReload: boolean = false):
${rfc.html}
</article>`;

return baseHTML(`RFC ${rfc.number} - ${rfc.title}`, content, "../styles.css", liveReload, repoUrl);
return baseHTML(
`RFC ${rfc.number} - ${rfc.title}`,
content,
"../styles.css",
liveReload,
repoUrl,
);
}

function parseRFCNumber(filename: string): string {
Expand All @@ -245,10 +271,14 @@ async function getGitHubRepoUrl(): Promise<string | null> {
}
}

async function getGitHubAuthor(repoPath: string, commitHash: string): Promise<GitHubAuthor | null> {
async function getGitHubAuthor(
repoPath: string,
commitHash: string,
): Promise<GitHubAuthor | null> {
try {
// Use gh CLI to fetch commit info from GitHub API
const result = await $`gh api repos/${repoPath}/commits/${commitHash} --jq '.author.login, .author.avatar_url, .author.html_url'`.quiet();
const result =
await $`gh api repos/${repoPath}/commits/${commitHash} --jq '.author.login, .author.avatar_url, .author.html_url'`.quiet();
const lines = result.stdout.toString().trim().split("\n");

if (lines.length >= 3 && lines[0] && lines[1] && lines[2]) {
Expand All @@ -264,9 +294,13 @@ async function getGitHubAuthor(repoPath: string, commitHash: string): Promise<Gi
}
}

async function getGitHistory(filepath: string, repoPath: string | null): Promise<RFCGitInfo> {
async function getGitHistory(
filepath: string,
repoPath: string | null,
): Promise<RFCGitInfo> {
try {
const result = await $`git log --follow --format=%H\ %aI -- ${filepath}`.quiet();
const result =
await $`git log --follow --format=%H\ %aI -- ${filepath}`.quiet();
const lines = result.stdout.toString().trim().split("\n").filter(Boolean);

if (lines.length === 0) {
Expand All @@ -284,7 +318,9 @@ async function getGitHistory(filepath: string, repoPath: string | null): Promise
const oldest = parseCommit(lines[lines.length - 1]!);

// Fetch author info from the first commit
const author = repoPath ? await getGitHubAuthor(repoPath, oldest.hash) : null;
const author = repoPath
? await getGitHubAuthor(repoPath, oldest.hash)
: null;

// If only one commit, or same commit, don't show lastUpdated
if (lines.length === 1 || mostRecent.hash === oldest.hash) {
Expand Down Expand Up @@ -479,7 +515,7 @@ async function startDevServer() {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
Connection: "keep-alive",
},
});
}
Expand All @@ -503,9 +539,11 @@ async function startDevServer() {
if (isDev) {
startDevServer().catch(console.error);
} else {
build().then(count => {
if (count > 0) {
console.log("Output directory: ./dist/");
}
}).catch(console.error);
build()
.then((count) => {
if (count > 0) {
console.log("Output directory: ./dist/");
}
})
.catch(console.error);
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"clean": "rm -rf dist"
},
"devDependencies": {
"@types/bun": "latest"
"@types/bun": "latest",
"prettier": "^3.8.1"
},
"peerDependencies": {
"typescript": "^5"
Expand Down
60 changes: 47 additions & 13 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@ html {
}

body {
font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-family:
"Inter",
"SF Pro Display",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Helvetica,
Arial,
sans-serif;
background: var(--bg);
color: var(--fg);
line-height: 1.6;
Expand Down Expand Up @@ -130,7 +139,9 @@ header h1 a:hover {
height: 36px;
border-radius: 50%;
color: var(--fg-muted);
transition: color 0.15s ease, box-shadow 0.15s ease;
transition:
color 0.15s ease,
box-shadow 0.15s ease;
}

.github-link:hover {
Expand Down Expand Up @@ -174,17 +185,33 @@ main {
min-height: calc(100vh - 200px);
}

h1, h2, h3, h4, h5, h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 600;
margin-top: 2rem;
margin-bottom: 1rem;
color: var(--accent);
}

h1 { font-size: 1.75rem; margin-top: 0; }
h2 { font-size: 1.375rem; }
h3 { font-size: 1.125rem; }
h4, h5, h6 { font-size: 1rem; }
h1 {
font-size: 1.75rem;
margin-top: 0;
}
h2 {
font-size: 1.375rem;
}
h3 {
font-size: 1.125rem;
}
h4,
h5,
h6 {
font-size: 1rem;
}

p {
margin-bottom: 1rem;
Expand All @@ -200,7 +227,8 @@ a:hover {
text-decoration: underline;
}

ul, ol {
ul,
ol {
margin-bottom: 1rem;
padding-left: 1.5rem;
}
Expand All @@ -210,15 +238,17 @@ li {
}

code {
font-family: "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;
font-family:
"IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;
background: var(--code-bg);
padding: 0.125rem 0.375rem;
border-radius: 3px;
font-size: 0.875em;
}

pre {
font-family: "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;
font-family:
"IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;
background: var(--code-bg);
border: 1px solid var(--border);
border-radius: 4px;
Expand Down Expand Up @@ -254,7 +284,8 @@ table {
margin-bottom: 1rem;
}

th, td {
th,
td {
border: 1px solid var(--border);
padding: 0.5rem 0.75rem;
text-align: left;
Expand All @@ -278,7 +309,9 @@ th {
padding: 0.75rem 1rem;
margin: 0 -1rem;
border-radius: 4px;
transition: box-shadow 0.15s ease, background 0.15s ease;
transition:
box-shadow 0.15s ease,
background 0.15s ease;
}

.rfc-list li:hover {
Expand Down Expand Up @@ -306,7 +339,8 @@ th {
}

.rfc-item .rfc-number {
font-family: "IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;
font-family:
"IBM Plex Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;
color: var(--fg-muted);
font-size: 0.875rem;
flex-shrink: 0;
Expand Down