for-humanity 0.12.0 → 0.13.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.
Files changed (226) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +16 -9
  3. package/dist/browser.js +14 -16
  4. package/dist/cli.css +2 -968
  5. package/dist/cli.js +92 -2318
  6. package/dist/config.js +1 -0
  7. package/dist/constant/copy.d.ts +100 -0
  8. package/dist/constant/site.d.ts +20 -0
  9. package/dist/constant/status.d.ts +19 -0
  10. package/dist/copy-C1uzvEnr.js +103 -0
  11. package/dist/group-path-XAThmzvC.js +10 -0
  12. package/dist/load-site-B-u5-jv0.js +2343 -0
  13. package/dist/logger-Dv1i9xSV.js +9 -0
  14. package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
  15. package/dist/mermaid/chunk--TN-qHgG.js +2 -0
  16. package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
  17. package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
  18. package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
  19. package/dist/mermaid/chunk-6HLei9i0.js +84 -0
  20. package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
  21. package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
  22. package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
  23. package/dist/mermaid/chunk-B--pNBQF.js +884 -0
  24. package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
  25. package/dist/mermaid/chunk-B58sEIY_.js +14 -0
  26. package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
  27. package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
  28. package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
  29. package/dist/mermaid/chunk-BKri0qr7.js +89 -0
  30. package/dist/mermaid/chunk-BL404pH5.js +26 -0
  31. package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
  32. package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
  33. package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
  34. package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
  35. package/dist/mermaid/chunk-BariMtWr.js +3020 -0
  36. package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
  37. package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
  38. package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
  39. package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
  40. package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
  41. package/dist/mermaid/chunk-BvVehae3.js +5069 -0
  42. package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
  43. package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
  44. package/dist/mermaid/chunk-CApNbSU9.js +6 -0
  45. package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
  46. package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
  47. package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
  48. package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
  49. package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
  50. package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
  51. package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
  52. package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
  53. package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
  54. package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
  55. package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
  56. package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
  57. package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
  58. package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
  59. package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
  60. package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
  61. package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
  62. package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
  63. package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
  64. package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
  65. package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
  66. package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
  67. package/dist/mermaid/chunk-CuYekbSv.js +2 -0
  68. package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
  69. package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
  70. package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
  71. package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
  72. package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
  73. package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
  74. package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
  75. package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
  76. package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
  77. package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
  78. package/dist/mermaid/chunk-DU69_VcF.js +363 -0
  79. package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
  80. package/dist/mermaid/chunk-DZe-4kde.js +20 -0
  81. package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
  82. package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
  83. package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
  84. package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
  85. package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
  86. package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
  87. package/dist/mermaid/chunk-DqGhppWe.js +2 -0
  88. package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
  89. package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
  90. package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
  91. package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
  92. package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
  93. package/dist/mermaid/chunk-KuPYb48V.js +275 -0
  94. package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
  95. package/dist/mermaid/chunk-MbInCS_6.js +28 -0
  96. package/dist/mermaid/chunk-MexOLyKV.js +355 -0
  97. package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
  98. package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
  99. package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
  100. package/dist/mermaid/chunk-TftHqGLg.js +490 -0
  101. package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
  102. package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
  103. package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
  104. package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
  105. package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
  106. package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
  107. package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
  108. package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
  109. package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
  110. package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
  111. package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
  112. package/dist/mermaid/chunk-yBz-vst0.js +976 -0
  113. package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
  114. package/dist/run-site-command-cqCjpIlc.js +129 -0
  115. package/dist/site-config-bllORGpm.js +90 -0
  116. package/dist/site.js +1 -0
  117. package/dist/start-dev-server-x7Ja5uwv.js +184 -0
  118. package/dist/to-change-queue-DbEnZGNK.js +34 -0
  119. package/dist/to-error-message-pF6_7wGK.js +16 -0
  120. package/dist/type/group-path.d.ts +7 -0
  121. package/dist/type/site-config.d.ts +57 -0
  122. package/package.json +34 -17
  123. package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
  124. package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
  125. package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
  126. package/src/component/widget/navigation/_constant/locale.ts +0 -9
  127. package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
  128. package/src/component/widget/navigation/_constant/navigation.ts +0 -9
  129. package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
  130. package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
  131. package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
  132. package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
  133. package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
  134. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
  135. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
  136. package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
  137. package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
  138. package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
  139. package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
  140. package/src/component/widget/navigation/_type/doc-group.ts +0 -24
  141. package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
  142. package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
  143. package/src/component/widget/navigation/_type/toc-group.ts +0 -39
  144. package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
  145. package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
  146. package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
  147. package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
  148. package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
  149. package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
  150. package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
  151. package/src/component/widget/navigation/wg-navigation.css +0 -282
  152. package/src/component/widget/navigation/wg-navigation.tsx +0 -420
  153. package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
  154. package/src/component/widget/prose/_constant/section.ts +0 -7
  155. package/src/component/widget/prose/_constant/status.ts +0 -9
  156. package/src/component/widget/prose/_function/has-block-content.ts +0 -30
  157. package/src/component/widget/prose/_function/rehype-head.ts +0 -31
  158. package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
  159. package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
  160. package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
  161. package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
  162. package/src/component/widget/prose/_function/remark-flow.ts +0 -26
  163. package/src/component/widget/prose/_function/remark-links.ts +0 -33
  164. package/src/component/widget/prose/_function/remark-parts.ts +0 -26
  165. package/src/component/widget/prose/_function/remark-status.ts +0 -59
  166. package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
  167. package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
  168. package/src/component/widget/prose/wg-prose.css +0 -484
  169. package/src/component/widget/prose/wg-prose.tsx +0 -43
  170. package/src/component/widget/shell/wg-shell.css +0 -63
  171. package/src/component/widget/shell/wg-shell.tsx +0 -88
  172. package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
  173. package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
  174. package/src/constant/asset.ts +0 -63
  175. package/src/constant/copy.ts +0 -133
  176. package/src/constant/doc.ts +0 -13
  177. package/src/constant/font.ts +0 -34
  178. package/src/constant/site.ts +0 -24
  179. package/src/constant/status.ts +0 -15
  180. package/src/entry/browser/browser.tsx +0 -22
  181. package/src/entry/cli/_constant/cli.ts +0 -19
  182. package/src/entry/cli/_constant/crawling.ts +0 -14
  183. package/src/entry/cli/_constant/snippet.ts +0 -21
  184. package/src/entry/cli/_function/create-app.tsx +0 -57
  185. package/src/entry/cli/_function/create-dev-app.ts +0 -87
  186. package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
  187. package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
  188. package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
  189. package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
  190. package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -91
  191. package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
  192. package/src/entry/cli/_function/read-docs.ts +0 -128
  193. package/src/entry/cli/_function/read-home.ts +0 -32
  194. package/src/entry/cli/_function/to-crawling-app.ts +0 -42
  195. package/src/entry/cli/cli.test.ts +0 -804
  196. package/src/entry/cli/cli.ts +0 -206
  197. package/src/env.d.ts +0 -6
  198. package/src/page/doc/pg-doc.tsx +0 -35
  199. package/src/page/home/pg-home.tsx +0 -40
  200. package/src/store/navigation/create-navigation-stores.test.ts +0 -74
  201. package/src/store/navigation/create-navigation-stores.ts +0 -59
  202. package/src/store/navigation/navigation-state.ts +0 -36
  203. package/src/store/navigation/navigation-storage.ts +0 -9
  204. package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
  205. package/src/style/base.css +0 -28
  206. package/src/style/token.css +0 -188
  207. package/src/type/doc-content.ts +0 -15
  208. package/src/type/doc-data.ts +0 -38
  209. package/src/type/doc-file-data.ts +0 -21
  210. package/src/type/doc-heading.ts +0 -17
  211. package/src/type/doc-outline.ts +0 -16
  212. package/src/type/doc-section.ts +0 -9
  213. package/src/type/doc.ts +0 -20
  214. package/src/type/group-path.ts +0 -7
  215. package/src/type/site-assets.ts +0 -25
  216. package/src/type/site-config.ts +0 -73
  217. package/src/type/vfile-data.d.ts +0 -10
  218. package/src/util/async/to-change-queue.test.ts +0 -58
  219. package/src/util/async/to-change-queue.ts +0 -43
  220. package/src/util/dom/find-hash-target.ts +0 -18
  221. package/src/util/dom/reveal-hash-target.ts +0 -15
  222. package/src/util/error/to-error-message.ts +0 -10
  223. package/src/util/file/to-asset-path.ts +0 -26
  224. package/src/util/font/to-font-css.test.ts +0 -41
  225. package/src/util/font/to-font-css.ts +0 -28
  226. package/src/util/mermaid/render-flow.js +0 -321
