mirror of
https://github.com/zooai/ngo.git
synced 2026-10-30 15:04:49 +00:00
The numbers were typed by hand and three of the four were wrong: 86 papers when there are 88, 149 proposals when there are 146, and 45 models against 78 — the site published barely half its own work, and a `45+` beside it hedging a number nobody could check. Counting at build rather than in getStaticProps, because that spends the whole sixty-an-hour allowance on a single build: Next runs nine workers and then exports every page a second time, so nothing a module remembers survives. One script writes the counts before the build and the whole site compiles with them, which also means every page is right with JavaScript off rather than the ten that had been plumbed by hand. Three requests, one build. A browser then counts at most once an hour and remembers what it found. Without that a visitor spends two of their sixty requests on every page they open — thirty pages before the sources refuse, and the refusal is invisible because the page simply keeps the number it already has. Nothing renders a zero. A source that fails keeps the last number that answered, a truncated tree throws rather than reading as a short count, and a value that is not a positive integer is refused. Papers are the directories holding their own .tex, which is the convention the repo already follows, so a paper added tomorrow counts itself and nothing here keeps a list. proofs stays typed by hand: that repository is private, so a public site has nothing to count.
53 lines
2.3 KiB
JavaScript
53 lines
2.3 KiB
JavaScript
// Write src/config/counts.json — what the sources say Zoo Labs has published.
|
|
//
|
|
// The counting rules live in src/config/corpus.tsx, because the browser runs
|
|
// them too; this only decides WHEN. Doing it here rather than in a page's
|
|
// getStaticProps is not a preference: this build runs nine worker processes and
|
|
// then exports every page a second time, so a module-level memo holds for none
|
|
// of it — measured, a per-page fetch spent the whole 60-an-hour GitHub
|
|
// allowance on one build. From here the whole build asks three times, once per
|
|
// source, whatever Next does with processes.
|
|
//
|
|
// First link of `build`, `dev` and `typecheck`, like scripts/gui-css.mjs, and
|
|
// named there rather than as `prebuild` because pnpm does not run pre/post
|
|
// scripts. A generator that silently does not run leaves the last good file.
|
|
import { build } from 'esbuild';
|
|
import { existsSync, writeFileSync, rmSync } from 'node:fs';
|
|
|
|
const root = new URL('..', import.meta.url);
|
|
const counts = new URL('src/config/counts.json', root);
|
|
const bundle = new URL('.counts.gen.mjs', root);
|
|
|
|
// The floor. Only ever reached on a first run that cannot reach the network,
|
|
// and only until one can — every later run starts from the file it last wrote.
|
|
// `proofs` is the exception that stays here: there is no public source to count
|
|
// it from, so it is counted by hand and has to agree with proofs.zoo.ngo.
|
|
if (!existsSync(counts)) {
|
|
writeFileSync(counts, JSON.stringify({ papers: 88, proposals: 146, models: 78, proofs: 15 }));
|
|
}
|
|
|
|
// corpus.tsx is TypeScript with JSX in it, so Node needs it bundled before it
|
|
// can be imported. React is left external — nothing here renders anything.
|
|
await build({
|
|
absWorkingDir: root.pathname,
|
|
entryPoints: ['src/config/corpus.tsx'],
|
|
bundle: true,
|
|
format: 'esm',
|
|
platform: 'node',
|
|
jsx: 'automatic',
|
|
external: ['react', 'react/jsx-runtime'],
|
|
outfile: bundle.pathname,
|
|
logLevel: 'error',
|
|
});
|
|
|
|
const { CORPUS, count } = await import(bundle);
|
|
const counted = await count(CORPUS);
|
|
rmSync(bundle);
|
|
|
|
writeFileSync(counts, `${JSON.stringify(counted, null, 2)}\n`);
|
|
const moved = Object.keys(counted).filter((k) => counted[k] !== CORPUS[k]);
|
|
console.log(
|
|
`src/config/counts.json — ${Object.entries(counted).map(([k, n]) => `${n} ${k}`).join(', ')}` +
|
|
(moved.length ? ` (${moved.join(', ')} changed)` : '')
|
|
);
|