fumadocs-core 16.4.0 → 16.4.2

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 (278) hide show
  1. package/dist/advanced-BRT5Ij43.js +80 -0
  2. package/dist/advanced-BRT5Ij43.js.map +1 -0
  3. package/dist/algolia-CBBN8R6-.d.ts +68 -0
  4. package/dist/algolia-CBBN8R6-.d.ts.map +1 -0
  5. package/dist/algolia-CQPXCnjV.js +49 -0
  6. package/dist/algolia-CQPXCnjV.js.map +1 -0
  7. package/dist/breadcrumb.d.ts +29 -27
  8. package/dist/breadcrumb.d.ts.map +1 -0
  9. package/dist/breadcrumb.js +55 -72
  10. package/dist/breadcrumb.js.map +1 -0
  11. package/dist/chunk-B-ezknvj.js +42 -0
  12. package/dist/codeblock-utils-lld8UiQo.d.ts +37 -0
  13. package/dist/codeblock-utils-lld8UiQo.d.ts.map +1 -0
  14. package/dist/content/github.d.ts +43 -32
  15. package/dist/content/github.d.ts.map +1 -0
  16. package/dist/content/github.js +29 -43
  17. package/dist/content/github.js.map +1 -0
  18. package/dist/content/index.d.ts +20 -13
  19. package/dist/content/index.d.ts.map +1 -0
  20. package/dist/content/index.js +17 -23
  21. package/dist/content/index.js.map +1 -0
  22. package/dist/content/mdx/preset-bundler.d.ts +22 -24
  23. package/dist/content/mdx/preset-bundler.d.ts.map +1 -0
  24. package/dist/content/mdx/preset-bundler.js +38 -69
  25. package/dist/content/mdx/preset-bundler.js.map +1 -0
  26. package/dist/content/mdx/preset-runtime.d.ts +22 -24
  27. package/dist/content/mdx/preset-runtime.d.ts.map +1 -0
  28. package/dist/content/mdx/preset-runtime.js +36 -68
  29. package/dist/content/mdx/preset-runtime.js.map +1 -0
  30. package/dist/content/toc.d.ts +7 -6
  31. package/dist/content/toc.d.ts.map +1 -0
  32. package/dist/content/toc.js +15 -19
  33. package/dist/content/toc.js.map +1 -0
  34. package/dist/definitions-DuxDer_c.d.ts +62 -0
  35. package/dist/definitions-DuxDer_c.d.ts.map +1 -0
  36. package/dist/dynamic-link.d.ts +7 -5
  37. package/dist/dynamic-link.d.ts.map +1 -0
  38. package/dist/dynamic-link.js +29 -27
  39. package/dist/dynamic-link.js.map +1 -0
  40. package/dist/fetch-B5e9CFfN.js +20 -0
  41. package/dist/fetch-B5e9CFfN.js.map +1 -0
  42. package/dist/framework/index.d.ts +38 -29
  43. package/dist/framework/index.d.ts.map +1 -0
  44. package/dist/framework/index.js +68 -17
  45. package/dist/framework/index.js.map +1 -0
  46. package/dist/framework/next.d.ts +15 -10
  47. package/dist/framework/next.d.ts.map +1 -0
  48. package/dist/framework/next.js +18 -26
  49. package/dist/framework/next.js.map +1 -0
  50. package/dist/framework/react-router.d.ts +15 -10
  51. package/dist/framework/react-router.d.ts.map +1 -0
  52. package/dist/framework/react-router.js +42 -55
  53. package/dist/framework/react-router.js.map +1 -0
  54. package/dist/framework/tanstack.d.ts +15 -10
  55. package/dist/framework/tanstack.d.ts.map +1 -0
  56. package/dist/framework/tanstack.js +54 -69
  57. package/dist/framework/tanstack.js.map +1 -0
  58. package/dist/framework/waku.d.ts +15 -10
  59. package/dist/framework/waku.d.ts.map +1 -0
  60. package/dist/framework/waku.js +47 -58
  61. package/dist/framework/waku.js.map +1 -0
  62. package/dist/highlight/client.d.ts +6 -7
  63. package/dist/highlight/client.d.ts.map +1 -0
  64. package/dist/highlight/client.js +22 -14
  65. package/dist/highlight/client.js.map +1 -0
  66. package/dist/highlight/index.d.ts +2 -30
  67. package/dist/highlight/index.js +3 -13
  68. package/dist/i18n/index.d.ts +2 -39
  69. package/dist/i18n/index.js +6 -7
  70. package/dist/i18n/index.js.map +1 -0
  71. package/dist/i18n/middleware.d.ts +36 -28
  72. package/dist/i18n/middleware.d.ts.map +1 -0
  73. package/dist/i18n/middleware.js +55 -73
  74. package/dist/i18n/middleware.js.map +1 -0
  75. package/dist/icon-Dt7IObrc.js +19 -0
  76. package/dist/icon-Dt7IObrc.js.map +1 -0
  77. package/dist/index-2U6Tl4--.d.ts +379 -0
  78. package/dist/index-2U6Tl4--.d.ts.map +1 -0
  79. package/dist/index-Bw-DCOra.d.ts +41 -0
  80. package/dist/index-Bw-DCOra.d.ts.map +1 -0
  81. package/dist/link.d.ts +17 -15
  82. package/dist/link.d.ts.map +1 -0
  83. package/dist/link.js +29 -9
  84. package/dist/link.js.map +1 -0
  85. package/dist/mdast-utils-mc9-X-PK.js +40 -0
  86. package/dist/mdast-utils-mc9-X-PK.js.map +1 -0
  87. package/dist/mdx-plugins/codeblock-utils.d.ts +2 -29
  88. package/dist/mdx-plugins/codeblock-utils.js +71 -9
  89. package/dist/mdx-plugins/codeblock-utils.js.map +1 -0
  90. package/dist/mdx-plugins/index.d.ts +15 -20
  91. package/dist/mdx-plugins/index.js +18 -73
  92. package/dist/mdx-plugins/rehype-code.d.ts +2 -55
  93. package/dist/mdx-plugins/rehype-code.js +5 -15
  94. package/dist/mdx-plugins/rehype-toc.d.ts +2 -14
  95. package/dist/mdx-plugins/rehype-toc.js +3 -7
  96. package/dist/mdx-plugins/remark-admonition.d.ts +2 -20
  97. package/dist/mdx-plugins/remark-admonition.js +74 -8
  98. package/dist/mdx-plugins/remark-admonition.js.map +1 -0
  99. package/dist/mdx-plugins/remark-code-tab.d.ts +2 -30
  100. package/dist/mdx-plugins/remark-code-tab.js +183 -7
  101. package/dist/mdx-plugins/remark-code-tab.js.map +1 -0
  102. package/dist/mdx-plugins/remark-directive-admonition.d.ts +2 -27
  103. package/dist/mdx-plugins/remark-directive-admonition.js +60 -7
  104. package/dist/mdx-plugins/remark-directive-admonition.js.map +1 -0
  105. package/dist/mdx-plugins/remark-gfm.d.ts +2 -1
  106. package/dist/mdx-plugins/remark-gfm.js +3 -7
  107. package/dist/mdx-plugins/remark-heading.d.ts +2 -31
  108. package/dist/mdx-plugins/remark-heading.js +45 -8
  109. package/dist/mdx-plugins/remark-heading.js.map +1 -0
  110. package/dist/mdx-plugins/remark-image.d.ts +2 -57
  111. package/dist/mdx-plugins/remark-image.js +192 -7
  112. package/dist/mdx-plugins/remark-image.js.map +1 -0
  113. package/dist/mdx-plugins/remark-mdx-files.d.ts +2 -40
  114. package/dist/mdx-plugins/remark-mdx-files.js +187 -7
  115. package/dist/mdx-plugins/remark-mdx-files.js.map +1 -0
  116. package/dist/mdx-plugins/remark-mdx-mermaid.d.ts +2 -15
  117. package/dist/mdx-plugins/remark-mdx-mermaid.js +31 -7
  118. package/dist/mdx-plugins/remark-mdx-mermaid.js.map +1 -0
  119. package/dist/mdx-plugins/remark-npm.d.ts +2 -31
  120. package/dist/mdx-plugins/remark-npm.js +68 -8
  121. package/dist/mdx-plugins/remark-npm.js.map +1 -0
  122. package/dist/mdx-plugins/remark-steps.d.ts +2 -23
  123. package/dist/mdx-plugins/remark-steps.js +77 -7
  124. package/dist/mdx-plugins/remark-steps.js.map +1 -0
  125. package/dist/mdx-plugins/remark-structure.d.ts +2 -71
  126. package/dist/mdx-plugins/remark-structure.js +105 -11
  127. package/dist/mdx-plugins/remark-structure.js.map +1 -0
  128. package/dist/mixedbread-DlByNYSd.js +88 -0
  129. package/dist/mixedbread-DlByNYSd.js.map +1 -0
  130. package/dist/negotiation/index.d.ts +6 -4
  131. package/dist/negotiation/index.d.ts.map +1 -0
  132. package/dist/negotiation/index.js +41 -11
  133. package/dist/negotiation/index.js.map +1 -0
  134. package/dist/normalize-url-DP9-1I-S.js +16 -0
  135. package/dist/normalize-url-DP9-1I-S.js.map +1 -0
  136. package/dist/orama-cloud-DH3g37zc.js +84 -0
  137. package/dist/orama-cloud-DH3g37zc.js.map +1 -0
  138. package/dist/page-tree/index.d.ts +23 -11
  139. package/dist/page-tree/index.d.ts.map +1 -0
  140. package/dist/page-tree/index.js +3 -17
  141. package/dist/path-DHIjrDBP.js +60 -0
  142. package/dist/path-DHIjrDBP.js.map +1 -0
  143. package/dist/rehype-code-CdiZ1Y6P.js +241 -0
  144. package/dist/rehype-code-CdiZ1Y6P.js.map +1 -0
  145. package/dist/rehype-code-vVWG4-ej.d.ts +58 -0
  146. package/dist/rehype-code-vVWG4-ej.d.ts.map +1 -0
  147. package/dist/rehype-toc-DJvSyE0o.d.ts +18 -0
  148. package/dist/rehype-toc-DJvSyE0o.d.ts.map +1 -0
  149. package/dist/rehype-toc-DVwJcwvA.js +143 -0
  150. package/dist/rehype-toc-DVwJcwvA.js.map +1 -0
  151. package/dist/remark-admonition-DOwBWzsH.d.ts +22 -0
  152. package/dist/remark-admonition-DOwBWzsH.d.ts.map +1 -0
  153. package/dist/remark-code-tab-CXsYlims.d.ts +32 -0
  154. package/dist/remark-code-tab-CXsYlims.d.ts.map +1 -0
  155. package/dist/remark-directive-admonition-BCm_yiU9.d.ts +36 -0
  156. package/dist/remark-directive-admonition-BCm_yiU9.d.ts.map +1 -0
  157. package/dist/remark-gfm-CeWpMwyk.d.ts +2 -0
  158. package/dist/remark-heading-CXvCY0go.d.ts +37 -0
  159. package/dist/remark-heading-CXvCY0go.d.ts.map +1 -0
  160. package/dist/remark-image-CvUis4R1.d.ts +65 -0
  161. package/dist/remark-image-CvUis4R1.d.ts.map +1 -0
  162. package/dist/remark-mdx-files-B31xFFG4.d.ts +56 -0
  163. package/dist/remark-mdx-files-B31xFFG4.d.ts.map +1 -0
  164. package/dist/remark-mdx-mermaid-BdSUUiCG.d.ts +17 -0
  165. package/dist/remark-mdx-mermaid-BdSUUiCG.d.ts.map +1 -0
  166. package/dist/remark-npm-BIvIEKT2.d.ts +36 -0
  167. package/dist/remark-npm-BIvIEKT2.d.ts.map +1 -0
  168. package/dist/remark-steps-CHJN-rtm.d.ts +28 -0
  169. package/dist/remark-steps-CHJN-rtm.d.ts.map +1 -0
  170. package/dist/remark-structure-RZD2gGKp.d.ts +77 -0
  171. package/dist/remark-structure-RZD2gGKp.d.ts.map +1 -0
  172. package/dist/remove-undefined-Cfs4o_mM.js +19 -0
  173. package/dist/remove-undefined-Cfs4o_mM.js.map +1 -0
  174. package/dist/search/algolia.d.ts +3 -69
  175. package/dist/search/algolia.js +69 -63
  176. package/dist/search/algolia.js.map +1 -0
  177. package/dist/search/client.d.ts +120 -114
  178. package/dist/search/client.d.ts.map +1 -0
  179. package/dist/search/client.js +92 -91
  180. package/dist/search/client.js.map +1 -0
  181. package/dist/search/index.d.ts +20 -18
  182. package/dist/search/index.d.ts.map +1 -0
  183. package/dist/search/index.js +3 -7
  184. package/dist/search/orama-cloud.d.ts +70 -68
  185. package/dist/search/orama-cloud.d.ts.map +1 -0
  186. package/dist/search/orama-cloud.js +46 -54
  187. package/dist/search/orama-cloud.js.map +1 -0
  188. package/dist/search/server.d.ts +6 -136
  189. package/dist/search/server.js +292 -369
  190. package/dist/search/server.js.map +1 -0
  191. package/dist/search-D6ChCLhY.js +44 -0
  192. package/dist/search-D6ChCLhY.js.map +1 -0
  193. package/dist/server-CPR_fgkH.d.ts +133 -0
  194. package/dist/server-CPR_fgkH.d.ts.map +1 -0
  195. package/dist/shiki-4oMYwHED.js +80 -0
  196. package/dist/shiki-4oMYwHED.js.map +1 -0
  197. package/dist/shiki-CIBQys54.d.ts +33 -0
  198. package/dist/shiki-CIBQys54.d.ts.map +1 -0
  199. package/dist/source/client/index.d.ts +7 -5
  200. package/dist/source/client/index.d.ts.map +1 -0
  201. package/dist/source/client/index.js +24 -35
  202. package/dist/source/client/index.js.map +1 -0
  203. package/dist/source/index.d.ts +3 -42
  204. package/dist/source/index.js +599 -752
  205. package/dist/source/index.js.map +1 -0
  206. package/dist/source/plugins/lucide-icons.d.ts +7 -7
  207. package/dist/source/plugins/lucide-icons.d.ts.map +1 -0
  208. package/dist/source/plugins/lucide-icons.js +21 -20
  209. package/dist/source/plugins/lucide-icons.js.map +1 -0
  210. package/dist/source/plugins/slugs.d.ts +3 -0
  211. package/dist/source/plugins/slugs.js +65 -0
  212. package/dist/source/plugins/slugs.js.map +1 -0
  213. package/dist/source/schema.d.ts +17 -14
  214. package/dist/source/schema.d.ts.map +1 -0
  215. package/dist/source/schema.js +26 -22
  216. package/dist/source/schema.js.map +1 -0
  217. package/dist/static-Dq8pA8Ay.js +51 -0
  218. package/dist/static-Dq8pA8Ay.js.map +1 -0
  219. package/dist/toc.d.ts +38 -25
  220. package/dist/toc.d.ts.map +1 -0
  221. package/dist/toc.js +123 -136
  222. package/dist/toc.js.map +1 -0
  223. package/dist/util-CK2ykiif.d.ts +8 -0
  224. package/dist/util-CK2ykiif.d.ts.map +1 -0
  225. package/dist/util-s9piKHsk.js +10 -0
  226. package/dist/util-s9piKHsk.js.map +1 -0
  227. package/dist/utils/use-effect-event.d.ts +3 -1
  228. package/dist/utils/use-effect-event.d.ts.map +1 -0
  229. package/dist/utils/use-effect-event.js +16 -13
  230. package/dist/utils/use-effect-event.js.map +1 -0
  231. package/dist/utils/use-media-query.d.ts +3 -1
  232. package/dist/utils/use-media-query.d.ts.map +1 -0
  233. package/dist/utils/use-media-query.js +20 -20
  234. package/dist/utils/use-media-query.js.map +1 -0
  235. package/dist/utils/use-on-change.d.ts +3 -1
  236. package/dist/utils/use-on-change.d.ts.map +1 -0
  237. package/dist/utils/use-on-change.js +23 -7
  238. package/dist/utils/use-on-change.js.map +1 -0
  239. package/dist/utils-DUvi2WkD.js +134 -0
  240. package/dist/utils-DUvi2WkD.js.map +1 -0
  241. package/package.json +60 -58
  242. package/dist/algolia-IZEDLPHE.js +0 -58
  243. package/dist/chunk-5PMI7QDD.js +0 -220
  244. package/dist/chunk-ADBHPKXG.js +0 -78
  245. package/dist/chunk-APKPSBSB.js +0 -74
  246. package/dist/chunk-CH7YHH7V.js +0 -222
  247. package/dist/chunk-EFVXL2PP.js +0 -144
  248. package/dist/chunk-EMWGTXSW.js +0 -19
  249. package/dist/chunk-FAEPKD7U.js +0 -20
  250. package/dist/chunk-FUUVPEA5.js +0 -29
  251. package/dist/chunk-GINBKBVQ.js +0 -12
  252. package/dist/chunk-GLRQBLGN.js +0 -59
  253. package/dist/chunk-JUF4WZ6G.js +0 -117
  254. package/dist/chunk-K4WNLOVQ.js +0 -75
  255. package/dist/chunk-L4JKQWCM.js +0 -131
  256. package/dist/chunk-MA6O2UUE.js +0 -50
  257. package/dist/chunk-ONG4RVCR.js +0 -8
  258. package/dist/chunk-OTD7MV33.js +0 -53
  259. package/dist/chunk-PFNP6PEB.js +0 -11
  260. package/dist/chunk-SH7BNTG7.js +0 -38
  261. package/dist/chunk-TWIDBWFG.js +0 -84
  262. package/dist/chunk-U67V476Y.js +0 -35
  263. package/dist/chunk-VLSDGCJE.js +0 -47
  264. package/dist/chunk-W6WTLKRA.js +0 -73
  265. package/dist/chunk-X2HFD5QJ.js +0 -275
  266. package/dist/chunk-XJ6ZQNEX.js +0 -91
  267. package/dist/chunk-XN2LKXFZ.js +0 -101
  268. package/dist/chunk-XOFXGHS4.js +0 -93
  269. package/dist/chunk-XZSI7AHE.js +0 -67
  270. package/dist/chunk-YVVDKJ2H.js +0 -34
  271. package/dist/chunk-ZMWYLUDP.js +0 -21
  272. package/dist/definitions-pJ7PybYY.d.ts +0 -60
  273. package/dist/fetch-IBTWQCJR.js +0 -22
  274. package/dist/loader-_E2HOdV0.d.ts +0 -333
  275. package/dist/mixedbread-A3WLENES.js +0 -117
  276. package/dist/orama-cloud-UZAPMPFV.js +0 -93
  277. package/dist/static-A2YJ5TXV.js +0 -62
  278. package/dist/util-bZU2QeJ2.d.ts +0 -6
