@wxxb789/anc 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/astro.config.mjs +255 -0
- package/bin/anc.mjs +798 -0
- package/package.json +93 -0
- package/public/_headers +45 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +9 -0
- package/public/fonts/Temml.woff2 +0 -0
- package/scripts/build-snapshot.js +69 -0
- package/scripts/build-wasm.js +67 -0
- package/scripts/build-workspace.js +50 -0
- package/scripts/copy-snapshot.js +48 -0
- package/scripts/copy-wasm.js +57 -0
- package/scripts/emit-redirects.js +64 -0
- package/scripts/generate-corpus.js +421 -0
- package/scripts/init-repository.js +249 -0
- package/scripts/load-config.js +975 -0
- package/scripts/markdown-to-artifact.js +1286 -0
- package/scripts/preview-site.js +364 -0
- package/scripts/publish-set-review.js +157 -0
- package/scripts/resolve-links.js +640 -0
- package/scripts/run-pagefind.js +125 -0
- package/scripts/scan-residue.js +1016 -0
- package/scripts/scan-secrets.js +268 -0
- package/scripts/seed-gitignore.js +410 -0
- package/scripts/snapshot-rows.js +205 -0
- package/scripts/validate-content.js +95 -0
- package/scripts/vendor-provenance.js +307 -0
- package/scripts/verify-output-inventory.js +307 -0
- package/scripts/write-report.js +351 -0
- package/scripts/write-snapshot.js +136 -0
- package/src/components/CollectionExplorer.astro +149 -0
- package/src/components/FacetIndex.astro +45 -0
- package/src/components/LinkedNotes.astro +94 -0
- package/src/components/NoteGraph.astro +434 -0
- package/src/components/NoteList.astro +54 -0
- package/src/components/SiteMetadata.astro +143 -0
- package/src/components/TableOfContents.astro +69 -0
- package/src/components/TagBrowser.astro +70 -0
- package/src/layouts/Layout.astro +305 -0
- package/src/lib/artifact-source.js +72 -0
- package/src/lib/build-bindings.js +11 -0
- package/src/lib/collection-navigation.js +145 -0
- package/src/lib/content.js +92 -0
- package/src/lib/diagram-mode.js +18 -0
- package/src/lib/graph-layout.js +219 -0
- package/src/lib/graph-selection.js +84 -0
- package/src/lib/graph.js +42 -0
- package/src/lib/link-resolution.js +389 -0
- package/src/lib/markdown.js +1469 -0
- package/src/lib/math-mode.js +31 -0
- package/src/lib/math-output.js +131 -0
- package/src/lib/math.js +165 -0
- package/src/lib/mermaid-environment.js +475 -0
- package/src/lib/mermaid-render.js +769 -0
- package/src/lib/preview-model.js +96 -0
- package/src/lib/relations.js +242 -0
- package/src/lib/rendered-marker.js +55 -0
- package/src/lib/route-path.js +192 -0
- package/src/lib/routes.js +342 -0
- package/src/lib/schema.js +578 -0
- package/src/lib/site.js +578 -0
- package/src/lib/snapshot-contract.js +216 -0
- package/src/lib/snapshot-operations.js +147 -0
- package/src/lib/snapshot-queries.js +216 -0
- package/src/lib/snapshot-reader.js +210 -0
- package/src/lib/snapshot.js +233 -0
- package/src/lib/sqlite-warning.js +22 -0
- package/src/lib/sqlite.js +14 -0
- package/src/lib/tag-browser-model.js +18 -0
- package/src/lib/translations.js +533 -0
- package/src/lib/wasm-asset.js +47 -0
- package/src/lib/worker-protocol.js +93 -0
- package/src/pages/404.astro +35 -0
- package/src/pages/about.astro +100 -0
- package/src/pages/collections/[slug].astro +36 -0
- package/src/pages/collections/index.astro +33 -0
- package/src/pages/graph.astro +64 -0
- package/src/pages/index.astro +33 -0
- package/src/pages/notes/[slug].astro +509 -0
- package/src/pages/privacy.astro +121 -0
- package/src/pages/private.astro +59 -0
- package/src/pages/recent.astro +33 -0
- package/src/pages/robots.txt.js +15 -0
- package/src/pages/rss.xml.js +21 -0
- package/src/pages/sitemap.xml.js +20 -0
- package/src/pages/tags/[tag].astro +56 -0
- package/src/pages/tags/index.astro +37 -0
- package/src/scripts/code-copy.js +45 -0
- package/src/scripts/diagram-disabled.js +16 -0
- package/src/scripts/diagram.js +322 -0
- package/src/scripts/graph-client.js +222 -0
- package/src/scripts/graph-draw.js +166 -0
- package/src/scripts/link-preview.js +334 -0
- package/src/scripts/math-disabled.js +18 -0
- package/src/scripts/math.js +133 -0
- package/src/scripts/preferences.js +123 -0
- package/src/scripts/search-dialog.js +651 -0
- package/src/scripts/snapshot-client.js +157 -0
- package/src/scripts/snapshot-worker.js +341 -0
- package/src/scripts/tag-browser.js +153 -0
- package/src/scripts/theme-init.js +35 -0
- package/src/scripts/toc-active.js +38 -0
- package/src/styles/code.css +152 -0
- package/src/styles/diagram.css +149 -0
- package/src/styles/global.css +1739 -0
- package/src/styles/graph.css +317 -0
- package/src/styles/math.css +376 -0
- package/src/styles/tokens.css +171 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the Pagefind search index over a built site.
|
|
3
|
+
*
|
|
4
|
+
* The JavaScript API rather than the `pagefind` CLI, so that this repository's
|
|
5
|
+
* own build and the packaged one run the same indexer through the same call.
|
|
6
|
+
* The CLI is reachable here — `pagefind` is a declared dependency and pnpm links
|
|
7
|
+
* its binary — but not reliably from a consumer's tree: the executable ships in
|
|
8
|
+
* seven per-platform optional dependencies, and locating it from a
|
|
9
|
+
* `node_modules/.bin` belonging to *the user's* project is an assumption this
|
|
10
|
+
* package should not make when a supported programmatic entry point exists.
|
|
11
|
+
*
|
|
12
|
+
* The exclusion is not a preference. `--exclude-selectors ".heading-anchor"`
|
|
13
|
+
* keeps the `#` character every heading anchor carries out of the index, and
|
|
14
|
+
* without it a search for any heading returns results whose excerpt begins with
|
|
15
|
+
* a stray `#`. It lives here as a constant rather than in a command line so that
|
|
16
|
+
* every path indexes alike: `package.json`'s `build`, `build-fixture.ts`, and
|
|
17
|
+
* the packaged binary all call this one function. They did not — `build` passed
|
|
18
|
+
* the flag and `build-fixture.ts` did not, so the fixture corpus the search
|
|
19
|
+
* gates measure was indexed differently from the corpus that ships, and
|
|
20
|
+
* `tests/search.test.ts` measures results rather than flags and so could not
|
|
21
|
+
* see it.
|
|
22
|
+
*/
|
|
23
|
+
import { createIndex, close } from 'pagefind';
|
|
24
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
25
|
+
import { dirname, join } from 'node:path';
|
|
26
|
+
import { fileURLToPath } from 'node:url';
|
|
27
|
+
import { BuildFailure } from "./write-report.js";
|
|
28
|
+
/**
|
|
29
|
+
* The selectors whose text must not enter the index.
|
|
30
|
+
*
|
|
31
|
+
* `.heading-anchor` is the `#` link every heading carries; indexing it puts a
|
|
32
|
+
* bare `#` into every heading's searchable text.
|
|
33
|
+
*
|
|
34
|
+
* **`code.language-math` is a cost, not a free win, and the cost is stated
|
|
35
|
+
* because it is a real one: a reader can no longer find a note by an expression
|
|
36
|
+
* in it.** Under client rendering the TeX source ships as the fallback a
|
|
37
|
+
* JS-disabled reader sees, and a Pagefind fragment stores extracted *text* with
|
|
38
|
+
* markup stripped — so `f:\mathbb{R} \to \mathbb{C}` arrives in the index with
|
|
39
|
+
* no element around it, where it reads as noise beside the prose and trips the
|
|
40
|
+
* residue scan's `absolute local path` rule with no code region left to exempt
|
|
41
|
+
* it. Measured: the fragment for such a note carries the raw TeX.
|
|
42
|
+
*
|
|
43
|
+
* The alternative is exempting the rule over every fragment, which
|
|
44
|
+
* `scripts/scan-residue.ts` measures as taking a genuinely leaked path with it.
|
|
45
|
+
* Excluding the source from the index is the narrower price, and it is paid by
|
|
46
|
+
* search rather than by the privacy boundary.
|
|
47
|
+
*
|
|
48
|
+
* `src/lib/math.ts` already declines to emit Temml's `<annotation>` copy of the
|
|
49
|
+
* source for the same reason, so this is the same decision applied to the mode
|
|
50
|
+
* where the source is what ships.
|
|
51
|
+
*/
|
|
52
|
+
const EXCLUDE_SELECTORS = ['.heading-anchor', 'code.language-math'];
|
|
53
|
+
const DIST = fileURLToPath(new URL('../dist', import.meta.url));
|
|
54
|
+
/**
|
|
55
|
+
* Pagefind's own error strings are third-party, of opaque provenance, and are
|
|
56
|
+
* composed over the directory being indexed — so they go to the report rather
|
|
57
|
+
* than to a stream a workflow log inherits. The public half is which of the
|
|
58
|
+
* three calls failed, which is a literal of this file's own source.
|
|
59
|
+
*/
|
|
60
|
+
function pagefindFailed(what, errors) {
|
|
61
|
+
return new BuildFailure('pagefind-failed', `pagefind ${what}`, `pagefind ${what}: ${errors.join('; ')}`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Write the bundle the indexer authored, synchronously, and only report success
|
|
65
|
+
* when every byte of it is on disk.
|
|
66
|
+
*
|
|
67
|
+
* `writeFiles` is deliberately not used. Measured on CI: its promise resolves
|
|
68
|
+
* before the bundle directory is complete — `pagefind-entry.json` was the first
|
|
69
|
+
* member a gate caught, then a partial content-addressed member failed the
|
|
70
|
+
* secret scanner with `could not inflate one output member`, and two builds of
|
|
71
|
+
* one corpus hashed differently because a tree was read while members were
|
|
72
|
+
* still landing. `close()` terminates the indexer, so an in-flight write can be
|
|
73
|
+
* abandoned permanently, and the existing poll for the manifest alone covered
|
|
74
|
+
* one member of many. A poll over every member (measured while diagnosing this)
|
|
75
|
+
* also cannot be trusted, because members appear and disappear while the
|
|
76
|
+
* writer runs. `getFiles()` is the indexer's authored copy of the complete
|
|
77
|
+
* bundle, and writing it here makes completion structural: each member is
|
|
78
|
+
* closed before this function returns, so no gate can read a tree the indexer
|
|
79
|
+
* is still writing. Measured byte-for-byte equal to `writeFiles` output in a
|
|
80
|
+
* direct author-vs-writer comparison on this host over a 12-page corpus with
|
|
81
|
+
* nested members and CJK text, and in an author-after-write comparison over a
|
|
82
|
+
* 65-page corpus.
|
|
83
|
+
*/
|
|
84
|
+
export function writePagefindBundle(bundleDirectory, authored) {
|
|
85
|
+
for (const file of authored) {
|
|
86
|
+
const target = join(bundleDirectory, file.path);
|
|
87
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
88
|
+
writeFileSync(target, file.content);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export async function indexWithPagefind(siteDirectory) {
|
|
92
|
+
const { index, errors } = await createIndex({ excludeSelectors: EXCLUDE_SELECTORS });
|
|
93
|
+
if (errors.length > 0 || index === undefined) {
|
|
94
|
+
throw pagefindFailed('could not start', errors);
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const added = await index.addDirectory({ path: siteDirectory });
|
|
98
|
+
if (added.errors.length > 0)
|
|
99
|
+
throw pagefindFailed('failed to index', added.errors);
|
|
100
|
+
const authored = await index.getFiles();
|
|
101
|
+
if (authored.errors.length > 0)
|
|
102
|
+
throw pagefindFailed('could not read back', authored.errors);
|
|
103
|
+
writePagefindBundle(join(siteDirectory, 'pagefind'), authored.files);
|
|
104
|
+
return added.page_count;
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
// The indexer is a long-lived child process. Left running, the build never
|
|
108
|
+
// exits — which on CI is a job that hangs until its timeout rather than a
|
|
109
|
+
// build that failed.
|
|
110
|
+
await close();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function main() {
|
|
114
|
+
try {
|
|
115
|
+
const pages = await indexWithPagefind(DIST);
|
|
116
|
+
console.log(`search index ok: ${pages} page${pages === 1 ? '' : 's'} indexed`);
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
121
|
+
return 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (process.argv[1] === fileURLToPath(import.meta.url))
|
|
125
|
+
process.exit(await main());
|