@@ -1,206 +0,0 @@
1
- #!/usr/bin/env node
2
- /*
3
- * CLI · for-humanity <dev|build|preview> [문서 폴더]
4
- * 기본 문서 폴더: 현재 폴더 · 출력: <문서 폴더>/dist
5
- */
6
-
7
- import {EventEmitter} from "node:events";
8
- import {existsSync, readFileSync, watch} from "node:fs";
9
- import {copyFile, mkdir, rm, writeFile} from "node:fs/promises";
10
- import {dirname, extname, join, relative, resolve, sep} from "node:path";
11
- import {fileURLToPath, pathToFileURL} from "node:url";
12
- import {serve} from "@hono/node-server";
13
- import {serveStatic} from "@hono/node-server/serve-static";
14
- import {debounce} from "es-toolkit";
15
- import {Hono} from "hono";
16
- import {toSSG} from "hono/ssg";
17
- import {asset_favicon_path, asset_font_dir, asset_media_extensions, asset_style_path} from "@/constant/asset";
18
- import {copy_error_config, copy_error_prefix, copy_error_unknown_command} from "@/constant/copy";
19
- import {font_body_css, font_brand_css, font_cache_control, font_mono_css} from "@/constant/font";
20
- import {site_config_absent} from "@/constant/site";
21
- import {cli_config_file_name, cli_default_command, cli_default_docs_dir, cli_reload_delay_ms} from "@/entry/cli/_constant/cli";
22
- import {crawling_reserved_roots} from "@/entry/cli/_constant/crawling";
23
- import {createApp} from "@/entry/cli/_function/create-app";
24
- import {createDevApp} from "@/entry/cli/_function/create-dev-app";
25
- import {createProcessor} from "@/entry/cli/_function/create-processor/create-processor";
26
- import {readDocs} from "@/entry/cli/_function/read-docs";
27
- import {readHome} from "@/entry/cli/_function/read-home";
28
- import {toCrawlingApp} from "@/entry/cli/_function/to-crawling-app";
29
- import {siteConfigSchema} from "@/type/site-config";
30
- import {toChangeQueue} from "@/util/async/to-change-queue";
31
- import {toErrorMessage} from "@/util/error/to-error-message";
32
- import {toAssetPath} from "@/util/file/to-asset-path";
33
- import {toFontCss} from "@/util/font/to-font-css";
34
-
35
- const commands = ["dev", "build", "preview"];
36
- const [command = cli_default_command, docsDir = cli_default_docs_dir] = process.argv.slice(2);
37
-
38
- /**
39
- * 명령 실행 · 설정 검증, 렌더링, 빌드·서버 시작
40
- * 실패: 터미널 오류와 종료 코드 1
41
- */
42
- const main = async () => {
43
- if (!commands.includes(command)) {
44
- throw new Error(`${copy_error_unknown_command}: ${command} (${commands.join(", ")})`);
45
- }
46
-
47
- // dist/cli.js 기준 패키지 루트
48
- const kitRoot = fileURLToPath(new URL("../", import.meta.url));
49
- const docsRoot = resolve(docsDir);
50
- const outDir = join(docsRoot, "dist");
51
- const configFile = join(docsRoot, cli_config_file_name);
52
- const parsedConfig = siteConfigSchema.safeParse(existsSync(configFile) ? (await import(pathToFileURL(configFile).href)).default : site_config_absent);
53
-
54
- if (!parsedConfig.success) {
55
- throw new Error(`${copy_error_config}: ${parsedConfig.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
56
- }
57
-
58
- const siteConfig = parsedConfig.data;
59
-
60
- if (command === "preview") {
61
- const app = new Hono();
62
-
63
- app.use(
64
- "/*",
65
- serveStatic({
66
- root: relative(process.cwd(), outDir),
67
- onFound: (_path, c) => {
68
- if (c.req.path.startsWith(`${asset_font_dir}/`)) {
69
- c.header("Cache-Control", font_cache_control);
70
- }
71
- },
72
- }),
73
- );
74
- serve({fetch: app.fetch, port: siteConfig.port}, (info) => console.log(`http://localhost:${info.port}/`));
75
-
76
- return;
77
- }
78
-
79
- // 내장 @font-face와 파일 수집 · font-family는 token.css 소유
80
- const mono = toFontCss({css: join(kitRoot, font_mono_css), fontDir: asset_font_dir});
81
- const body = toFontCss({css: join(kitRoot, font_body_css), fontDir: asset_font_dir});
82
- const brand = toFontCss({css: join(kitRoot, font_brand_css), fontDir: asset_font_dir});
83
-
84
- const fontCss = [mono.css, body.css, brand.css].join("\n");
85
- const stylePath = toAssetPath({path: asset_style_path, file: join(kitRoot, "dist/cli.css")});
86
- const browserScript = readFileSync(join(kitRoot, "dist/browser.js"), "utf8");
87
- const kitFiles = new Map([
88
- [stylePath, join(kitRoot, "dist/cli.css")],
89
- [asset_favicon_path, join(kitRoot, "src/asset/favicon.svg")],
90
- ...mono.files,
91
- ...body.files,
92
- ...brand.files,
93
- ]);
94
- const files = new Map(kitFiles);
95
- const snippets = new Set<string>();
96
- const processor = createProcessor({site: siteConfig, root: docsRoot, files, snippets});
97
- const [docs, home] = await Promise.all([
98
- readDocs({root: docsRoot, processor, reserved: siteConfig.url === undefined ? undefined : crawling_reserved_roots}),
99
- readHome({root: docsRoot, processor}),
100
- ]);
101
- const store = {docs, home};
102
- const crawling = siteConfig.url === undefined ? undefined : toCrawlingApp({url: siteConfig.url, store});
103
- const app = createApp({
104
- site: siteConfig,
105
- store,
106
- assets: {stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys(), ...body.files.keys()], reload: command === "dev"},
107
- });
108
-
109
- if (command === "build") {
110
- // 삭제된 문서·자원의 잔여 파일 방지
111
- await rm(outDir, {recursive: true, force: true});
112
-
113
- const result = await toSSG(app, {writeFile, mkdir}, {dir: outDir});
114
-
115
- if (!result.success) {
116
- throw result.error;
117
- }
118
-
119
- const crawlerResult = crawling === undefined ? undefined : await toSSG(crawling, {writeFile, mkdir}, {dir: outDir});
120
-
121
- if (crawlerResult?.success === false) {
122
- throw crawlerResult.error;
123
- }
124
-
125
- for (const [url, file] of files) {
126
- await mkdir(dirname(join(outDir, url)), {recursive: true});
127
- await copyFile(file, join(outDir, url));
128
- }
129
-
130
- console.log(
131
- `${crawlerResult === undefined ? result.files.length : result.files.length + crawlerResult.files.length} files, ${files.size} assets → ${relative(process.cwd(), outDir)}`,
132
- );
133
-
134
- return;
135
- }
136
-
137
- const reload = new EventEmitter();
138
- let generation = 0;
139
-
140
- serve({fetch: createDevApp({pages: app, crawling, files, reload}).fetch, port: siteConfig.port}, (info) => console.log(`http://localhost:${info.port}/`));
141
-
142
- /**
143
- * 갱신은 하나씩 실행 · 연속 저장 합치기 · 최신 변경만 적용
144
- * 문서 수가 많아도 파일 이벤트마다 전체 렌더링이 동시에 쌓이지 않음
145
- */
146
- const reloadDocs = debounce(
147
- toChangeQueue({
148
- run: async () => {
149
- const currentGeneration = generation;
150
- const nextFiles = new Map(kitFiles);
151
- const nextSnippets = new Set<string>();
152
- const nextProcessor = createProcessor({site: siteConfig, root: docsRoot, files: nextFiles, snippets: nextSnippets});
153
- const [docs, home] = await Promise.all([
154
- readDocs({root: docsRoot, processor: nextProcessor, reserved: siteConfig.url === undefined ? undefined : crawling_reserved_roots}),
155
- readHome({root: docsRoot, processor: nextProcessor}),
156
- ]);
157
-
158
- if (currentGeneration !== generation) {
159
- return;
160
- }
161
-
162
- files.clear();
163
- for (const entry of nextFiles) {
164
- files.set(...entry);
165
- }
166
- snippets.clear();
167
- for (const entry of nextSnippets) {
168
- snippets.add(entry);
169
- }
170
- store.docs = docs;
171
- store.home = home;
172
- reload.emit("change");
173
- },
174
- onError: (error) => console.error(`${copy_error_prefix}: ${toErrorMessage(error)}`),
175
- }),
176
- cli_reload_delay_ms,
177
- );
178
-
179
- /**
180
- * 입력 변경 감지 · 출력·설치 폴더 제외 · 누락 자원 추가도 다시 확인 · 불러온 스니펫 파일 변경 포함
181
- */
182
- const handleDocsChange = (_event: string, filename: string | null) => {
183
- if (filename !== null) {
184
- const segments = filename.split(sep);
185
- const isSnippet = snippets.has(join(docsRoot, filename));
186
- if (
187
- segments.includes("dist") ||
188
- segments.includes("node_modules") ||
189
- (!isSnippet && !/\.mdx?$/i.test(filename) && !asset_media_extensions.has(extname(filename).toLowerCase()))
190
- ) {
191
- return;
192
- }
193
- }
194
- generation += 1;
195
- reloadDocs();
196
- };
197
-
198
- watch(docsRoot, {recursive: true}, handleDocsChange);
199
- };
200
-
201
- try {
202
- await main();
203
- } catch (error) {
204
- console.error(`${copy_error_prefix}: ${toErrorMessage(error)}`);
205
- process.exit(1);
206
- }
package/src/env.d.ts DELETED
@@ -1,6 +0,0 @@
1
- /// <reference types="mdast-util-to-hast" />
2
-
3
- /**
4
- * 컴포넌트 CSS 부수효과 import · esbuild CSS 묶음 대상
5
- */
6
- declare module "*.css";
@@ -1,35 +0,0 @@
1
- import {WgProse} from "@/component/widget/prose/wg-prose";
2
- import {WgShell} from "@/component/widget/shell/wg-shell";
3
- import type {Doc} from "@/type/doc";
4
- import type {SiteAssets} from "@/type/site-assets";
5
- import type {SiteConfig} from "@/type/site-config";
6
-
7
- /**
8
- * /:slug/ 문서 페이지 입력 · 렌더링된 HTML 사용
9
- */
10
- export interface PgDocProps {
11
- /**
12
- * 검증된 사이트 설정
13
- */
14
- site: SiteConfig;
15
- /**
16
- * 사이드바의 전체 문서
17
- */
18
- docs: Doc[];
19
- /**
20
- * HTML 머리의 공통 자원
21
- */
22
- assets: SiteAssets;
23
- /**
24
- * 현재 페이지의 문서
25
- */
26
- doc: Doc;
27
- }
28
-
29
- export const PgDoc = (props: PgDocProps) => {
30
- return (
31
- <WgShell site={props.site} docs={props.docs} assets={props.assets} title={props.doc.data.name} current={props.doc.id} outline={props.doc.outline}>
32
- <WgProse html={props.doc.html} />
33
- </WgShell>
34
- );
35
- };
@@ -1,40 +0,0 @@
1
- import {WgProse} from "@/component/widget/prose/wg-prose";
2
- import {WgShell} from "@/component/widget/shell/wg-shell";
3
- import {copy_home_missing} from "@/constant/copy";
4
- import type {Doc} from "@/type/doc";
5
- import type {DocContent} from "@/type/doc-content";
6
- import type {SiteAssets} from "@/type/site-assets";
7
- import type {SiteConfig} from "@/type/site-config";
8
-
9
- /**
10
- * / 첫 화면 입력 · 문서 폴더 README의 본문과 목차
11
- */
12
- export interface PgHomeProps {
13
- /**
14
- * 검증된 사이트 설정
15
- */
16
- site: SiteConfig;
17
- /**
18
- * 사이드바의 전체 문서
19
- */
20
- docs: Doc[];
21
- /**
22
- * HTML 머리의 공통 자원
23
- */
24
- assets: SiteAssets;
25
- /**
26
- * README 렌더링 결과 · 파일이 없으면 작성 안내
27
- */
28
- home?: DocContent;
29
- }
30
-
31
- export const PgHome = (props: PgHomeProps) => {
32
- return (
33
- <WgShell site={props.site} docs={props.docs} assets={props.assets} outline={props.home?.outline}>
34
- {/**
35
- * README 원문 · 없을 때만 파일 작성 안내
36
- */}
37
- {props.home === undefined ? <WgProse head={{title: props.site.title, lead: copy_home_missing}} /> : <WgProse html={props.home.html} />}
38
- </WgShell>
39
- );
40
- };
@@ -1,74 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import {test} from "node:test";
3
- import {createNavigationStores} from "@/store/navigation/create-navigation-stores";
4
- import {navigation_scroll_storage_key} from "@/store/navigation/navigation-storage";
5
-
6
- const fixture = () => {
7
- const session = new Map<string, string>();
8
- const storage = {
9
- getItem: (key: string) => {
10
- const value = session.get(key);
11
- return value === undefined ? null : value;
12
- },
13
- setItem: (key: string, value: string) => {
14
- session.set(key, value);
15
- },
16
- removeItem: (key: string) => {
17
- session.delete(key);
18
- },
19
- };
20
- return {session, options: {session: () => storage}};
21
- };
22
-
23
- test("retains independent wide, desktop and drawer scroll positions within a tab", () => {
24
- const setup = fixture();
25
- const stores = createNavigationStores(setup.options);
26
- stores.scroll.setState({
27
- positions: {
28
- wide: {navigation: "docs", pathname: "/one/", documents: 450, outline: 300},
29
- desktop: {navigation: "docs", pathname: "/two/", documents: 750, outline: 100},
30
- drawer: {navigation: "docs", pathname: "/one/", documents: 200, outline: 800},
31
- },
32
- });
33
- assert.deepEqual(createNavigationStores(setup.options).scroll.getState(), stores.scroll.getState());
34
- });
35
-
36
- test("rejects malformed and unknown-version persistence without losing defaults", () => {
37
- for (const value of ["{", "null", '{"state":null,"version":1}', '{"state":{"positions":{}},"version":999}']) {
38
- const setup = fixture();
39
- setup.session.set(navigation_scroll_storage_key, value);
40
- const stores = createNavigationStores(setup.options);
41
- assert.deepEqual(stores.scroll.getState(), {positions: {}});
42
- }
43
- });
44
-
45
- test("rejects invalid scroll coordinates", () => {
46
- const setup = fixture();
47
- setup.session.set(
48
- navigation_scroll_storage_key,
49
- JSON.stringify({
50
- version: 1,
51
- state: {
52
- positions: {
53
- desktop: {navigation: "docs", pathname: "/one/", documents: -1, outline: 0},
54
- wide: {navigation: "docs", pathname: "/one/", documents: 100, outline: 20},
55
- drawer: {navigation: "docs", pathname: "/one/", documents: 100, outline: "20"},
56
- },
57
- },
58
- }),
59
- );
60
- const stores = createNavigationStores(setup.options);
61
- assert.deepEqual(stores.scroll.getState().positions.wide, {navigation: "docs", pathname: "/one/", documents: 100, outline: 20});
62
- assert.equal(stores.scroll.getState().positions.desktop, undefined);
63
- assert.equal(stores.scroll.getState().positions.drawer, undefined);
64
- });
65
-
66
- test("keeps in-memory interaction working when storage reads and writes are blocked", () => {
67
- const blocked = () => {
68
- throw new Error("Storage blocked");
69
- };
70
- const stores = createNavigationStores({session: blocked});
71
- stores.scroll.setState({positions: {desktop: {navigation: "docs", pathname: "/", documents: 100, outline: 200}}});
72
- stores.scroll.persist.rehydrate();
73
- assert.equal(stores.scroll.getState().positions.desktop?.documents, 100);
74
- });
@@ -1,59 +0,0 @@
1
- import {createJSONStorage, persist, type StateStorage} from "zustand/middleware";
2
- import {createStore} from "zustand/vanilla";
3
- import type {NavigationScrollState} from "@/store/navigation/navigation-state";
4
- import {navigation_scroll_storage_key, navigation_storage_version} from "@/store/navigation/navigation-storage";
5
- import {toNavigationScrollState} from "@/store/navigation/to-navigation-scroll-state";
6
-
7
- /**
8
- * 브라우저 저장소를 늦게 읽는 경계 · 차단 환경과 테스트의 메모리 저장소 지원
9
- */
10
- interface NavigationStorage {
11
- /**
12
- * 같은 탭 안에서만 복원할 스크롤 위치
13
- */
14
- session: () => StateStorage;
15
- }
16
-
17
- /**
18
- * 브라우저 탐색의 vanilla 스토어 생성기 · Hono Hook이 아닌 생성기이므로 use- 접두사를 붙이지 않음
19
- * 서버 요청은 이 생성기를 실행하지 않으며 저장 실패 시 메모리 상태 유지
20
- */
21
- export const createNavigationStores = (options: NavigationStorage) => {
22
- /**
23
- * 저장소 접근이 막혀도 persist 갱신이 스크롤 동작을 중단하지 않도록 격리
24
- */
25
- const toSafeStorage = (getStorage: NavigationStorage["session"]): StateStorage => {
26
- return {
27
- getItem: (key) => {
28
- // persist의 읽기 오류 경로로 보내 기존 메모리 상태를 유지 · null은 실제 저장소 초기화에만 사용
29
- return getStorage().getItem(key);
30
- },
31
- setItem: (key, value) => {
32
- try {
33
- return getStorage().setItem(key, value);
34
- } catch {
35
- /* 저장 실패 시에도 스토어의 메모리 상태는 유지 */
36
- }
37
- },
38
- removeItem: (key) => {
39
- try {
40
- return getStorage().removeItem(key);
41
- } catch {
42
- /* 저장소 차단이 탐색을 막지 않음 */
43
- }
44
- },
45
- };
46
- };
47
-
48
- return {
49
- scroll: createStore<NavigationScrollState>()(
50
- persist(() => ({positions: {}}), {
51
- name: navigation_scroll_storage_key,
52
- version: navigation_storage_version,
53
- storage: createJSONStorage(() => toSafeStorage(options.session)),
54
- merge: (persisted) => toNavigationScrollState(persisted),
55
- migrate: () => ({positions: {}}),
56
- }),
57
- ),
58
- };
59
- };
@@ -1,36 +0,0 @@
1
- /**
2
- * 스크롤 영역의 배치 · 넓은 3열, 좁은 2열, 모바일 모달
3
- */
4
- export type NavigationLayout = "wide" | "desktop" | "drawer";
5
-
6
- /**
7
- * 한 화면 배치의 마지막 탐색 위치 · 목록 변경과 다른 페이지의 목차는 재사용하지 않음
8
- */
9
- export interface NavigationPosition {
10
- /**
11
- * 현재 사이트의 공통 문서 URL·제목 목록
12
- */
13
- navigation: string;
14
- /**
15
- * 목차가 속한 페이지
16
- */
17
- pathname: string;
18
- /**
19
- * 공통 문서 목록의 세로 위치
20
- */
21
- documents: number;
22
- /**
23
- * 현재 페이지 목차의 세로 위치
24
- */
25
- outline: number;
26
- }
27
-
28
- /**
29
- * 같은 탭 안에서 유지하는 배치별 탐색 위치
30
- */
31
- export interface NavigationScrollState {
32
- /**
33
- * 아직 열지 않은 배치의 위치는 저장하지 않음
34
- */
35
- positions: Partial<Record<NavigationLayout, NavigationPosition>>;
36
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * 저장 형태가 바뀌면 기존 자료를 기본 상태로 돌리는 persist 버전
3
- */
4
- export const navigation_storage_version = 1;
5
-
6
- /**
7
- * 같은 탭에서 문서 이동 후 탐색 위치 복원 · 데스크톱과 드로어는 별도 저장
8
- */
9
- export const navigation_scroll_storage_key = "for-humanity:navigation-scroll";
@@ -1,42 +0,0 @@
1
- import type {NavigationPosition, NavigationScrollState} from "@/store/navigation/navigation-state";
2
-
3
- /**
4
- * 알 수 없는 저장 형태·음수·무한 좌표 제외 · 초기 HTML과 Zustand에 같은 검증 적용
5
- */
6
- export const toNavigationScrollState = (value: unknown): NavigationScrollState => {
7
- /**
8
- * 한 배치의 완전한 좌표만 복원 대상으로 수용
9
- */
10
- const toPosition = (position: unknown): NavigationPosition | undefined => {
11
- if (
12
- typeof position !== "object" ||
13
- position === null ||
14
- !("navigation" in position) ||
15
- typeof position.navigation !== "string" ||
16
- !("pathname" in position) ||
17
- typeof position.pathname !== "string" ||
18
- !("documents" in position) ||
19
- typeof position.documents !== "number" ||
20
- !Number.isFinite(position.documents) ||
21
- position.documents < 0 ||
22
- !("outline" in position) ||
23
- typeof position.outline !== "number" ||
24
- !Number.isFinite(position.outline) ||
25
- position.outline < 0
26
- ) {
27
- return;
28
- }
29
- return {navigation: position.navigation, pathname: position.pathname, documents: position.documents, outline: position.outline};
30
- };
31
-
32
- if (typeof value !== "object" || value === null || !("positions" in value) || typeof value.positions !== "object" || value.positions === null) {
33
- return {positions: {}};
34
- }
35
-
36
- const positions = {
37
- wide: toPosition("wide" in value.positions ? value.positions.wide : undefined),
38
- desktop: toPosition("desktop" in value.positions ? value.positions.desktop : undefined),
39
- drawer: toPosition("drawer" in value.positions ? value.positions.drawer : undefined),
40
- };
41
- return {positions: Object.fromEntries(Object.entries(positions).filter((entry) => entry[1] !== undefined))};
42
- };
@@ -1,28 +0,0 @@
1
- /*
2
- * 전역 상자 크기와 스크롤·움직임 기본값
3
- */
4
-
5
- * {
6
- box-sizing: border-box;
7
- }
8
-
9
- /* 페이지 바탕과 절 이동 · 초기 hash 보정 중 smooth scroll 일시 중지 */
10
- :root {
11
- background: var(--app-color-ground);
12
- scrollbar-gutter: stable;
13
- scroll-behavior: smooth;
14
- }
15
-
16
- /* 움직임 줄이기 · 컴포넌트보다 우선하는 전역 !important 예외 */
17
- @media (prefers-reduced-motion: reduce) {
18
- *,
19
- *::before,
20
- *::after {
21
- animation-duration: 0.01ms !important;
22
- animation-delay: 0s !important;
23
- animation-iteration-count: 1 !important;
24
- transition-duration: 0.01ms !important;
25
- transition-delay: 0s !important;
26
- scroll-behavior: auto !important;
27
- }
28
- }