package/dist/toc.js CHANGED
@@ -1,151 +1,138 @@
1
- "use client";
2
- import "./chunk-U67V476Y.js";
1
+ 'use client';
3
2
 
4
- // src/toc.tsx
5
- import {
6
- createContext,
7
- useContext,
8
- useEffect,
9
- useEffectEvent,
10
- useLayoutEffect,
11
- useMemo,
12
- useRef,
13
- useState
14
- } from "react";
3
+ import { createContext, useContext, useEffect, useEffectEvent, useLayoutEffect, useMemo, useRef, useState } from "react";
4
+ import { jsx } from "react/jsx-runtime";
15
5
  import scrollIntoView from "scroll-into-view-if-needed";
16
6
 
17
- // src/utils/merge-refs.ts
7
+ //#region src/utils/merge-refs.ts
18
8
  function mergeRefs(...refs) {
19
- return (value) => {
20
- refs.forEach((ref) => {
21
- if (typeof ref === "function") {
22
- ref(value);
23
- } else if (ref != null) {
24
- ref.current = value;
25
- }
26
- });
27
- };
9
+ return (value) => {
10
+ refs.forEach((ref) => {
11
+ if (typeof ref === "function") ref(value);
12
+ else if (ref != null) ref.current = value;
13
+ });
14
+ };
28
15
  }
