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.
- package/CHANGELOG.md +39 -0
- package/README.md +16 -9
- package/dist/browser.js +14 -16
- package/dist/cli.css +2 -968
- package/dist/cli.js +92 -2318
- package/dist/config.js +1 -0
- package/dist/constant/copy.d.ts +100 -0
- package/dist/constant/site.d.ts +20 -0
- package/dist/constant/status.d.ts +19 -0
- package/dist/copy-C1uzvEnr.js +103 -0
- package/dist/group-path-XAThmzvC.js +10 -0
- package/dist/load-site-B-u5-jv0.js +2343 -0
- package/dist/logger-Dv1i9xSV.js +9 -0
- package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
- package/dist/mermaid/chunk--TN-qHgG.js +2 -0
- package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
- package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
- package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
- package/dist/mermaid/chunk-6HLei9i0.js +84 -0
- package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
- package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
- package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
- package/dist/mermaid/chunk-B--pNBQF.js +884 -0
- package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
- package/dist/mermaid/chunk-B58sEIY_.js +14 -0
- package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
- package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
- package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
- package/dist/mermaid/chunk-BKri0qr7.js +89 -0
- package/dist/mermaid/chunk-BL404pH5.js +26 -0
- package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
- package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
- package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
- package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
- package/dist/mermaid/chunk-BariMtWr.js +3020 -0
- package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
- package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
- package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
- package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
- package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
- package/dist/mermaid/chunk-BvVehae3.js +5069 -0
- package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
- package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
- package/dist/mermaid/chunk-CApNbSU9.js +6 -0
- package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
- package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
- package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
- package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
- package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
- package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
- package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
- package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
- package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
- package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
- package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
- package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
- package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
- package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
- package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
- package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
- package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
- package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
- package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
- package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
- package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
- package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
- package/dist/mermaid/chunk-CuYekbSv.js +2 -0
- package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
- package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
- package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
- package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
- package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
- package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
- package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
- package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
- package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
- package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
- package/dist/mermaid/chunk-DU69_VcF.js +363 -0
- package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
- package/dist/mermaid/chunk-DZe-4kde.js +20 -0
- package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
- package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
- package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
- package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
- package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
- package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
- package/dist/mermaid/chunk-DqGhppWe.js +2 -0
- package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
- package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
- package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
- package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
- package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
- package/dist/mermaid/chunk-KuPYb48V.js +275 -0
- package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
- package/dist/mermaid/chunk-MbInCS_6.js +28 -0
- package/dist/mermaid/chunk-MexOLyKV.js +355 -0
- package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
- package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
- package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
- package/dist/mermaid/chunk-TftHqGLg.js +490 -0
- package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
- package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
- package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
- package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
- package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
- package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
- package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
- package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
- package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
- package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
- package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
- package/dist/mermaid/chunk-yBz-vst0.js +976 -0
- package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
- package/dist/run-site-command-cqCjpIlc.js +129 -0
- package/dist/site-config-bllORGpm.js +90 -0
- package/dist/site.js +1 -0
- package/dist/start-dev-server-x7Ja5uwv.js +184 -0
- package/dist/to-change-queue-DbEnZGNK.js +34 -0
- package/dist/to-error-message-pF6_7wGK.js +16 -0
- package/dist/type/group-path.d.ts +7 -0
- package/dist/type/site-config.d.ts +57 -0
- package/package.json +34 -17
- package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
- package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
- package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
- package/src/component/widget/navigation/_constant/locale.ts +0 -9
- package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
- package/src/component/widget/navigation/_constant/navigation.ts +0 -9
- package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
- package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
- package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
- package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
- package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
- package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
- package/src/component/widget/navigation/_type/doc-group.ts +0 -24
- package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
- package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
- package/src/component/widget/navigation/_type/toc-group.ts +0 -39
- package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
- package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
- package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
- package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
- package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
- package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
- package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
- package/src/component/widget/navigation/wg-navigation.css +0 -282
- package/src/component/widget/navigation/wg-navigation.tsx +0 -420
- package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
- package/src/component/widget/prose/_constant/section.ts +0 -7
- package/src/component/widget/prose/_constant/status.ts +0 -9
- package/src/component/widget/prose/_function/has-block-content.ts +0 -30
- package/src/component/widget/prose/_function/rehype-head.ts +0 -31
- package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
- package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
- package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
- package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
- package/src/component/widget/prose/_function/remark-flow.ts +0 -26
- package/src/component/widget/prose/_function/remark-links.ts +0 -33
- package/src/component/widget/prose/_function/remark-parts.ts +0 -26
- package/src/component/widget/prose/_function/remark-status.ts +0 -59
- package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
- package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
- package/src/component/widget/prose/wg-prose.css +0 -484
- package/src/component/widget/prose/wg-prose.tsx +0 -43
- package/src/component/widget/shell/wg-shell.css +0 -63
- package/src/component/widget/shell/wg-shell.tsx +0 -88
- package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
- package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
- package/src/constant/asset.ts +0 -63
- package/src/constant/copy.ts +0 -133
- package/src/constant/doc.ts +0 -13
- package/src/constant/font.ts +0 -34
- package/src/constant/site.ts +0 -24
- package/src/constant/status.ts +0 -15
- package/src/entry/browser/browser.tsx +0 -22
- package/src/entry/cli/_constant/cli.ts +0 -19
- package/src/entry/cli/_constant/crawling.ts +0 -14
- package/src/entry/cli/_constant/snippet.ts +0 -21
- package/src/entry/cli/_function/create-app.tsx +0 -57
- package/src/entry/cli/_function/create-dev-app.ts +0 -87
- package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
- package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
- package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
- package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
- package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -91
- package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
- package/src/entry/cli/_function/read-docs.ts +0 -128
- package/src/entry/cli/_function/read-home.ts +0 -32
- package/src/entry/cli/_function/to-crawling-app.ts +0 -42
- package/src/entry/cli/cli.test.ts +0 -804
- package/src/entry/cli/cli.ts +0 -206
- package/src/env.d.ts +0 -6
- package/src/page/doc/pg-doc.tsx +0 -35
- package/src/page/home/pg-home.tsx +0 -40
- package/src/store/navigation/create-navigation-stores.test.ts +0 -74
- package/src/store/navigation/create-navigation-stores.ts +0 -59
- package/src/store/navigation/navigation-state.ts +0 -36
- package/src/store/navigation/navigation-storage.ts +0 -9
- package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
- package/src/style/base.css +0 -28
- package/src/style/token.css +0 -188
- package/src/type/doc-content.ts +0 -15
- package/src/type/doc-data.ts +0 -38
- package/src/type/doc-file-data.ts +0 -21
- package/src/type/doc-heading.ts +0 -17
- package/src/type/doc-outline.ts +0 -16
- package/src/type/doc-section.ts +0 -9
- package/src/type/doc.ts +0 -20
- package/src/type/group-path.ts +0 -7
- package/src/type/site-assets.ts +0 -25
- package/src/type/site-config.ts +0 -73
- package/src/type/vfile-data.d.ts +0 -10
- package/src/util/async/to-change-queue.test.ts +0 -58
- package/src/util/async/to-change-queue.ts +0 -43
- package/src/util/dom/find-hash-target.ts +0 -18
- package/src/util/dom/reveal-hash-target.ts +0 -15
- package/src/util/error/to-error-message.ts +0 -10
- package/src/util/file/to-asset-path.ts +0 -26
- package/src/util/font/to-font-css.test.ts +0 -41
- package/src/util/font/to-font-css.ts +0 -28
- package/src/util/mermaid/render-flow.js +0 -321
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
import {Fragment, useEffect, useLayoutEffect, useRef} from "hono/jsx";
|
|
3
|
-
import {WgCursorFace} from "@/component/widget/cursor-face/wg-cursor-face";
|
|
4
|
-
import {WgNavigation, type WgNavigationProps} from "@/component/widget/navigation/wg-navigation";
|
|
5
|
-
import {heading_highlight_hold_ms} from "@/component/widget/prose/_constant/heading-highlight";
|
|
6
|
-
import {asset_reload_path} from "@/constant/asset";
|
|
7
|
-
import {revealHashTarget} from "@/util/dom/reveal-hash-target";
|
|
8
|
-
import "./wg-shell-controls.css";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 셸의 서버·브라우저 공통 입력 · 탐색 계약을 그대로 사용하고 dev 갱신만 추가
|
|
12
|
-
*/
|
|
13
|
-
export interface WgShellControlsProps extends WgNavigationProps {
|
|
14
|
-
/**
|
|
15
|
-
* 문서 변경 알림에 따른 dev 새로고침 활성화
|
|
16
|
-
*/
|
|
17
|
-
reload: boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const WgShellControls = (props: WgShellControlsProps) => {
|
|
21
|
-
const headingRef = useRef<HTMLElement | null>(null);
|
|
22
|
-
const timerRef = useRef(0);
|
|
23
|
-
const arrivalRef = useRef<AbortController | null>(null);
|
|
24
|
-
const lifetimeRef = useRef<AbortController | null>(null);
|
|
25
|
-
const userScrollRef = useRef<AbortController | null>(null);
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 다음 앵커 이동과 해제에서 이전 강조·도착 감시·타이머를 함께 정리
|
|
29
|
-
*/
|
|
30
|
-
const clearHeadingHighlight = () => {
|
|
31
|
-
clearTimeout(timerRef.current);
|
|
32
|
-
timerRef.current = 0;
|
|
33
|
-
arrivalRef.current?.abort();
|
|
34
|
-
arrivalRef.current = null;
|
|
35
|
-
headingRef.current?.classList.remove("wg_prose__headingText--highlighted");
|
|
36
|
-
headingRef.current = null;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 본문 스크롤 도착 후 3초 확보 · 사이드바 자체의 scrollend는 제외
|
|
41
|
-
*/
|
|
42
|
-
const handleHighlightArrival = (event: Event) => {
|
|
43
|
-
if (event.target !== document) return;
|
|
44
|
-
clearTimeout(timerRef.current);
|
|
45
|
-
arrivalRef.current?.abort();
|
|
46
|
-
arrivalRef.current = null;
|
|
47
|
-
timerRef.current = window.setTimeout(clearHeadingHighlight, heading_highlight_hold_ms);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 도착 제목만 강조 · 같은 hash 재클릭도 유지 시간 재시작
|
|
52
|
-
*/
|
|
53
|
-
const highlightHeading = (target: HTMLElement | null) => {
|
|
54
|
-
clearHeadingHighlight();
|
|
55
|
-
headingRef.current = target === null ? null : target.querySelector<HTMLElement>(".wg_prose__headingText");
|
|
56
|
-
if (headingRef.current === null) return;
|
|
57
|
-
headingRef.current.classList.add("wg_prose__headingText--highlighted");
|
|
58
|
-
timerRef.current = window.setTimeout(clearHeadingHighlight, heading_highlight_hold_ms);
|
|
59
|
-
arrivalRef.current = new AbortController();
|
|
60
|
-
document.addEventListener("scrollend", handleHighlightArrival, {signal: arrivalRef.current.signal});
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 탐색 DOM이 다시 만들어져도 같은 hash의 접힌 Details 공개를 유지
|
|
65
|
-
*/
|
|
66
|
-
const handleHashClick = (event: MouseEvent) => {
|
|
67
|
-
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
68
|
-
const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
|
|
69
|
-
if (
|
|
70
|
-
link instanceof HTMLAnchorElement &&
|
|
71
|
-
(link.target === "" || link.target === "_self") &&
|
|
72
|
-
!link.hasAttribute("download") &&
|
|
73
|
-
link.origin === location.origin &&
|
|
74
|
-
link.pathname === location.pathname &&
|
|
75
|
-
link.search === location.search &&
|
|
76
|
-
link.hash
|
|
77
|
-
) {
|
|
78
|
-
const target = revealHashTarget(link.hash);
|
|
79
|
-
if (link.hash === location.hash) highlightHeading(target);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* hash 변경 시 접힌 대상을 공개하고 네이티브 스크롤·강조 적용
|
|
85
|
-
*/
|
|
86
|
-
const handleHashChange = () => {
|
|
87
|
-
const target = revealHashTarget(location.hash);
|
|
88
|
-
target?.scrollIntoView();
|
|
89
|
-
highlightHeading(target);
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const handleUserScroll = () => {
|
|
93
|
-
userScrollRef.current?.abort();
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 초기 폰트 로드 후 앵커 보정 · 해제된 인스턴스와 사용자 이동에 개입하지 않음
|
|
98
|
-
*/
|
|
99
|
-
const handlePageLoad = async () => {
|
|
100
|
-
const lifetime = lifetimeRef.current;
|
|
101
|
-
const hash = location.hash;
|
|
102
|
-
const target = revealHashTarget(hash);
|
|
103
|
-
await document.fonts.ready;
|
|
104
|
-
if (lifetime === null || lifetime.signal.aborted) return;
|
|
105
|
-
if (target !== null && !userScrollRef.current?.signal.aborted && hash === location.hash) {
|
|
106
|
-
target.scrollIntoView({behavior: "instant"});
|
|
107
|
-
highlightHeading(target);
|
|
108
|
-
}
|
|
109
|
-
document.documentElement.style.removeProperty("scroll-behavior");
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* 셸은 본문 앞에서 마운트 · 본문 파싱 이후에만 초기 접힘 대상 조회
|
|
114
|
-
*/
|
|
115
|
-
const handleBodyReady = () => {
|
|
116
|
-
revealHashTarget(location.hash);
|
|
117
|
-
if (document.readyState === "complete") void handlePageLoad();
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* 본문 이벤트의 설치·정리는 셸이 소유 · SSR에서는 DOM에 접근하지 않음
|
|
122
|
-
*/
|
|
123
|
-
useLayoutEffect(() => {
|
|
124
|
-
const lifetime = new AbortController();
|
|
125
|
-
lifetimeRef.current = lifetime;
|
|
126
|
-
userScrollRef.current = new AbortController();
|
|
127
|
-
document.documentElement.style.scrollBehavior = "auto";
|
|
128
|
-
document.addEventListener("click", handleHashClick, {signal: lifetime.signal});
|
|
129
|
-
addEventListener("hashchange", handleHashChange, {signal: lifetime.signal});
|
|
130
|
-
addEventListener("load", handlePageLoad, {once: true, signal: lifetime.signal});
|
|
131
|
-
for (const type of ["wheel", "touchmove", "keydown", "mousedown"]) {
|
|
132
|
-
addEventListener(type, handleUserScroll, {once: true, passive: true, signal: lifetime.signal});
|
|
133
|
-
}
|
|
134
|
-
if (document.readyState === "loading") {
|
|
135
|
-
document.addEventListener("DOMContentLoaded", handleBodyReady, {once: true, signal: lifetime.signal});
|
|
136
|
-
} else {
|
|
137
|
-
handleBodyReady();
|
|
138
|
-
}
|
|
139
|
-
return () => {
|
|
140
|
-
lifetime.abort();
|
|
141
|
-
lifetimeRef.current = null;
|
|
142
|
-
userScrollRef.current?.abort();
|
|
143
|
-
userScrollRef.current = null;
|
|
144
|
-
clearHeadingHighlight();
|
|
145
|
-
document.documentElement.style.removeProperty("scroll-behavior");
|
|
146
|
-
};
|
|
147
|
-
}, []);
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* dev 새로고침 연결도 브라우저 셸의 수명에 맞춰 닫음
|
|
151
|
-
*/
|
|
152
|
-
useEffect(() => {
|
|
153
|
-
if (!props.reload || lifetimeRef.current === null) return;
|
|
154
|
-
const source = new EventSource(asset_reload_path);
|
|
155
|
-
source.onmessage = () => location.reload();
|
|
156
|
-
return () => source.close();
|
|
157
|
-
}, [props.reload]);
|
|
158
|
-
|
|
159
|
-
return (
|
|
160
|
-
<Fragment>
|
|
161
|
-
{/**
|
|
162
|
-
* 별도 DOM 경계로 탐색 갱신이 커서 형제 사이에서 dialog를 재삽입하지 않게 함
|
|
163
|
-
*/}
|
|
164
|
-
<div className={clsx("wg_shellControls__navigation")}>
|
|
165
|
-
<WgNavigation data={props.data} stores={props.stores} />
|
|
166
|
-
</div>
|
|
167
|
-
{props.data.cursorFace && <WgCursorFace ready={props.stores !== undefined} />}
|
|
168
|
-
</Fragment>
|
|
169
|
-
);
|
|
170
|
-
};
|
package/src/constant/asset.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 정적 빌드와 dev의 공통 자원 URL
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 문서 경로와 구분한 자원 폴더
|
|
7
|
-
*/
|
|
8
|
-
export const asset_dir = "_fh";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 내용 지문을 붙일 esbuild CSS의 기본 URL
|
|
12
|
-
*/
|
|
13
|
-
export const asset_style_path = `/${asset_dir}/style.css`;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 자체 호스팅 글꼴 폴더
|
|
17
|
-
*/
|
|
18
|
-
export const asset_font_dir = `/${asset_dir}/fonts`;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* dev 문서 변경 알림 SSE URL
|
|
22
|
-
*/
|
|
23
|
-
export const asset_reload_path = `/${asset_dir}/reload`;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 탭 아이콘 URL
|
|
27
|
-
*/
|
|
28
|
-
export const asset_favicon_path = "/favicon.svg";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* dev 자원 응답의 확장자별 content-type
|
|
32
|
-
*/
|
|
33
|
-
export const asset_content_types: Record<string, string> = {
|
|
34
|
-
".css": "text/css; charset=utf-8",
|
|
35
|
-
".js": "text/javascript; charset=utf-8",
|
|
36
|
-
".woff2": "font/woff2",
|
|
37
|
-
".svg": "image/svg+xml",
|
|
38
|
-
".png": "image/png",
|
|
39
|
-
".jpg": "image/jpeg",
|
|
40
|
-
".jpeg": "image/jpeg",
|
|
41
|
-
".gif": "image/gif",
|
|
42
|
-
".webp": "image/webp",
|
|
43
|
-
".avif": "image/avif",
|
|
44
|
-
".pdf": "application/pdf",
|
|
45
|
-
".csv": "text/csv; charset=utf-8",
|
|
46
|
-
".txt": "text/plain; charset=utf-8",
|
|
47
|
-
".zip": "application/zip",
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 미등록 확장자의 content-type
|
|
52
|
-
*/
|
|
53
|
-
export const asset_content_type_default = "application/octet-stream";
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 문서에서 참조한 그림·첨부 자원의 예약 경로
|
|
57
|
-
*/
|
|
58
|
-
export const asset_media_dir = `/${asset_dir}/media`;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* 명시적 로컬 참조로 배포할 수 있는 파일 형식 · 실행 파일·소스·설정 제외
|
|
62
|
-
*/
|
|
63
|
-
export const asset_media_extensions = new Set([".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".avif", ".pdf", ".csv", ".txt", ".zip"]);
|
package/src/constant/copy.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 화면·CLI 공통 문구 · 번역 분리의 단일 출처
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 사이트 제목의 기본값 · 사이드바와 탭
|
|
7
|
-
*/
|
|
8
|
-
export const copy_site_title_default = "for humanity";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 사이드바의 접근 가능한 이름
|
|
12
|
-
*/
|
|
13
|
-
export const copy_nav_aria_label = "Document navigation";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 모바일 문서 탐색 열기 버튼
|
|
17
|
-
*/
|
|
18
|
-
export const copy_nav_open = "Open navigation";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 모바일 문서 탐색 닫기 버튼
|
|
22
|
-
*/
|
|
23
|
-
export const copy_nav_close = "Close navigation";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 모바일 문서 탐색 대화상자 제목
|
|
27
|
-
*/
|
|
28
|
-
export const copy_nav_title = "Navigation";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* README가 없는 홈의 안내
|
|
32
|
-
*/
|
|
33
|
-
export const copy_home_missing = "문서 폴더에 README.md를 추가하면 이곳에 홈 화면으로 표시됩니다.";
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 현재 문서 목차 라벨
|
|
37
|
-
*/
|
|
38
|
-
export const copy_nav_toc_label = "On this page";
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 대소문자만 다른 README 중복 오류
|
|
42
|
-
*/
|
|
43
|
-
export const copy_error_home_clash = "홈 README가 겹친다";
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* CLI 오류 접두사
|
|
47
|
-
*/
|
|
48
|
-
export const copy_error_prefix = "for-humanity";
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 미지원 명령 오류
|
|
52
|
-
*/
|
|
53
|
-
export const copy_error_unknown_command = "모르는 명령이다";
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 설정 검증 오류 · 항목 경로와 이유 추가
|
|
57
|
-
*/
|
|
58
|
-
export const copy_error_config = "설정이 틀렸다";
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* 공개 사이트 URL의 미지원 경로·자격 증명·검색·앵커 오류
|
|
62
|
-
*/
|
|
63
|
-
export const copy_error_site_url = "url은 사용자 정보·하위 경로·query·hash가 없는 HTTP(S) 사이트 루트여야 한다";
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 문서 frontmatter 오류 · 파일과 항목 추가
|
|
67
|
-
*/
|
|
68
|
-
export const copy_error_frontmatter = "frontmatter가 올바르지 않다";
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* 탐색 순서에 같은 묶음을 두 번 지정한 설정 오류
|
|
72
|
-
*/
|
|
73
|
-
export const copy_error_navigation_clash = "navigation의 묶음이 겹친다";
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 빈 id·예약 경로·URL 예약 문자 오류
|
|
77
|
-
*/
|
|
78
|
-
export const copy_error_doc_id = "문서 id에 사용할 수 없는 경로";
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 확장자·대소문자 정규화 후 문서 경로 중복
|
|
82
|
-
*/
|
|
83
|
-
export const copy_error_doc_id_clash = "문서 id가 겹친다";
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* 누락되거나 홈을 가리키는 부모 문서 참조
|
|
87
|
-
*/
|
|
88
|
-
export const copy_error_doc_parent_missing = "부모 문서가 없다";
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* 자기 참조 또는 순환하는 문서 부모 경로
|
|
92
|
-
*/
|
|
93
|
-
export const copy_error_doc_parent_cycle = "문서 parent가 순환한다";
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* 분류 경로가 다른 문서 사이의 부모 참조
|
|
97
|
-
*/
|
|
98
|
-
export const copy_error_doc_parent_group = "부모 문서와 group이 다르다";
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 흐름도 렌더링 실패
|
|
102
|
-
*/
|
|
103
|
-
export const copy_error_flow = "흐름도를 그리지 못했다";
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* 미지원 블록 지시문 오류
|
|
107
|
-
*/
|
|
108
|
-
export const copy_error_unknown_directive = "모르는 부품이다";
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 부품의 작성 계약 오류 · 이름과 수정 기준 추가
|
|
112
|
-
*/
|
|
113
|
-
export const copy_error_directive_syntax = "부품 문법이 올바르지 않다";
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* 없는 Markdown 링크 경고 · 빌드 계속
|
|
117
|
-
*/
|
|
118
|
-
export const copy_warn_broken_link = "없는 문서로 건 링크다";
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* 미등록 날짜 상태 문구 경고
|
|
122
|
-
*/
|
|
123
|
-
export const copy_warn_unknown_status = "설정에 없는 상태 문구다";
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* 문서에서 참조한 로컬 자원의 경로·형식 오류
|
|
127
|
-
*/
|
|
128
|
-
export const copy_error_asset = "자원이 올바르지 않다";
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* `<<<` 로 불러온 코드 스니펫의 경로·파일·region 오류
|
|
132
|
-
*/
|
|
133
|
-
export const copy_error_snippet = "코드 스니펫이 올바르지 않다";
|
package/src/constant/doc.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 기존 frontmatter type의 호환 값 · 모두 같은 Markdown 렌더링
|
|
3
|
-
* 새 문서는 type 생략 권장
|
|
4
|
-
*/
|
|
5
|
-
export const doc_type = {
|
|
6
|
-
document: "document",
|
|
7
|
-
blueprint: "blueprint",
|
|
8
|
-
} as const;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 순서 미지정 문서는 번호가 있는 문서 뒤에서 이름순 배치
|
|
12
|
-
*/
|
|
13
|
-
export const doc_order_default = Number.MAX_SAFE_INTEGER;
|
package/src/constant/font.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 패키지 내장 글꼴 · OFL 라이선스는 각 폴더
|
|
3
|
-
* CLI에서 @font-face와 자원 생성 · font-family는 token.css 소유
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 본문 영문·코드·흐름도 글꼴 CSS · 패키지 기준 경로 · Regular·SemiBold 두 파일
|
|
8
|
-
*/
|
|
9
|
-
export const font_mono_css = "src/asset/font/monoplex-kr/monoplex-kr.css";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 본문 한글 글꼴 CSS · IBM Plex Sans KR Regular·SemiBold · 한글 unicode-range
|
|
13
|
-
*/
|
|
14
|
-
export const font_body_css = "src/asset/font/ibm-plex-sans-kr/ibm-plex-sans-kr.css";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 사이트 이름 글꼴 CSS · Architects Daughter Regular · 라틴 subset
|
|
18
|
-
*/
|
|
19
|
-
export const font_brand_css = "src/asset/font/architects-daughter/architects-daughter.css";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 늦게 받은 글꼴로 이미 보이는 대체 글꼴을 교체하지 않는 표시 정책
|
|
23
|
-
*/
|
|
24
|
-
export const font_display_strategy = "optional";
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 글꼴 파일 내용의 URL 지문 길이 · 파일 변경 시 이전 캐시와 분리
|
|
28
|
-
*/
|
|
29
|
-
export const font_hash_length = 12;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 내용 지문이 붙은 글꼴만 장기 재사용 · CSS와 브라우저 스크립트는 대상 제외
|
|
33
|
-
*/
|
|
34
|
-
export const font_cache_control = "public, max-age=31536000, immutable";
|
package/src/constant/site.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 설정 파일 부재 시 입력 · 스키마 기본값 적용
|
|
3
|
-
*/
|
|
4
|
-
export const site_config_absent = {};
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 탐색 순서 생략 시 모든 묶음을 이름순 배치
|
|
8
|
-
*/
|
|
9
|
-
export const site_navigation_default: readonly string[] = [];
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* dev·preview 서버 기본 포트
|
|
13
|
-
*/
|
|
14
|
-
export const site_port_default = 4321;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 포트 번호 하한 · TCP
|
|
18
|
-
*/
|
|
19
|
-
export const site_port_min = 1;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 포트 번호 상한 · TCP
|
|
23
|
-
*/
|
|
24
|
-
export const site_port_max = 65535;
|
package/src/constant/status.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 상태 표지 종류 · verified 초록, unverified amber
|
|
3
|
-
*/
|
|
4
|
-
export const status_kind = {
|
|
5
|
-
verified: "verified",
|
|
6
|
-
unverified: "unverified",
|
|
7
|
-
} as const;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 기본 상태 문구 · 확인됨은 뒤의 날짜 포함
|
|
11
|
-
*/
|
|
12
|
-
export const status_default_phrases = [
|
|
13
|
-
{phrase: "확인됨", kind: status_kind.verified, date: true},
|
|
14
|
-
{phrase: "확인되지 않았다", kind: status_kind.unverified},
|
|
15
|
-
];
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 브라우저 진입 · 서버 자료 검증과 저장소 생성 후 공통 셸 컨트롤을 한 번 마운트
|
|
3
|
-
*/
|
|
4
|
-
import {createRoot} from "hono/jsx/dom/client";
|
|
5
|
-
import {navigationDataSchema} from "@/component/widget/navigation/_constant/navigation-data-schema";
|
|
6
|
-
import {WgShellControls} from "@/component/widget/shell-controls/wg-shell-controls";
|
|
7
|
-
import {createNavigationStores} from "@/store/navigation/create-navigation-stores";
|
|
8
|
-
|
|
9
|
-
const root = document.querySelector<HTMLElement>("[data-shell-browser-root]");
|
|
10
|
-
const payload = document.getElementById("fh-navigation-data");
|
|
11
|
-
|
|
12
|
-
if (root !== null && payload !== null) {
|
|
13
|
-
try {
|
|
14
|
-
const value: unknown = JSON.parse(payload.textContent);
|
|
15
|
-
const data = navigationDataSchema.parse(value);
|
|
16
|
-
const stores = createNavigationStores({session: () => sessionStorage});
|
|
17
|
-
createRoot(root).render(<WgShellControls data={data} stores={stores} reload={root.hasAttribute("data-shell-reload")} />);
|
|
18
|
-
} catch (error) {
|
|
19
|
-
// 초기화 오류에서도 서버의 링크·본문과 네이티브 스크롤 유지
|
|
20
|
-
console.error("for-humanity browser initialization failed", error);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 명령 생략 시 dev
|
|
3
|
-
*/
|
|
4
|
-
export const cli_default_command = "dev";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 문서 폴더 생략 시 현재 폴더
|
|
8
|
-
*/
|
|
9
|
-
export const cli_default_docs_dir = ".";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 문서 폴더의 선택 설정 파일
|
|
13
|
-
*/
|
|
14
|
-
export const cli_config_file_name = "for-humanity.config.mjs";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 연속 저장을 하나의 문서 갱신으로 합치는 대기 시간 · ms
|
|
18
|
-
*/
|
|
19
|
-
export const cli_reload_delay_ms = 150;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 크롤러 안내 파일의 사이트 루트 경로
|
|
3
|
-
*/
|
|
4
|
-
export const crawling_robots_path = "/robots.txt";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 공개 페이지 목록의 사이트 루트 경로
|
|
8
|
-
*/
|
|
9
|
-
export const crawling_sitemap_path = "/sitemap.xml";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 공개 크롤러 파일과 정적 출력이 충돌하는 문서의 첫 경로 조각
|
|
13
|
-
*/
|
|
14
|
-
export const crawling_reserved_roots = [crawling_robots_path.slice(1), crawling_sitemap_path.slice(1)];
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 스니펫 줄 · `<<< ./path.ext`, 선택 `#region`, 선택 메타(펜스 메타와 같음)
|
|
3
|
-
*/
|
|
4
|
-
export const snippet_pattern = /^<<<\s+(\S+?)(?:#([\w-]+))?(?:\s+(.+?))?\s*$/;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* region 표시 줄 · 주석 모양은 자유 · `#region 이름`, `#endregion 이름`
|
|
8
|
-
*/
|
|
9
|
-
export const snippet_region_pattern = /^\s*\S*\s*#(end)?region\s+([\w-]+)/;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 확장자 → 펜스 언어 · 없으면 확장자 그대로
|
|
13
|
-
*/
|
|
14
|
-
export const snippet_language_by_extension: Record<string, string> = {
|
|
15
|
-
".cjs": "js",
|
|
16
|
-
".md": "markdown",
|
|
17
|
-
".mjs": "js",
|
|
18
|
-
".mts": "ts",
|
|
19
|
-
".txt": "text",
|
|
20
|
-
".yml": "yaml",
|
|
21
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import {Hono} from "hono";
|
|
2
|
-
import {html} from "hono/html";
|
|
3
|
-
import type {Child} from "hono/jsx";
|
|
4
|
-
import {ssgParams} from "hono/ssg";
|
|
5
|
-
import {PgDoc} from "@/page/doc/pg-doc";
|
|
6
|
-
import {PgHome} from "@/page/home/pg-home";
|
|
7
|
-
import type {Doc} from "@/type/doc";
|
|
8
|
-
import type {DocContent} from "@/type/doc-content";
|
|
9
|
-
import type {SiteAssets} from "@/type/site-assets";
|
|
10
|
-
import type {SiteConfig} from "@/type/site-config";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 페이지 앱 입력 계약
|
|
14
|
-
*/
|
|
15
|
-
export interface AppOptions {
|
|
16
|
-
/**
|
|
17
|
-
* 검증된 사이트 설정
|
|
18
|
-
*/
|
|
19
|
-
site: SiteConfig;
|
|
20
|
-
/**
|
|
21
|
-
* 렌더링 대상 홈과 문서 · dev 재처리 시 함께 교체
|
|
22
|
-
*/
|
|
23
|
-
store: {docs: Doc[]; home?: DocContent};
|
|
24
|
-
/**
|
|
25
|
-
* HTML 머리에 포함할 공통 자원
|
|
26
|
-
*/
|
|
27
|
-
assets: SiteAssets;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Hono JSX 페이지에 HTML 문서 선언 추가 · 서버와 정적 출력에서 같은 렌더러 사용
|
|
32
|
-
*/
|
|
33
|
-
const toHtml = (page: Child) => {
|
|
34
|
-
return html`<!DOCTYPE html>${page}`;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 첫 화면 / · 문서 /:slug{.+}/ · 하위 폴더 id 지원
|
|
39
|
-
* 자원 wildcard와 정규식 매개변수 혼합 시 TrieRouter fallback으로 중첩 경로 불일치
|
|
40
|
-
* 자원·SSE는 createDevApp의 별도 앱 소유
|
|
41
|
-
*/
|
|
42
|
-
export const createApp = (options: AppOptions) => {
|
|
43
|
-
const app = new Hono();
|
|
44
|
-
|
|
45
|
-
app.get("/", (c) => c.html(toHtml(<PgHome site={options.site} docs={options.store.docs} assets={options.assets} home={options.store.home} />)));
|
|
46
|
-
app.get(
|
|
47
|
-
"/:slug{.+}/",
|
|
48
|
-
ssgParams(() => options.store.docs.map((doc) => ({slug: doc.id}))),
|
|
49
|
-
(c) => {
|
|
50
|
-
const doc = options.store.docs.find((entry) => entry.id === c.req.param("slug"));
|
|
51
|
-
|
|
52
|
-
return doc === undefined ? c.notFound() : c.html(toHtml(<PgDoc site={options.site} docs={options.store.docs} assets={options.assets} doc={doc} />));
|
|
53
|
-
},
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
return app;
|
|
57
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import type {EventEmitter} from "node:events";
|
|
2
|
-
import {readFile} from "node:fs/promises";
|
|
3
|
-
import {extname} from "node:path";
|
|
4
|
-
import {type Context, Hono} from "hono";
|
|
5
|
-
import {streamSSE} from "hono/streaming";
|
|
6
|
-
import {asset_content_type_default, asset_content_types, asset_dir, asset_favicon_path, asset_reload_path} from "@/constant/asset";
|
|
7
|
-
import {font_cache_control} from "@/constant/font";
|
|
8
|
-
import {crawling_robots_path, crawling_sitemap_path} from "@/entry/cli/_constant/crawling";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 개발 서버 입력 계약
|
|
12
|
-
*/
|
|
13
|
-
export interface DevOptions {
|
|
14
|
-
/**
|
|
15
|
-
* 정적 자원 외 요청을 처리할 페이지 앱
|
|
16
|
-
*/
|
|
17
|
-
pages: Hono;
|
|
18
|
-
/**
|
|
19
|
-
* 공개 URL을 설정한 프로젝트의 크롤러 파일 앱
|
|
20
|
-
*/
|
|
21
|
-
crawling?: Hono;
|
|
22
|
-
/**
|
|
23
|
-
* 자원 URL → 파일 경로 · 정적 빌드와 동일 목록
|
|
24
|
-
*/
|
|
25
|
-
files: Map<string, string>;
|
|
26
|
-
/**
|
|
27
|
-
* 문서 변경 알림 · SSE 새로고침의 change 이벤트
|
|
28
|
-
*/
|
|
29
|
-
reload: EventEmitter;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 개발 전용 자원·SSE와 선택적 크롤러 응답 · 나머지 요청은 페이지 앱에 위임
|
|
34
|
-
* 정적 빌드의 페이지 라우트와 분리
|
|
35
|
-
*/
|
|
36
|
-
export const createDevApp = (options: DevOptions) => {
|
|
37
|
-
const app = new Hono();
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 등록된 URL의 자원 응답 · 미등록 시 404
|
|
41
|
-
*/
|
|
42
|
-
const handleAsset = async (c: Context) => {
|
|
43
|
-
const file = options.files.get(c.req.path);
|
|
44
|
-
|
|
45
|
-
if (file === undefined) {
|
|
46
|
-
return c.notFound();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
c.header("content-type", asset_content_types[extname(file).toLowerCase()] ?? asset_content_type_default);
|
|
50
|
-
|
|
51
|
-
if (extname(file) === ".woff2") {
|
|
52
|
-
c.header("Cache-Control", font_cache_control);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return c.body(await readFile(file));
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
app.get(asset_reload_path, (c) =>
|
|
59
|
-
streamSSE(
|
|
60
|
-
c,
|
|
61
|
-
(stream) =>
|
|
62
|
-
new Promise((done) => {
|
|
63
|
-
/**
|
|
64
|
-
* 문서 변경의 SSE 전송 · 전송 후 연결 종료
|
|
65
|
-
*/
|
|
66
|
-
const handleChange = async () => {
|
|
67
|
-
await stream.writeSSE({data: "change"});
|
|
68
|
-
done();
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
options.reload.once("change", handleChange);
|
|
72
|
-
stream.onAbort(() => {
|
|
73
|
-
options.reload.off("change", handleChange);
|
|
74
|
-
done();
|
|
75
|
-
});
|
|
76
|
-
}),
|
|
77
|
-
),
|
|
78
|
-
);
|
|
79
|
-
app.get(`/${asset_dir}/*`, handleAsset);
|
|
80
|
-
app.get(asset_favicon_path, handleAsset);
|
|
81
|
-
if (options.crawling !== undefined) {
|
|
82
|
-
app.on("GET", [crawling_robots_path, crawling_sitemap_path], (c) => options.crawling?.fetch(c.req.raw, c.env) ?? c.notFound());
|
|
83
|
-
}
|
|
84
|
-
app.all("/*", (c) => options.pages.fetch(c.req.raw, c.env));
|
|
85
|
-
|
|
86
|
-
return app;
|
|
87
|
-
};
|