@clean-jsdoc-theme/utils

@clean-jsdoc-theme/utils は、pipeline 内の他のすべての package が import する 共有 contract です。これは setu と dwar の間の type boundary、nav links と heading anchors が常に一致するように両者が使う slug rules、そして entry-point bridges が実行する純粋な opts-validation + build-report ロジック を定義します。

rendering も I/O も一切含まれません。残りのシステムが構築される土台となる interfaces、Zod schemas、そして少数の小さな純粋関数だけです。

theme を使いたいだけなら、この package を install することは決してありません。 これは内部的な building block です。実際に install する部分については Packages セクションを、オプションについては Configuration を参照してください。

なぜ独立した package なのか

pipeline 全体は意図的に一方向です。setu は doclets を SiteManifest に変換し、 dwar がその manifest を render します。そして両者の間に隠れた coupling が決して 育ってはなりません。boundary types を独立した package に切り出すことで、 project は次の2つを手に入れます。

  • boundary に対する単一の真実の源。 setu は SiteManifest を emit し、dwar は 同じ SiteManifest type を consume します。そしてどちらも他方を import しません。この形は一度だけここで定義されるため、build 側と render 側が 乖離することはありません。これは boundary barrel である site/index.ts で確認できます。その doc comment 自体がこれを「the boundary contract between setu (build) and dwar (render)」と呼んでいます。
  • Browser-safe なので rang も import できる。 Preact component library (rang) は browser 上で動くため、共有する contract は node-free でなければ なりません。ここにある slug rules、base-path helpers、diagnostics model、 build-report formatter は web-platform globals (URLTextEncoderfetchAbortController) のみを使い、fsBuffernode:* は決して使いません。 唯一の networked dependency (Google Fonts の存在確認) と唯一の node-only dependency (gzip sizing) は、import するのではなく caller によって inject されます。これこそが package を browser で importable に保つ仕組み です。

トップの barrel である src/index.ts がすべてを re-export し、package.json は単一の entry point を公開します。 したがってすべての consumer は @clean-jsdoc-theme/utils から import します (subpath exports はありません)。

中身は何か

package は2つの surface に分かれます。site/ contracts と config/ logic、 さらに JSDoc doclet schema です。

site/ — setu ↔ dwar の contract

boundary objects と、両者が共有しなければならない rules です。検証済みの exports には次が含まれます。

  • SiteManifestPageNavNodeSearchEntry — setu が dwar に渡すもの: pages、nav tree、search index、そして cache busting 用の buildId です。 manifest が self-contained であるのは意図的です。dwar が doclet database を 読み直すことは決してありません。 (manifest.ts, page.ts)
  • FrontmatterPageKindHeading — page ごとの metadata、layout を 駆動する page kind (classmoduleguidesource、…)、そして TOC island が render する事前抽出済みの headings です。 (page.ts)
  • RenderOptionsRenderResultOutputFileRenderErrordwar.render の入力と出力です。render() は純粋で、files を memory 上で返します。doc comment は、意図的に embedSearchIndex flag を設けていないと述べています。 (render.ts)
  • ThemeConfigThemeTokensThemeColorsComponentOverrides — theme contract: color tokens、fonts、Shiki themes、component slot overrides、 base path、copy-page と prev/next の config、custom CSS/JS です。 (theme.ts)
  • SiteNameSiteLogo と helpers の siteNameText() および resolveSiteLogo() — plain-text または logo-set による site identity です。 (site-name.ts)
  • IslandNameIslandPropsMap — interactive islands の registry (sidebartoccmdkcopy-page、…) と、それぞれに対する type-safe な prop bag で、server render と hydration の間で共有されます。 (islands.ts)
  • slugifyHeading()slugifyPath()slugifySourcePath() — GitHub-style の slug rules です。setu (sidebar / TOC generation) と dwar (rendered anchor IDs) の両者がここから import するため、anchors と links は常に一致します。 この file はこれを「Risk R4」に対処するものだと明記しています。 (slug-rules.ts)
  • normalizeBasePath()withBase() — site を sub-directory から serve する ための、純粋で browser-safe かつ fail-safe な helpers です。 (base-path.ts)

config/ — 純粋な opts validation + build report

build の前後に entry-point bridges が実行する logic です。

  • validateThemeOpts() — orchestrator です。raw な opts object を受け取り、 siteNamefonts の validators、さらに unknown-key policy を単一の DiagnosticBag で実行し、normalized な値を返します。決して throw しません。 strict-mode の強制は diagnostics.hasErrors() を介した caller の仕事です。 (validate-opts.ts)
  • DiagnosticBagDiagnosticformatDiagnostics() — reporting の背骨: 純粋で node-free な、構造化され level-tagged (error / warning / info) された finding model です。 (diagnostics.ts)
  • createGoogleFontResolver()FontResolverFontExistenceFetchLike — utils を browser-safe に保つ injection パターンです。 唯一の networked チェック (この Google Font は存在するか?) は inject された fetch を中心に組み立てられ、fail-open です。曖昧なものはすべて 'unknown' に resolve されるため、offline build が壊れることは決してありません。 (google-fonts.ts)
  • formatBuildReport() — Next.js 風の build summary です。byte sizes は TextEncoder から得られます (Buffer は決して使いません)。gzip sizing は inject された gzipSizer で、これもまた utils を node-free に保つためです。 (report.ts)
  • Zod schemasTHEME_OPT_KEYSSiteNameSchemaFontsSchemaMenuSchemaCopyPageConfigSchema などです。認識される theme-option surface を Zod として表現したもので、failures が構造化された path + message を 伴うようになっています。 (opts-schema.ts)

doclet schema

doclet-schema.ts (TDoclet など) と salty.ts (TJSDocSaltyCollection) は、setu が読む JSDoc 側の types を運びます。これらも トップの barrel から re-export されるため、setu の doclet processing は同じ package から import します。

injection パターンの仕組み

これが config package を browser-safe に保つ詳細です。utils は fetchzlib を決して import しません。caller がそれらを渡します。

  • validateThemeOpts({ … fontResolver }) は、bridge が createGoogleFontResolver() で構築した resolver を受け取ります。これがなければ、 font existence チェックは穏やかにスキップされ、build は先へ進みます。
  • formatBuildReport({ … gzipSizer }) は gzip function を受け取ります。gzip column は sizer が供給されたときだけ現れます。bridge は (b) => zlib.gzipSync(b).length を渡します。

google-fonts.tsreport.ts の両方が、これを module doc comments で 述べています。networked / node-only dependency は「is never imported, only the optional [resolver/sizer] injected by the caller.」です。

source を読む

maintainer はあなたを code へ送りたいと考えています。ここから始めてください。

次へ