src/lib/order.ts (971B)
1 /**
2 * Ordering: date DESC, then title by Intl.Collator('en'), then path.
3 *
4 * This single order drives the Writing index and the feed at once, so it must never be
5 * delegated to filesystem or database order. Sorting by raw code points instead would put
6 * `TSO` ahead of `journalctl`, two posts that share a date, because code points order every
7 * capital before every lowercase letter.
8 */
9 const collator = new Intl.Collator('en');
10
11 export interface Sortable { data: { date: string; title: string }; id: string }
12
13 export function byHugoOrder<T extends Sortable>(a: T, b: T): number {
14 if (a.data.date !== b.data.date) return a.data.date < b.data.date ? 1 : -1;
15 const t = collator.compare(a.data.title, b.data.title);
16 return t !== 0 ? t : (a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
17 }
18
19 /** Canonical path for a post. The year is derived from the front matter date. */
20 export const postUrl = (p: Sortable): string => `/writing/${p.data.date.slice(0, 4)}/${p.id}/`;