29
16
 
30
- // src/toc.tsx
31
- import { jsx } from "react/jsx-runtime";
32
- var ActiveAnchorContext = createContext([]);
33
- var ScrollContext = createContext({
34
- current: null
35
- });
17
+ //#endregion
18
+ //#region src/toc.tsx
19
+ const ActiveAnchorContext = createContext([]);
20
+ const ScrollContext = createContext({ current: null });
21
+ /**
22
+ * The estimated active heading ID
23
+ */
36
24
  function useActiveAnchor() {
37
- return useContext(ActiveAnchorContext)[0];
25
+ return useContext(ActiveAnchorContext)[0];
38
26
  }
27
+ /**
28
+ * The id of visible anchors
29
+ */
39
30
  function useActiveAnchors() {
40
- return useContext(ActiveAnchorContext);
31
+ return useContext(ActiveAnchorContext);
41
32
  }
42
- function ScrollProvider({
43
- containerRef,
44
- children
45
- }) {
46
- return /* @__PURE__ */ jsx(ScrollContext.Provider, { value: containerRef, children });
33
+ function ScrollProvider({ containerRef, children }) {
34
+ return /* @__PURE__ */ jsx(ScrollContext.Provider, {
35
+ value: containerRef,
36
+ children
37
+ });
47
38
  }
48
- function AnchorProvider({
49
- toc,
50
- single = false,
51
- children
52
- }) {
53
- const headings = useMemo(() => {
54
- return toc.map((item) => item.url.split("#")[1]);
55
- }, [toc]);
56
- return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, { value: useAnchorObserver(headings, single), children });
39
+ function AnchorProvider({ toc, single = false, children }) {
40
+ const headings = useMemo(() => {
41
+ return toc.map((item) => item.url.split("#")[1]);
42
+ }, [toc]);
43
+ return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, {
44
+ value: useAnchorObserver(headings, single),
45
+ children
46
+ });
57
47
  }
