diff --git a/package-lock.json b/package-lock.json
index 32f9f58..d98e1d2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -49,7 +49,6 @@
"tinybench": "^6.0.2",
"typedoc": "^0.28.19",
"typedoc-plugin-missing-exports": "^4.1.4",
- "typedoc-theme-oxide": "^0.3.0",
"typescript": "^6.0.3",
"vite": "^8.1.5",
"vite-plugin-singlefile": "^2.3.3"
@@ -1771,13 +1770,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/brace-expansion": {
"version": "1.1.18",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
@@ -1913,50 +1905,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/cheerio": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz",
- "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cheerio-select": "^2.1.0",
- "dom-serializer": "^2.0.0",
- "domhandler": "^5.0.3",
- "domutils": "^3.2.2",
- "encoding-sniffer": "^0.2.1",
- "htmlparser2": "^10.1.0",
- "parse5": "^7.3.0",
- "parse5-htmlparser2-tree-adapter": "^7.1.0",
- "parse5-parser-stream": "^7.1.2",
- "undici": "^7.19.0",
- "whatwg-mimetype": "^4.0.0"
- },
- "engines": {
- "node": ">=20.18.1"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
- }
- },
- "node_modules/cheerio-select": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
- "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0",
- "css-select": "^5.1.0",
- "css-what": "^6.1.0",
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3",
- "domutils": "^3.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
"node_modules/cliui": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
@@ -2056,36 +2004,6 @@
"node": ">= 8"
}
},
- "node_modules/css-select": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
- "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0",
- "css-what": "^6.1.0",
- "domhandler": "^5.0.2",
- "domutils": "^3.0.1",
- "nth-check": "^2.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
- "node_modules/css-what": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
- "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">= 6"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
"node_modules/data-view-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
@@ -2237,78 +2155,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/dom-serializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
- "entities": "^4.2.0"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
- }
- },
- "node_modules/dom-serializer/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "BSD-2-Clause"
- },
- "node_modules/domhandler": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "domelementtype": "^2.3.0"
- },
- "engines": {
- "node": ">= 4"
- },
- "funding": {
- "url": "https://github.com/fb55/domhandler?sponsor=1"
- }
- },
- "node_modules/domutils": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
- "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "dom-serializer": "^2.0.0",
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3"
- },
- "funding": {
- "url": "https://github.com/fb55/domutils?sponsor=1"
- }
- },
"node_modules/dts-resolver": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-3.0.0.tgz",
@@ -2359,20 +2205,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/encoding-sniffer": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
- "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "iconv-lite": "^0.6.3",
- "whatwg-encoding": "^3.1.1"
- },
- "funding": {
- "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
- }
- },
"node_modules/enhanced-resolve": {
"version": "5.24.5",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz",
@@ -3102,35 +2934,6 @@
"dev": true,
"license": "ISC"
},
- "node_modules/flexsearch": {
- "version": "0.8.212",
- "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.8.212.tgz",
- "integrity": "sha512-wSyJr1GUWoOOIISRu+X2IXiOcVfg9qqBRyCPRUdLMIGJqPzMo+jMRlvE83t14v1j0dRMEaBbER/adQjp6Du2pw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/ts-thomas"
- },
- {
- "type": "paypal",
- "url": "https://www.paypal.com/donate/?hosted_button_id=GEVR88FC9BWRW"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/flexsearch"
- },
- {
- "type": "patreon",
- "url": "https://patreon.com/user?u=96245532"
- },
- {
- "type": "liberapay",
- "url": "https://liberapay.com/ts-thomas"
- }
- ],
- "license": "Apache-2.0"
- },
"node_modules/for-each": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
@@ -3623,52 +3426,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/htmlparser2": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
- "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
- "dev": true,
- "funding": [
- "https://github.com/fb55/htmlparser2?sponsor=1",
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3",
- "domutils": "^3.2.2",
- "entities": "^7.0.1"
- }
- },
- "node_modules/htmlparser2/node_modules/entities": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
- "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -5089,19 +4846,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/nth-check": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/fb55/nth-check?sponsor=1"
- }
- },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -5316,59 +5060,6 @@
"node": ">=6"
}
},
- "node_modules/parse5": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
- "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "entities": "^6.0.0"
- },
- "funding": {
- "url": "https://github.com/inikulin/parse5?sponsor=1"
- }
- },
- "node_modules/parse5-htmlparser2-tree-adapter": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
- "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "domhandler": "^5.0.3",
- "parse5": "^7.0.0"
- },
- "funding": {
- "url": "https://github.com/inikulin/parse5?sponsor=1"
- }
- },
- "node_modules/parse5-parser-stream": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
- "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "parse5": "^7.0.0"
- },
- "funding": {
- "url": "https://github.com/inikulin/parse5?sponsor=1"
- }
- },
- "node_modules/parse5/node_modules/entities": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
- "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -5901,13 +5592,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -6089,16 +5773,6 @@
"node": ">=8"
}
},
- "node_modules/slug": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/slug/-/slug-11.0.1.tgz",
- "integrity": "sha512-VrM060OM/E7rdLQSnp6JHrzFfJFmqQBp0+TMhZStnEB8PfNliaZ9UWYjTHGHLUFVJorZ8TjVd/aKvIxHWU2O7g==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "slug": "cli.js"
- }
- },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -6661,21 +6335,6 @@
"typedoc": "^0.28.1"
}
},
- "node_modules/typedoc-theme-oxide": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/typedoc-theme-oxide/-/typedoc-theme-oxide-0.3.0.tgz",
- "integrity": "sha512-K16JtPvyF4DJS2wH5xgumnUDlgEW5bzB4uBSxBM18gBvFCsTdYD713vSzTXvZdPe19a3HEnjXc0wZ1cYqshGeA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cheerio": "^1.1.2",
- "flexsearch": "^0.8.212",
- "slug": "^11.0.1"
- },
- "peerDependencies": {
- "typedoc": "^0.28.4"
- }
- },
"node_modules/typedoc/node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
@@ -6778,16 +6437,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/undici": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz",
- "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=20.18.1"
- }
- },
"node_modules/unicorn-magic": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
@@ -6949,30 +6598,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/whatwg-encoding": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
- "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
- "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "iconv-lite": "0.6.3"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/whatwg-mimetype": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
- "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index ac5b029..e57e28f 100644
--- a/package.json
+++ b/package.json
@@ -104,7 +104,6 @@
"tinybench": "^6.0.2",
"typedoc": "^0.28.19",
"typedoc-plugin-missing-exports": "^4.1.4",
- "typedoc-theme-oxide": "^0.3.0",
"typescript": "^6.0.3",
"vite": "^8.1.5",
"vite-plugin-singlefile": "^2.3.3"
diff --git a/support/typedoc-custom.css b/support/typedoc-custom.css
deleted file mode 100644
index 900b339..0000000
--- a/support/typedoc-custom.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Missed alert styles */
-
-:root {
- --color-alert-note: #0969da;
- --color-alert-tip: #1a7f37;
- --color-alert-important: #8250df;
- --color-alert-warning: #9a6700;
- --color-alert-caution: #cf222e;
-}
-
-:root[data-theme="dark"],
-:root[data-theme="ayu"] {
- --color-alert-note: #4493f8;
- --color-alert-tip: #3fb950;
- --color-alert-important: #ab7df8;
- --color-alert-warning: #d29922;
- --color-alert-caution: #f85149;
-}
-
-.tsd-alert {
- padding: 8px 16px;
- margin-bottom: 16px;
- border-left: 0.25em solid var(--alert-color);
-}
-
-.tsd-alert > :last-child {
- margin-bottom: 0;
-}
-
-.tsd-alert-title {
- color: var(--alert-color);
- display: inline-flex;
- align-items: center;
- font-weight: 500;
-}
-
-.tsd-alert-title span {
- margin-left: 4px;
-}
-
-.tsd-alert-note { --alert-color: var(--color-alert-note); }
-.tsd-alert-tip { --alert-color: var(--color-alert-tip); }
-.tsd-alert-important { --alert-color: var(--color-alert-important); }
-.tsd-alert-warning { --alert-color: var(--color-alert-warning); }
-.tsd-alert-caution { --alert-color: var(--color-alert-caution); }
-
-/* Fix `@example` tags display */
-
-.item-table.comment-tags {
- display: block;
-}
-
-.item-table.comment-tags > dt {
- margin: 1em 0 0.5em;
-}
-
-.item-table.comment-tags > dd {
- margin: 0;
-}
-
-.item-table.comment-tags > dd > pre {
- margin-top: 0;
-}
diff --git a/support/typedoc-oxide-fixes.mjs b/support/typedoc-oxide-fixes.mjs
deleted file mode 100644
index 9dad82d..0000000
--- a/support/typedoc-oxide-fixes.mjs
+++ /dev/null
@@ -1,115 +0,0 @@
-import * as fs from 'fs/promises'
-import * as path from 'path'
-import { deflateSync as deflate, inflateSync as inflate } from 'zlib'
-import { RendererEvent, PageEvent, ReflectionKind } from 'typedoc'
-import { itemSlug } from 'typedoc-theme-oxide/dist/plugin/context/utils.js'
-
-// Workarounds for https://github.com/balthild/typedoc-theme-oxide - drop them
-// once the theme fixes the issues upstream.
-export function load (app) {
- app.renderer.on(RendererEvent.BEGIN, (event) => {
- for (const refl of Object.values(event.project.reflections)) {
- // The theme renders `categories` and `groups` side by side, ignoring
- // `navigation.includeCategories`, so everything shows up twice. Drop the
- // groups wherever categories exist; members without categories (class
- // properties, methods, ...) keep their groups.
- if (refl.categories?.length && refl.groups?.length) refl.groups = undefined
-
- // The theme appends default values right after the type with no
- // separator ("boolean" + "false"). Carry the separator in the value.
- if (refl.defaultValue && !refl.kindOf(ReflectionKind.SomeType)) {
- refl.defaultValue = ' = ' + refl.defaultValue
- }
- }
- })
-
- // The theme builds its own "Source" and navigation links, ignoring
- // `sourceLinkExternal`. Markdown links are already handled by TypeDoc.
- const baseUrl = app.options.getValue('hostedBaseUrl')
-
- app.renderer.on(PageEvent.END, (page) => {
- page.contents = page.contents.replace(/]*>/g, tag => {
- if (/\btarget=/.test(tag)) return tag
- const href = tag.match(/\shref="(https?:\/\/[^"]*)"/)?.[1]
- if (!href || (href + '/').startsWith(baseUrl)) return tag
- return tag.replace(/^ (
- this.router.hasOwnDocument(item) ? context.urlTo(item) : itemLink(item, forceNested)
- )
-
- context.navigation = (...args) => {
- const fragment = navigation(...args)
-
- for (const child of fragment.children) {
- // Drop the hardcoded "Exports" link at the top of the sidebar - it is
- // the only bare there, everything else is wrapped in .
- child.children = child.children.filter(x => x?.tag !== 'ul')
-
- // The theme lists the sibling modules of the parent, rustdoc style.
- // On a namespace page that is useful navigation, anywhere else it
- // just glues the project namespaces on top. Keep the ".." link only.
- if (args[0]?.model?.kindOf(ReflectionKind.SomeModule)) continue
-
- for (const section of child.children.filter(x => x?.tag === 'section')) {
- for (const list of section.children) {
- list.children = list.children
- .flat(Infinity)
- .filter(x => x?.props?.class === 'parent-module')
- }
- }
- }
-
- return fragment
- }
-
- return context
- }
-
- // The search index is built with the same broken links as the sidebar, but
- // by a private method. Repoint its entries once it has been written.
- async postRender (event) {
- await super.postRender(event)
-
- const file = path.join(event.outputDirectory, 'assets', 'oxide', 'search-index.deflate')
- const parts = JSON.parse(inflate(await fs.readFile(file)).toString())
-
- for (const part of Object.values(parts)) {
- if (!Array.isArray(part)) continue
- for (const entry of part) {
- const doc = Array.isArray(entry) ? entry[1] : null
- if (typeof doc?.url !== 'string') continue
- const refl = event.project.getReflectionById(doc.id)
- if (refl && this.router.hasOwnDocument(refl)) doc.url = this.router.getFullUrl(refl)
- }
- }
-
- await fs.writeFile(file, deflate(Buffer.from(JSON.stringify(parts))))
- }
- }
-
- app.renderer.themes.set('oxide', PatchedOxideTheme)
-}
diff --git a/support/typedoc_condensed_theme/condensed_theme.css b/support/typedoc_condensed_theme/condensed_theme.css
new file mode 100644
index 0000000..344c065
--- /dev/null
+++ b/support/typedoc_condensed_theme/condensed_theme.css
@@ -0,0 +1,262 @@
+/*
+ * Keep TypeDoc's default layout and navigation. This file only adapts the
+ * content typography and removes duplicated declarations.
+ */
+
+:root {
+ --cndnsd-font-serif: Charter, "Bitstream Charter", "Sitka Text", Cambria, serif;
+ --cndnsd-font-sans: Seravek, "Gill Sans Nova", Ubuntu, Calibri, "DejaVu Sans", source-sans-pro, sans-serif;
+ --cndnsd-font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace;
+ --cndnsd-target-animation: 0.65s cubic-bezier(0, 0, 0.1, 1) 0.1s cndnsd-target-fadein;
+ --cndnsd-target-color-faded: rgb(from var(--color-background-warning) r g b / 30%);
+}
+
+/* =============================================================================
+ * Base typography tweaks
+ * ========================================================================== */
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: var(--cndnsd-font-sans);
+ font-weight: 500;
+}
+
+h1 { font-size: 1.5rem; }
+h2 { font-size: 1.375rem; }
+h3 { font-size: 1.25rem; }
+h4,
+h5,
+h6 {
+ font-size: 1rem;
+}
+
+code {
+ font-family: var(--cndnsd-font-mono);
+ background: oklch(
+ from var(--color-background-secondary)
+ calc(l - 0.025) c h
+ );
+ border-radius: 3px;
+}
+
+pre {
+ font-family: var(--cndnsd-font-mono);
+ margin: 0;
+ padding: .875rem;
+ background: var(--color-background-secondary);
+ border: 0;
+ border-radius: 6px;
+ font-size: 1rem;
+ line-height: 1.5;
+}
+
+.col-content .tsd-typography pre code {
+ padding: 0;
+ background: none;
+}
+
+/* Change default font for content only, don't touch side columns */
+.col-content {
+ font: 16px/1.5 var(--cndnsd-font-serif);
+}
+
+/* =============================================================================
+ * Content
+ * ========================================================================== */
+
+.tsd-breadcrumb {
+ font-family: var(--cndnsd-font-sans);
+}
+
+/* underline collapsible headers*/
+.col-content .tsd-accordion-summary {
+ padding-bottom: .5rem;
+ border-bottom: 1px solid var(--color-accent);
+}
+/* Fix "open" chevron offset after typography changes. TBH, that's an icon bug */
+.tsd-accordion[open] > .tsd-accordion-summary > svg:first-child {
+ translate: 0 4px;
+}
+
+.tsd-panel {
+ margin-bottom: 1.5rem;
+}
+
+/*
+ * Anchor links
+ */
+
+.tsd-anchor-icon {
+ opacity: 0;
+ position: absolute;
+ top: 0;
+ right: 100%;
+ margin: 0;
+ font-family: var(--cndnsd-font-sans);
+ font-style: normal;
+ font-weight: 400;
+ line-height: inherit;
+ text-decoration: none;
+}
+
+.tsd-anchor-link {
+ position: relative;
+}
+
+/* Remove permalinks in useless places in stead of styling
+ * - modules page
+ * - deprecated blocks
+ * - default values
+ */
+.tsd-member-group:has(> .tsd-member-summaries) .tsd-anchor-icon,
+.tsd-tag-deprecated .tsd-anchor-icon,
+.tsd-tag-defaultValue .tsd-anchor-icon {
+ display: none;
+}
+
+/* mouse over */
+.tsd-anchor-icon:hover,
+.tsd-anchor-icon:focus-visible,
+.tsd-anchor-link:hover .tsd-anchor-icon {
+ opacity: 1;
+}
+
+/* fix permalink offset in markdown documents */
+.tsd-panel > h1,
+.tsd-panel > h2,
+.tsd-panel > h3 {
+ margin-inline: 0;
+ padding-inline: 0;
+}
+
+/*
+ * Animate permalinks on page load
+ */
+
+@keyframes cndnsd-target-fadein {
+ from {
+ background-color: var(--color-background);
+ }
+ 50% {
+ background-color: var(--color-background-warning);
+ }
+ to {
+ background-color: var(--cndnsd-target-color-faded);
+ }
+}
+
+/* various permalinks for generated code docs */
+.tsd-member:target .tsd-signature,
+.tsd-tag-example .tsd-anchor-link:target,
+.tsd-accordion-summary:has(.tsd-anchor-link:target),
+/* for markdown headers */
+.tsd-panel.tsd-typography > .tsd-anchor-link:target {
+ background-color: var(--cndnsd-target-color-faded);
+ animation: var(--cndnsd-target-animation);
+}
+
+@media (prefers-reduced-motion) {
+ .col-content {
+ --cndnsd-target-animation: none;
+ }
+}
+
+/* Header-like signatures (properties, methods) */
+.tsd-member .tsd-signature {
+ font-family: var(--cndnsd-font-mono);
+ padding: 0;
+ border: 0;
+ background: none;
+ font-size: 1rem;
+ line-height: 1.5;
+ overflow: visible;
+ white-space: pre-wrap;
+}
+
+.cndnsd-call-signature .tsd-signature {
+ font-weight: 600;
+}
+.cndnsd-call-signature .tsd-signature * {
+ font-weight: inherit;
+}
+
+/* offset signature descriptions */
+.tsd-member > :not(.tsd-signature, .tsd-signatures, .tsd-anchor-icon),
+.cndnsd-call-signature > :not(.tsd-signature) {
+ margin-left: 1.5rem;
+}
+
+/* Page top signatures */
+.col-content > .tsd-panel :where(.tsd-signature),
+.col-content > .tsd-signature {
+ font-family: var(--cndnsd-font-mono);
+ margin: 1rem 0;
+ padding: .875rem;
+ background: var(--color-background-secondary);
+ border: 0;
+ border-radius: 6px;
+ font-size: 1rem;
+ line-height: 1.5;
+
+ overflow-x: auto;
+ overflow-wrap: normal;
+ white-space: pre;
+}
+
+/*
+ * Source links
+ */
+.tsd-sources {
+ font: 1rem/1.5 var(--cndnsd-font-sans);
+ margin: 0;
+ white-space: normal; /* rollback for top */
+}
+.tsd-sources a {
+ color: var(--color-link);
+ text-decoration: none;
+}
+
+.tsd-member .tsd-signature {
+ display: flow-root;
+}
+/* Only the link moved up; implements/inherited notes share the same class. */
+.tsd-member .tsd-signature .tsd-sources {
+ float: right;
+ margin: 0 0 0 .75rem;
+}
+.tsd-member .tsd-signature .tsd-sources ul {
+ margin: 0;
+}
+
+/* Restyle "default values" as one-line blocks of declaration. */
+.tsd-tag-defaultValue {
+ display: flex;
+ align-items: baseline;
+ column-gap: 1rem;
+ font-size: 0.875rem;
+ font-weight: 400;
+ margin: 1rem 0;
+}
+.tsd-tag-defaultValue * {
+ font-size: inherit;
+ font-weight: inherit;
+ margin: 0;
+}
+
+/*
+ * Remove useless blocks
+ */
+
+/* These ones duplicate info and just add noise to the page. */
+.tsd-index-group,
+.tsd-type-declaration,
+.tsd-returns-title,
+.tsd-parameters-title {
+ display: none;
+}
+
+/* Hide "Type Parameters" blocks without valuable info. */
+.tsd-panel:has(.tsd-type-parameter-list):not(:has(.tsd-comment)),
+/* Hide call signature "Parameters" blocks without valuable info. */
+.tsd-parameters:not(:has(.tsd-comment)) {
+ display: none;
+}
diff --git a/support/typedoc_condensed_theme/condensed_theme_plugin.mjs b/support/typedoc_condensed_theme/condensed_theme_plugin.mjs
new file mode 100644
index 0000000..55ed85f
--- /dev/null
+++ b/support/typedoc_condensed_theme/condensed_theme_plugin.mjs
@@ -0,0 +1,245 @@
+/*
+ * Theme on top of the default one. Page layout and navigation are kept intact,
+ * only member presentation is changed:
+ *
+ * - source link is compact (`Source`) and moved into the signature line;
+ * - member `h3` heading is dropped, its anchor moves to the `section`;
+ * - permalink is a plain `§` instead of an icon;
+ * - own markup for signature and getter/setter lists;
+ * - page top keeps the default layout.
+ *
+ * The only place coupled to TypeDoc's markup is `findMemberSignature`.
+ */
+
+import { cpSync } from 'node:fs'
+import { join } from 'node:path'
+
+import {
+ DefaultTheme,
+ DefaultThemeRenderContext,
+ i18n,
+ JSX,
+ ReflectionKind,
+ RendererEvent
+} from 'typedoc'
+
+const h = JSX.createElement
+
+/* =============================================================================
+ * Source links and permalinks
+ * ========================================================================== */
+
+function sourceLink (context, source) {
+ if (!source.url) return 'Source'
+
+ const attributes = { href: source.url }
+
+ if (context.options.getValue('sourceLinkExternal')) {
+ attributes.target = '_blank'
+ }
+
+ return h('a', attributes, 'Source')
+}
+
+function sourceLinks (context, item) {
+ if (!item.sources?.length) return null
+
+ return h('aside', { class: 'tsd-sources' },
+ h('ul', null,
+ item.sources.map(source => h('li', null, sourceLink(context, source)))
+ )
+ )
+}
+
+// Hide sources for the duration of the default render: TypeDoc skips its own
+// source links, but keeps implements/inherited/overrides notes untouched.
+function renderWithoutSources (item, render) {
+ const saved = item.sources
+
+ item.sources = undefined
+ try {
+ return render()
+ } finally {
+ item.sources = saved
+ }
+}
+
+function anchorIcon (context, anchor) {
+ if (!anchor) return h(JSX.Fragment, null)
+
+ return h('a', {
+ href: `#${anchor}`,
+ 'aria-label': i18n.theme_permalink(),
+ class: 'tsd-anchor-icon'
+ }, context.icons.anchor())
+}
+
+function addSignaturePermalink (context, signature, anchor) {
+ if (!anchor) return
+
+ signature.props = {
+ ...signature.props,
+ class: `${signature.props.class} tsd-anchor-link`
+ }
+ signature.children.push(anchorIcon(context, anchor))
+}
+
+// TypeDoc renders the page top bypassing `member`, keep the default look there.
+function isPageTop (context, reflection) {
+ return reflection === context.page.model
+}
+
+// Coupled to TypeDoc's markup: the signature line of `memberDeclaration` output.
+function findMemberSignature (element) {
+ return element?.children.find(child =>
+ child?.props?.class?.split(' ').includes('tsd-signature')
+ )
+}
+
+/* =============================================================================
+ * Signature lists
+ * ========================================================================== */
+
+function signatureItem (context, signature, permalinkAnchor, itemClass) {
+ const anchor = context.getAnchor(signature)
+ const className = [
+ context.getReflectionClasses(signature),
+ itemClass
+ ].filter(Boolean).join(' ')
+ const signatureElement = h('div', {
+ class: 'tsd-signature',
+ id: anchor
+ },
+ sourceLinks(context, signature),
+ context.memberSignatureTitle(signature)
+ )
+
+ addSignaturePermalink(context, signatureElement, permalinkAnchor)
+
+ return h('li', className ? { class: className } : null, signatureElement,
+ h('div', { class: 'tsd-description' },
+ renderWithoutSources(signature, () => context.memberSignatureBody(signature))
+ )
+ )
+}
+
+function signatureList (context, declaration, items) {
+ const classes = context.getReflectionClasses(declaration)
+
+ return h('ul', {
+ class: classes ? `tsd-signatures ${classes}` : 'tsd-signatures'
+ }, items)
+}
+
+/* =============================================================================
+ * Render context
+ * ========================================================================== */
+
+class CondensedThemeRenderContext extends DefaultThemeRenderContext {
+ constructor (...args) {
+ super(...args)
+
+ // In TypeDoc these renderers are fields, not prototype methods, so `super`
+ // can't reach them: overrides that augment the output capture the original
+ // here, while a full replacement is declared as a class field.
+ const renderMember = this.member
+ const renderMemberDeclaration = this.memberDeclaration
+ const renderMemberSignatures = this.memberSignatures
+ const renderMemberSources = this.memberSources
+
+ this.memberSources = item => h(JSX.Fragment, null,
+ sourceLinks(this, item),
+ renderWithoutSources(item, () => renderMemberSources(item))
+ )
+
+ this.memberDeclaration = declaration => {
+ if (isPageTop(this, declaration)) return renderMemberDeclaration(declaration)
+
+ const element = renderWithoutSources(declaration, () => renderMemberDeclaration(declaration))
+ const signature = findMemberSignature(element)
+
+ if (!signature) return element
+
+ const sources = sourceLinks(this, declaration)
+
+ if (sources) signature.children.unshift(sources)
+ addSignaturePermalink(this, signature, this.getAnchor(declaration))
+
+ return element
+ }
+
+ this.memberSignatures = declaration => {
+ if (isPageTop(this, declaration)) return renderMemberSignatures(declaration)
+
+ return signatureList(this, declaration, declaration.signatures?.map((signature, index) =>
+ signatureItem(
+ this,
+ signature,
+ index === 0 && this.getAnchor(declaration),
+ signature.kind === ReflectionKind.CallSignature && 'cndnsd-call-signature'
+ )
+ ))
+ }
+
+ this.member = item => {
+ const element = renderMember(item)
+ const anchor = this.getAnchor(item)
+
+ element.children = element.children.filter(child => child?.tag !== 'h3')
+ element.props = { ...element.props, id: anchor }
+
+ return element
+ }
+ }
+
+ get icons () {
+ return {
+ ...super.icons,
+ anchor: () => h('span', {
+ 'aria-hidden': 'true',
+ class: 'cndnsd-anchor-symbol'
+ }, '§')
+ }
+ }
+
+ memberGetterSetter = declaration => signatureList(this, declaration, [
+ declaration.getSignature && signatureItem(
+ this,
+ declaration.getSignature,
+ this.getAnchor(declaration)
+ ),
+ declaration.setSignature && signatureItem(
+ this,
+ declaration.setSignature,
+ !declaration.getSignature && this.getAnchor(declaration)
+ )
+ ])
+}
+
+/* =============================================================================
+ * Theme and plugin
+ * ========================================================================== */
+
+class CondensedTheme extends DefaultTheme {
+ ContextClass = CondensedThemeRenderContext
+
+ constructor (renderer) {
+ super(renderer)
+
+ this.owner.on(RendererEvent.END, event => {
+ cpSync(
+ join(import.meta.dirname, 'condensed_theme.css'),
+ join(event.outputDirectory, 'assets', 'condensed_theme.css')
+ )
+ })
+ }
+}
+
+export default function condensedThemePlugin (app) {
+ app.renderer.hooks.on('head.end', context => h('link', {
+ rel: 'stylesheet',
+ href: context.relativeURL('assets/condensed_theme.css')
+ }))
+
+ app.renderer.defineTheme('condensed', CondensedTheme)
+}
diff --git a/typedoc.config.mjs b/typedoc.config.mjs
index 54a462e..e879250 100644
--- a/typedoc.config.mjs
+++ b/typedoc.config.mjs
@@ -1,3 +1,5 @@
+import condensedThemePlugin from './support/typedoc_condensed_theme/condensed_theme_plugin.mjs'
+
export default {
entryPoints: ['src/index.ts'],
@@ -15,13 +17,11 @@ export default {
plugin: [
'typedoc-plugin-missing-exports',
-
- 'typedoc-theme-oxide',
- './support/typedoc-oxide-fixes.mjs'
+ condensedThemePlugin
],
- theme: 'oxide',
- customCss: './support/typedoc-custom.css',
+ theme: 'condensed',
excludeExternals: true,
+ excludeInternal: true,
placeInternalsInOwningModule: true,
out: 'apidoc',