58
- function TOCItem({
59
- ref,
60
- onActiveChange = () => null,
61
- ...props
62
- }) {
63
- const containerRef = useContext(ScrollContext);
64
- const anchorRef = useRef(null);
65
- const activeOrder = useActiveAnchors().indexOf(props.href.slice(1));
66
- const isActive = activeOrder !== -1;
67
- const shouldScroll = activeOrder === 0;
68
- const onActiveChangeEvent = useEffectEvent(onActiveChange);
69
- useLayoutEffect(() => {
70
- const anchor = anchorRef.current;
71
- const container = containerRef.current;
72
- if (container && anchor && shouldScroll)
73
- scrollIntoView(anchor, {
74
- behavior: "smooth",
75
- block: "center",
76
- inline: "center",
77
- scrollMode: "always",
78
- boundary: container
79
- });
80
- }, [containerRef, shouldScroll]);
81
- useEffect(() => {
82
- return () => onActiveChangeEvent(isActive);
83
- }, [isActive]);
84
- return /* @__PURE__ */ jsx("a", { ref: mergeRefs(anchorRef, ref), "data-active": isActive, ...props, children: props.children });
48
+ function TOCItem({ ref, onActiveChange = () => null, ...props }) {
49
+ const containerRef = useContext(ScrollContext);
50
+ const anchorRef = useRef(null);
51
+ const activeOrder = useActiveAnchors().indexOf(props.href.slice(1));
52
+ const isActive = activeOrder !== -1;
53
+ const shouldScroll = activeOrder === 0;
54
+ const onActiveChangeEvent = useEffectEvent(onActiveChange);
55
+ useLayoutEffect(() => {
56
+ const anchor = anchorRef.current;
57
+ const container = containerRef.current;
58
+ if (container && anchor && shouldScroll) scrollIntoView(anchor, {
59
+ behavior: "smooth",
60
+ block: "center",
61
+ inline: "center",
62
+ scrollMode: "always",
63
+ boundary: container
64
+ });
65
+ }, [containerRef, shouldScroll]);
66
+ useEffect(() => {
67
+ return () => onActiveChangeEvent(isActive);
68
+ }, [isActive]);
69
+ return /* @__PURE__ */ jsx("a", {
70
+ ref: mergeRefs(anchorRef, ref),
71
+ "data-active": isActive,
72
+ ...props,
73
+ children: props.children
74
+ });
85
75
  }
76
+ /**
77
+ * Find the active heading of page
78
+ *
79
+ * It selects the top heading by default, and the last item when reached the bottom of page.
80
+ *
81
+ * @param watch - An array of element ids to watch
82
+ * @param single - only one active item at most
83
+ * @returns Active anchor
84
+ */
86
85
  function useAnchorObserver(watch, single) {
87
- const observerRef = useRef(null);
88
- const [activeAnchor, setActiveAnchor] = useState(() => []);
89
- const stateRef = useRef(null);
90
- const onChange = useEffectEvent((entries) => {
91
- stateRef.current ??= {
92
- visible: /* @__PURE__ */ new Set()
93
- };
94
- const state = stateRef.current;
95
- for (const entry of entries) {
96
- if (entry.isIntersecting) {
97
- state.visible.add(entry.target.id);
98
- } else {
99
- state.visible.delete(entry.target.id);
100
- }
101
- }
102
- if (state.visible.size === 0) {
103
- const viewTop = entries.length > 0 ? entries[0]?.rootBounds?.top ?? 0 : 0;
104
- let fallback;
105
- let min = -1;
106
- for (const id of watch) {
107
- const element = document.getElementById(id);
108
- if (!element) continue;
109
- const d = Math.abs(viewTop - element.getBoundingClientRect().top);
110
- if (min === -1 || d < min) {
111
- fallback = element;
112
- min = d;
113
- }
114
- }
115
- setActiveAnchor(fallback ? [fallback.id] : []);
116
- } else {
117
- const items = watch.filter((item) => state.visible.has(item));
118
- setActiveAnchor(single ? items.slice(0, 1) : items);
119
- }
120
- });
121
- useEffect(() => {
122
- if (observerRef.current) return;
123
- observerRef.current = new IntersectionObserver(onChange, {
124
- rootMargin: "0px",
125
- threshold: 0.98
126
- });
127
- return () => {
128
- observerRef.current?.disconnect();
129
- observerRef.current = null;
130
- };
131
- }, []);
132
- useEffect(() => {
133
- const observer = observerRef.current;
134
- if (!observer) return;
135
- const elements = watch.flatMap(
136
- (heading) => document.getElementById(heading) ?? []
137
- );
138
- for (const element of elements) observer.observe(element);
139
- return () => {
140
- for (const element of elements) observer.unobserve(element);
141
- };
142
- }, [watch]);
143
- return activeAnchor;
86
+ const observerRef = useRef(null);
87
+ const [activeAnchor, setActiveAnchor] = useState(() => []);
88
+ const stateRef = useRef(null);
89
+ const onChange = useEffectEvent((entries) => {
90
+ stateRef.current ??= { visible: /* @__PURE__ */ new Set() };
91
+ const state = stateRef.current;
92
+ for (const entry of entries) if (entry.isIntersecting) state.visible.add(entry.target.id);
93
+ else state.visible.delete(entry.target.id);
94
+ if (state.visible.size === 0) {
95
+ const viewTop = entries.length > 0 ? entries[0]?.rootBounds?.top ?? 0 : 0;
96
+ let fallback;
97
+ let min = -1;
98
+ for (const id of watch) {
99
+ const element = document.getElementById(id);
100
+ if (!element) continue;
101
+ const d = Math.abs(viewTop - element.getBoundingClientRect().top);
102
+ if (min === -1 || d < min) {
103
+ fallback = element;
104
+ min = d;
105
+ }
106
+ }
107
+ setActiveAnchor(fallback ? [fallback.id] : []);
108
+ } else {
109
+ const items = watch.filter((item) => state.visible.has(item));
110
+ setActiveAnchor(single ? items.slice(0, 1) : items);
111
+ }
112
+ });
113
+ useEffect(() => {
114
+ if (observerRef.current) return;
115
+ observerRef.current = new IntersectionObserver(onChange, {
116
+ rootMargin: "0px",
117
+ threshold: .98
118
+ });
119
+ return () => {
120
+ observerRef.current?.disconnect();
121
+ observerRef.current = null;
122
+ };
123
+ }, []);
124
+ useEffect(() => {
125
+ const observer = observerRef.current;
126
+ if (!observer) return;
127
+ const elements = watch.flatMap((heading) => document.getElementById(heading) ?? []);
128
+ for (const element of elements) observer.observe(element);
129
+ return () => {
130
+ for (const element of elements) observer.unobserve(element);
131
+ };
132
+ }, [watch]);
133
+ return activeAnchor;
144
134
  }
145
- export {
146
- AnchorProvider,
147
- ScrollProvider,
148
- TOCItem,
149
- useActiveAnchor,
150
- useActiveAnchors
151
- };
135
+
136
+ //#endregion
137
+ export { AnchorProvider, ScrollProvider, TOCItem, useActiveAnchor, useActiveAnchors };
138
+ //# sourceMappingURL=toc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toc.js","names":["fallback: Element | undefined"],"sources":["../src/utils/merge-refs.ts","../src/toc.tsx"],"sourcesContent":["import type * as React from 'react';\n\nexport function mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {\n return (value) => {\n refs.forEach((ref) => {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref != null) {\n ref.current = value;\n }\n });\n };\n}\n","'use client';\nimport {\n type ComponentProps,\n createContext,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useEffectEvent,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport scrollIntoView from 'scroll-into-view-if-needed';\nimport { mergeRefs } from '@/utils/merge-refs';\n\nexport interface TOCItemType {\n title: ReactNode;\n url: string;\n depth: number;\n}\n\nexport type TableOfContents = TOCItemType[];\n\nconst ActiveAnchorContext = createContext<string[]>([]);\n\nconst ScrollContext = createContext<RefObject<HTMLElement | null>>({\n current: null,\n});\n\n/**\n * The estimated active heading ID\n */\nexport function useActiveAnchor(): string | undefined {\n return useContext(ActiveAnchorContext)[0];\n}\n\n/**\n * The id of visible anchors\n */\nexport function useActiveAnchors(): string[] {\n return useContext(ActiveAnchorContext);\n}\n\nexport interface AnchorProviderProps {\n toc: TableOfContents;\n /**\n * Only accept one active item at most\n *\n * @defaultValue false\n */\n single?: boolean;\n children?: ReactNode;\n}\n\nexport interface ScrollProviderProps {\n /**\n * Scroll into the view of container when active\n */\n containerRef: RefObject<HTMLElement | null>;\n\n children?: ReactNode;\n}\n\nexport function ScrollProvider({ containerRef, children }: ScrollProviderProps) {\n return <ScrollContext.Provider value={containerRef}>{children}</ScrollContext.Provider>;\n}\n\nexport function AnchorProvider({ toc, single = false, children }: AnchorProviderProps) {\n const headings = useMemo(() => {\n return toc.map((item) => item.url.split('#')[1]);\n }, [toc]);\n\n return (\n <ActiveAnchorContext.Provider value={useAnchorObserver(headings, single)}>\n {children}\n </ActiveAnchorContext.Provider>\n );\n}\n\nexport interface TOCItemProps extends Omit<ComponentProps<'a'>, 'href'> {\n href: string;\n onActiveChange?: (v: boolean) => void;\n}\n\nexport function TOCItem({ ref, onActiveChange = () => null, ...props }: TOCItemProps) {\n const containerRef = useContext(ScrollContext);\n const anchorRef = useRef<HTMLAnchorElement>(null);\n const activeOrder = useActiveAnchors().indexOf(props.href.slice(1));\n const isActive = activeOrder !== -1;\n const shouldScroll = activeOrder === 0;\n const onActiveChangeEvent = useEffectEvent(onActiveChange);\n\n useLayoutEffect(() => {\n const anchor = anchorRef.current;\n const container = containerRef.current;\n\n if (container && anchor && shouldScroll)\n scrollIntoView(anchor, {\n behavior: 'smooth',\n block: 'center',\n inline: 'center',\n scrollMode: 'always',\n boundary: container,\n });\n }, [containerRef, shouldScroll]);\n\n useEffect(() => {\n return () => onActiveChangeEvent(isActive);\n }, [isActive]);\n\n return (\n <a ref={mergeRefs(anchorRef, ref)} data-active={isActive} {...props}>\n {props.children}\n </a>\n );\n}\n\n/**\n * Find the active heading of page\n *\n * It selects the top heading by default, and the last item when reached the bottom of page.\n *\n * @param watch - An array of element ids to watch\n * @param single - only one active item at most\n * @returns Active anchor\n */\nfunction useAnchorObserver(watch: string[], single: boolean): string[] {\n const observerRef = useRef<IntersectionObserver>(null);\n const [activeAnchor, setActiveAnchor] = useState<string[]>(() => []);\n const stateRef = useRef<{\n visible: Set<string>;\n }>(null);\n\n const onChange = useEffectEvent((entries: IntersectionObserverEntry[]) => {\n stateRef.current ??= {\n visible: new Set(),\n };\n const state = stateRef.current;\n\n for (const entry of entries) {\n if (entry.isIntersecting) {\n state.visible.add(entry.target.id);\n } else {\n state.visible.delete(entry.target.id);\n }\n }\n\n if (state.visible.size === 0) {\n const viewTop = entries.length > 0 ? (entries[0]?.rootBounds?.top ?? 0) : 0;\n let fallback: Element | undefined;\n let min = -1;\n\n for (const id of watch) {\n const element = document.getElementById(id);\n if (!element) continue;\n\n const d = Math.abs(viewTop - element.getBoundingClientRect().top);\n if (min === -1 || d < min) {\n fallback = element;\n min = d;\n }\n }\n\n setActiveAnchor(fallback ? [fallback.id] : []);\n } else {\n const items = watch.filter((item) => state.visible.has(item));\n setActiveAnchor(single ? items.slice(0, 1) : items);\n }\n });\n\n useEffect(() => {\n if (observerRef.current) return;\n observerRef.current = new IntersectionObserver(onChange, {\n rootMargin: '0px',\n threshold: 0.98,\n });\n\n return () => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n const observer = observerRef.current;\n if (!observer) return;\n const elements = watch.flatMap((heading) => document.getElementById(heading) ?? []);\n\n for (const element of elements) observer.observe(element);\n return () => {\n for (const element of elements) observer.unobserve(element);\n };\n }, [watch]);\n\n return activeAnchor;\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Pluggable } from "unified";
2
+
3
+ //#region src/content/mdx/util.d.ts
4
+ type Thenable<T> = T | PromiseLike<T>;
5
+ type ResolvePlugins = Thenable<Pluggable>[] | ((v: Pluggable[]) => Thenable<Pluggable>[]);
6
+ //#endregion
7
+ export { ResolvePlugins as t };
8
+ //# sourceMappingURL=util-CK2ykiif.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util-CK2ykiif.d.ts","names":[],"sources":["../src/content/mdx/util.ts"],"sourcesContent":[],"mappings":";;;KAEK,cAAc,IAAI,YAAY;KAEvB,cAAA,GAAiB,SAAS,oBAAoB,gBAAgB,SAAS"}
@@ -0,0 +1,10 @@
1
+ //#region src/content/mdx/util.ts
2
+ async function resolvePlugins(def, options = []) {
3
+ const list = (await Promise.all(def(Array.isArray(options) ? options : []))).filter((v) => v !== false);
4
+ if (typeof options === "function") return Promise.all(options(list));
5
+ return list;
6
+ }
7
+
8
+ //#endregion
9
+ export { resolvePlugins as t };
10
+ //# sourceMappingURL=util-s9piKHsk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util-s9piKHsk.js","names":[],"sources":["../src/content/mdx/util.ts"],"sourcesContent":["import type { Pluggable } from 'unified';\n\ntype Thenable<T> = T | PromiseLike<T>;\n\nexport type ResolvePlugins = Thenable<Pluggable>[] | ((v: Pluggable[]) => Thenable<Pluggable>[]);\n\nexport async function resolvePlugins(\n def: (v: Thenable<Pluggable>[]) => Thenable<Pluggable | false>[],\n options: ResolvePlugins = [],\n): Promise<Pluggable[]> {\n const list = (await Promise.all(def(Array.isArray(options) ? options : []))).filter(\n (v) => v !== false,\n );\n\n if (typeof options === 'function') {\n return Promise.all(options(list));\n }\n\n return list;\n}\n"],"mappings":";AAMA,eAAsB,eACpB,KACA,UAA0B,EAAE,EACN;CACtB,MAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,MAAM,QAAQ,QAAQ,GAAG,UAAU,EAAE,CAAC,CAAC,EAAE,QAC1E,MAAM,MAAM,MACd;AAED,KAAI,OAAO,YAAY,WACrB,QAAO,QAAQ,IAAI,QAAQ,KAAK,CAAC;AAGnC,QAAO"}
@@ -1,3 +1,4 @@
1
+ //#region src/utils/use-effect-event.d.ts
1
2
  type UseEffectEvent = <F extends (...params: never[]) => unknown>(callback: F) => F;
2
3
  /**
3
4
  * Polyfill for React.js 19.2 `useEffectEvent`.
@@ -5,5 +6,6 @@ type UseEffectEvent = <F extends (...params: never[]) => unknown>(callback: F) =
5
6
  * @internal Don't use this, could be deleted anytime.
6
7
  */
7
8
  declare const useEffectEvent: UseEffectEvent;
8
-
9
+ //#endregion
9
10
  export { useEffectEvent };
11
+ //# sourceMappingURL=use-effect-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-effect-event.d.ts","names":[],"sources":["../../src/utils/use-effect-event.ts"],"sourcesContent":[],"mappings":";KAGK,cAAA,yDAAuE,MAAM;;AAOlF;;;;cAAa,gBAAgB"}
@@ -1,16 +1,19 @@
1
- "use client";
2
- import "../chunk-U67V476Y.js";
1
+ 'use client';
3
2
 
4
- // src/utils/use-effect-event.ts
5
3
  import * as React from "react";
6
- var useEffectEvent = "useEffectEvent" in React ? { ...React }.useEffectEvent : (callback) => {
7
- const ref = React.useRef(callback);
8
- ref.current = callback;
9
- return React.useCallback(
10
- ((...params) => ref.current(...params)),
11
- []
12
- );
13
- };
14
- export {
15
- useEffectEvent
4
+
5
+ //#region src/utils/use-effect-event.ts
6
+ /**
7
+ * Polyfill for React.js 19.2 `useEffectEvent`.
8
+ *
9
+ * @internal Don't use this, could be deleted anytime.
10
+ */
11
+ const useEffectEvent = "useEffectEvent" in React ? { ...React }.useEffectEvent : (callback) => {
12
+ const ref = React.useRef(callback);
13
+ ref.current = callback;
14
+ return React.useCallback(((...params) => ref.current(...params)), []);
16
15
  };
16
+
17
+ //#endregion
18
+ export { useEffectEvent };
19
+ //# sourceMappingURL=use-effect-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-effect-event.js","names":["useEffectEvent: UseEffectEvent"],"sources":["../../src/utils/use-effect-event.ts"],"sourcesContent":["'use client';\nimport * as React from 'react';\n\ntype UseEffectEvent = <F extends (...params: never[]) => unknown>(callback: F) => F;\n\n/**\n * Polyfill for React.js 19.2 `useEffectEvent`.\n *\n * @internal Don't use this, could be deleted anytime.\n */\nexport const useEffectEvent: UseEffectEvent =\n 'useEffectEvent' in React\n ? { ...React }.useEffectEvent\n : <F extends (...params: never[]) => unknown>(callback: F) => {\n const ref = React.useRef(callback);\n ref.current = callback;\n\n return React.useCallback(((...params) => ref.current(...params)) as F, []);\n };\n"],"mappings":";;;;;;;;;;AAUA,MAAaA,iBACX,oBAAoB,QAChB,EAAE,GAAG,OAAO,CAAC,kBAC+B,aAAgB;CAC1D,MAAM,MAAM,MAAM,OAAO,SAAS;AAClC,KAAI,UAAU;AAEd,QAAO,MAAM,cAAc,GAAG,WAAW,IAAI,QAAQ,GAAG,OAAO,GAAQ,EAAE,CAAC"}
@@ -1,3 +1,5 @@
1
+ //#region src/utils/use-media-query.d.ts
1
2
  declare function useMediaQuery(query: string, disabled?: boolean): boolean | null;
2
-
3
+ //#endregion
3
4
  export { useMediaQuery };
5
+ //# sourceMappingURL=use-media-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.d.ts","names":[],"sources":["../../src/utils/use-media-query.ts"],"sourcesContent":[],"mappings":";iBAEgB,aAAA"}
@@ -1,23 +1,23 @@
1
- import "../chunk-U67V476Y.js";
2
-
3
- // src/utils/use-media-query.ts
4
1
  import { useEffect, useState } from "react";
2
+
3
+ //#region src/utils/use-media-query.ts
5
4
  function useMediaQuery(query, disabled = false) {
6
- const [isMatch, setMatch] = useState(null);
7
- useEffect(() => {
8
- if (disabled) return;
9
- const mediaQueryList = window.matchMedia(query);
10
- const handleChange = () => {
11
- setMatch(mediaQueryList.matches);
12
- };
13
- handleChange();
14
- mediaQueryList.addEventListener("change", handleChange);
15
- return () => {
16
- mediaQueryList.removeEventListener("change", handleChange);
17
- };
18
- }, [disabled, query]);
19
- return isMatch;
5
+ const [isMatch, setMatch] = useState(null);
6
+ useEffect(() => {
7
+ if (disabled) return;
8
+ const mediaQueryList = window.matchMedia(query);
9
+ const handleChange = () => {
10
+ setMatch(mediaQueryList.matches);
11
+ };
12
+ handleChange();
13
+ mediaQueryList.addEventListener("change", handleChange);
14
+ return () => {
15
+ mediaQueryList.removeEventListener("change", handleChange);
16
+ };
17
+ }, [disabled, query]);
18
+ return isMatch;
20
19
  }
21
- export {
22
- useMediaQuery
23
- };
20
+
21
+ //#endregion
22
+ export { useMediaQuery };
23
+ //# sourceMappingURL=use-media-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.js","names":[],"sources":["../../src/utils/use-media-query.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport function useMediaQuery(query: string, disabled = false): boolean | null {\n const [isMatch, setMatch] = useState<boolean | null>(null);\n\n useEffect(() => {\n if (disabled) return;\n const mediaQueryList = window.matchMedia(query);\n\n const handleChange = () => {\n setMatch(mediaQueryList.matches);\n };\n handleChange();\n mediaQueryList.addEventListener('change', handleChange);\n return () => {\n mediaQueryList.removeEventListener('change', handleChange);\n };\n }, [disabled, query]);\n\n return isMatch;\n}\n"],"mappings":";;;AAEA,SAAgB,cAAc,OAAe,WAAW,OAAuB;CAC7E,MAAM,CAAC,SAAS,YAAY,SAAyB,KAAK;AAE1D,iBAAgB;AACd,MAAI,SAAU;EACd,MAAM,iBAAiB,OAAO,WAAW,MAAM;EAE/C,MAAM,qBAAqB;AACzB,YAAS,eAAe,QAAQ;;AAElC,gBAAc;AACd,iBAAe,iBAAiB,UAAU,aAAa;AACvD,eAAa;AACX,kBAAe,oBAAoB,UAAU,aAAa;;IAE3D,CAAC,UAAU,MAAM,CAAC;AAErB,QAAO"}
@@ -1,8 +1,10 @@
1
+ //#region src/utils/use-on-change.d.ts
1
2
  /**
2
3
  * @param value - state to watch
3
4
  * @param onChange - when the state changed
4
5
  * @param isUpdated - a function that determines if the state is updated
5
6
  */
6
7
  declare function useOnChange<T>(value: T, onChange: (current: T, previous: T) => void, isUpdated?: (prev: T, current: T) => boolean): void;
7
-
8
+ //#endregion
8
9
  export { useOnChange };
10
+ //# sourceMappingURL=use-on-change.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-on-change.d.ts","names":[],"sources":["../../src/utils/use-on-change.ts"],"sourcesContent":[],"mappings":";;AAeA;;;;AAGoB,iBAHJ,WAGI,CAAA,CAAA,CAAA,CAAA,KAAA,EAFX,CAEW,EAAA,QAAA,EAAA,CAAA,OAAA,EADE,CACF,EAAA,QAAA,EADe,CACf,EAAA,GAAA,IAAA,EAAA,SAAA,CAAA,EAAA,CAAA,IAAA,EAAA,CAAA,EAAA,OAAA,EAAY,CAAZ,EAAA,GAAA,OAAA,CAAA,EAAA,IAAA"}
@@ -1,7 +1,23 @@
1
- import {
2
- useOnChange
3
- } from "../chunk-EMWGTXSW.js";
4
- import "../chunk-U67V476Y.js";
5
- export {
6
- useOnChange
7
- };
1
+ import { useState } from "react";
2
+
3
+ //#region src/utils/use-on-change.ts
4
+ function isDifferent(a, b) {
5
+ if (Array.isArray(a) && Array.isArray(b)) return b.length !== a.length || a.some((v, i) => isDifferent(v, b[i]));
6
+ return a !== b;
7
+ }
8
+ /**
9
+ * @param value - state to watch
10
+ * @param onChange - when the state changed
11
+ * @param isUpdated - a function that determines if the state is updated
12
+ */
13
+ function useOnChange(value, onChange, isUpdated = isDifferent) {
14
+ const [prev, setPrev] = useState(value);
15
+ if (isUpdated(prev, value)) {
16
+ onChange(value, prev);
17
+ setPrev(value);
18
+ }
19
+ }
20
+
21
+ //#endregion
22
+ export { useOnChange };
23
+ //# sourceMappingURL=use-on-change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-on-change.js","names":[],"sources":["../../src/utils/use-on-change.ts"],"sourcesContent":["import { useState } from 'react';\n\nfunction isDifferent(a: unknown, b: unknown): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n return b.length !== a.length || a.some((v, i) => isDifferent(v, b[i]));\n }\n\n return a !== b;\n}\n\n/**\n * @param value - state to watch\n * @param onChange - when the state changed\n * @param isUpdated - a function that determines if the state is updated\n */\nexport function useOnChange<T>(\n value: T,\n onChange: (current: T, previous: T) => void,\n isUpdated: (prev: T, current: T) => boolean = isDifferent,\n): void {\n const [prev, setPrev] = useState<T>(value);\n\n if (isUpdated(prev, value)) {\n onChange(value, prev);\n setPrev(value);\n }\n}\n"],"mappings":";;;AAEA,SAAS,YAAY,GAAY,GAAqB;AACpD,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,CACtC,QAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,YAAY,GAAG,EAAE,GAAG,CAAC;AAGxE,QAAO,MAAM;;;;;;;AAQf,SAAgB,YACd,OACA,UACA,YAA8C,aACxC;CACN,MAAM,CAAC,MAAM,WAAW,SAAY,MAAM;AAE1C,KAAI,UAAU,MAAM,MAAM,EAAE;AAC1B,WAAS,OAAO,KAAK;AACrB,UAAQ,MAAM"}
@@ -0,0 +1,134 @@
1
+ //#region src/page-tree/utils.ts
2
+ /**
3
+ * Flatten tree to an array of page nodes
4
+ */
5
+ function flattenTree(nodes) {
6
+ const out = [];
7
+ for (const node of nodes) if (node.type === "folder") {
8
+ if (node.index) out.push(node.index);
9
+ out.push(...flattenTree(node.children));
10
+ } else if (node.type === "page") out.push(node);
11
+ return out;
12
+ }
13
+ /**
14
+ * Get neighbours of a page, useful for implementing "previous & next" buttons
15
+ */
16
+ function findNeighbour(tree, url, options) {
17
+ const { separateRoot = true } = options ?? {};
18
+ const roots = separateRoot ? getPageTreeRoots(tree) : [tree];
19
+ if (tree.fallback) roots.push(tree.fallback);
20
+ for (const root of roots) {
21
+ const list = flattenTree(root.children);
22
+ const idx = list.findIndex((item) => item.url === url);
23
+ if (idx === -1) continue;
24
+ return {
25
+ previous: list[idx - 1],
26
+ next: list[idx + 1]
27
+ };
28
+ }
29
+ return {};
30
+ }
31
+ function getPageTreeRoots(pageTree) {
32
+ const result = pageTree.children.flatMap((child) => {
33
+ if (child.type !== "folder") return [];
34
+ const roots = getPageTreeRoots(child);
35
+ if (child.root) roots.push(child);
36
+ return roots;
37
+ });
38
+ if (!("type" in pageTree)) result.push(pageTree);
39
+ return result;
40
+ }
41
+ /**
42
+ * Get other item nodes that lives under the same parent.
43
+ */
44
+ function getPageTreePeers(treeOrTrees, url) {
45
+ return findSiblings(treeOrTrees, url).filter((item) => item.type === "page");
46
+ }
47
+ /**
48
+ * Get other tree nodes that lives under the same parent.
49
+ */
50
+ function findSiblings(treeOrTrees, url) {
51
+ if ("children" in treeOrTrees) {
52
+ const parent = findParent(treeOrTrees, url);
53
+ if (!parent) return [];
54
+ return parent.children.filter((item) => item.type !== "page" || item.url !== url);
55
+ }
56
+ for (const lang in treeOrTrees) {
57
+ const result = getPageTreePeers(treeOrTrees[lang], url);
58
+ if (result) return result;
59
+ }
60
+ return [];
61
+ }
62
+ function findParent(from, url) {
63
+ let result;
64
+ visit(from, (node, parent) => {
65
+ if ("type" in node && node.type === "page" && node.url === url) {
66
+ result = parent;
67
+ return "break";
68
+ }
69
+ });
70
+ return result;
71
+ }
72
+ /**
73
+ * Search the path of a node in the tree matched by the matcher.
74
+ *
75
+ * @returns The path to the target node (from starting root), or null if the page doesn't exist
76
+ */
77
+ function findPath(nodes, matcher, options = {}) {
78
+ const { includeSeparator = true } = options;
79
+ function run(nodes$1) {
80
+ let separator;
81
+ for (const node of nodes$1) {
82
+ if (matcher(node)) {
83
+ const items = [];
84
+ if (separator) items.push(separator);
85
+ items.push(node);
86
+ return items;
87
+ }
88
+ if (node.type === "separator" && includeSeparator) {
89
+ separator = node;
90
+ continue;
91
+ }
92
+ if (node.type === "folder") {
93
+ const items = node.index && matcher(node.index) ? [node.index] : run(node.children);
94
+ if (items) {
95
+ items.unshift(node);
96
+ if (separator) items.unshift(separator);
97
+ return items;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ return run(nodes) ?? null;
103
+ }
104
+ const VisitBreak = Symbol("VisitBreak");
105
+ /**
106
+ * Perform a depth-first search on page tree visiting every node.
107
+ *
108
+ * @param root - the root of page tree to visit.
109
+ * @param visitor - function to receive nodes, return `skip` to skip the children of current node, `break` to stop the search entirely.
110
+ */
111
+ function visit(root, visitor) {
112
+ function onNode(node, parent) {
113
+ const result = visitor(node, parent);
114
+ switch (result) {
115
+ case "skip": return node;
116
+ case "break": throw VisitBreak;
117
+ default: if (result) node = result;
118
+ }
119
+ if ("index" in node && node.index) node.index = onNode(node.index, node);
120
+ if ("fallback" in node && node.fallback) node.fallback = onNode(node.fallback, node);
121
+ if ("children" in node) for (let i = 0; i < node.children.length; i++) node.children[i] = onNode(node.children[i], node);
122
+ return node;
123
+ }
124
+ try {
125
+ return onNode(root);
126
+ } catch (e) {
127
+ if (e === VisitBreak) return root;
128
+ throw e;
129
+ }
130
+ }
131
+
132
+ //#endregion
133
+ export { flattenTree as a, visit as c, findSiblings as i, findParent as n, getPageTreePeers as o, findPath as r, getPageTreeRoots as s, findNeighbour as t };
134
+ //# sourceMappingURL=utils-DUvi2WkD.js.map