@lickle/docs 0.0.0-dev.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 (407) hide show
  1. package/README.md +3 -0
  2. package/dist/esm/_lib/fs/index.js +20 -0
  3. package/dist/esm/_lib/fs/index.js.map +1 -0
  4. package/dist/esm/_lib/fs/watch.js +30 -0
  5. package/dist/esm/_lib/fs/watch.js.map +1 -0
  6. package/dist/esm/_lib/index.js +9 -0
  7. package/dist/esm/_lib/index.js.map +1 -0
  8. package/dist/esm/_lib/jiti/index.js +16 -0
  9. package/dist/esm/_lib/jiti/index.js.map +1 -0
  10. package/dist/esm/_lib/path/index.js +42 -0
  11. package/dist/esm/_lib/path/index.js.map +1 -0
  12. package/dist/esm/_lib/pkg/index.js +128 -0
  13. package/dist/esm/_lib/pkg/index.js.map +1 -0
  14. package/dist/esm/_lib/repo/index.js +100 -0
  15. package/dist/esm/_lib/repo/index.js.map +1 -0
  16. package/dist/esm/_lib/slug/index.js +23 -0
  17. package/dist/esm/_lib/slug/index.js.map +1 -0
  18. package/dist/esm/_lib/t.js +2 -0
  19. package/dist/esm/_lib/t.js.map +1 -0
  20. package/dist/esm/_lib/tsconfig/index.js +12 -0
  21. package/dist/esm/_lib/tsconfig/index.js.map +1 -0
  22. package/dist/esm/_lib/util/index.js +54 -0
  23. package/dist/esm/_lib/util/index.js.map +1 -0
  24. package/dist/esm/cli/cmd/dev.js +74 -0
  25. package/dist/esm/cli/cmd/dev.js.map +1 -0
  26. package/dist/esm/cli/cmd/index.js +4 -0
  27. package/dist/esm/cli/cmd/index.js.map +1 -0
  28. package/dist/esm/cli/cmd/init.js +74 -0
  29. package/dist/esm/cli/cmd/init.js.map +1 -0
  30. package/dist/esm/cli/cmd/json.js +28 -0
  31. package/dist/esm/cli/cmd/json.js.map +1 -0
  32. package/dist/esm/cli/env.js +5 -0
  33. package/dist/esm/cli/env.js.map +1 -0
  34. package/dist/esm/cli/index.js +13 -0
  35. package/dist/esm/cli/index.js.map +1 -0
  36. package/dist/esm/cli/vite/client/index.jsx +20 -0
  37. package/dist/esm/cli/vite/client/index.jsx.map +1 -0
  38. package/dist/esm/cli/vite/index.js +100 -0
  39. package/dist/esm/cli/vite/index.js.map +1 -0
  40. package/dist/esm/cli.js +5 -0
  41. package/dist/esm/cli.js.map +1 -0
  42. package/dist/esm/config/defaults.js +32 -0
  43. package/dist/esm/config/defaults.js.map +1 -0
  44. package/dist/esm/config/file.js +48 -0
  45. package/dist/esm/config/file.js.map +1 -0
  46. package/dist/esm/config/index.js +7 -0
  47. package/dist/esm/config/index.js.map +1 -0
  48. package/dist/esm/config/load.js +79 -0
  49. package/dist/esm/config/load.js.map +1 -0
  50. package/dist/esm/config/types.js +2 -0
  51. package/dist/esm/config/types.js.map +1 -0
  52. package/dist/esm/core/index.js +3 -0
  53. package/dist/esm/core/index.js.map +1 -0
  54. package/dist/esm/core/project/debug.js +26 -0
  55. package/dist/esm/core/project/debug.js.map +1 -0
  56. package/dist/esm/core/project/index.js +39 -0
  57. package/dist/esm/core/project/index.js.map +1 -0
  58. package/dist/esm/core/project/naming.js +39 -0
  59. package/dist/esm/core/project/naming.js.map +1 -0
  60. package/dist/esm/core/project/routing.js +173 -0
  61. package/dist/esm/core/project/routing.js.map +1 -0
  62. package/dist/esm/core/project/types.js +4 -0
  63. package/dist/esm/core/project/types.js.map +1 -0
  64. package/dist/esm/core/reflect/index.js +10 -0
  65. package/dist/esm/core/reflect/index.js.map +1 -0
  66. package/dist/esm/core/reflect/indexed.js +195 -0
  67. package/dist/esm/core/reflect/indexed.js.map +1 -0
  68. package/dist/esm/core/reflect/resolve.js +157 -0
  69. package/dist/esm/core/reflect/resolve.js.map +1 -0
  70. package/dist/esm/core/reflect/scan.js +787 -0
  71. package/dist/esm/core/reflect/scan.js.map +1 -0
  72. package/dist/esm/core/reflect/state.js +29 -0
  73. package/dist/esm/core/reflect/state.js.map +1 -0
  74. package/dist/esm/core/reflect/types.js +16 -0
  75. package/dist/esm/core/reflect/types.js.map +1 -0
  76. package/dist/esm/core/reflect/walk.js +106 -0
  77. package/dist/esm/core/reflect/walk.js.map +1 -0
  78. package/dist/esm/solidjs/index.js +2 -0
  79. package/dist/esm/solidjs/index.js.map +1 -0
  80. package/dist/esm/solidjs/jsx-runtime.js +2 -0
  81. package/dist/esm/solidjs/jsx-runtime.js.map +1 -0
  82. package/dist/esm/ui/App.jsx +71 -0
  83. package/dist/esm/ui/App.jsx.map +1 -0
  84. package/dist/esm/ui/components/Breadcrumb.jsx +45 -0
  85. package/dist/esm/ui/components/Breadcrumb.jsx.map +1 -0
  86. package/dist/esm/ui/components/Code/index.jsx +89 -0
  87. package/dist/esm/ui/components/Code/index.jsx.map +1 -0
  88. package/dist/esm/ui/components/Comment.jsx +176 -0
  89. package/dist/esm/ui/components/Comment.jsx.map +1 -0
  90. package/dist/esm/ui/components/Declaration.jsx +147 -0
  91. package/dist/esm/ui/components/Declaration.jsx.map +1 -0
  92. package/dist/esm/ui/components/Header.jsx +66 -0
  93. package/dist/esm/ui/components/Header.jsx.map +1 -0
  94. package/dist/esm/ui/components/Layout.jsx +44 -0
  95. package/dist/esm/ui/components/Layout.jsx.map +1 -0
  96. package/dist/esm/ui/components/Link.jsx +34 -0
  97. package/dist/esm/ui/components/Link.jsx.map +1 -0
  98. package/dist/esm/ui/components/LivePreview/Example.jsx +76 -0
  99. package/dist/esm/ui/components/LivePreview/Example.jsx.map +1 -0
  100. package/dist/esm/ui/components/LivePreview/Sandbox.jsx +25 -0
  101. package/dist/esm/ui/components/LivePreview/Sandbox.jsx.map +1 -0
  102. package/dist/esm/ui/components/LivePreview/index.js +4 -0
  103. package/dist/esm/ui/components/LivePreview/index.js.map +1 -0
  104. package/dist/esm/ui/components/LivePreview/transform.js +16 -0
  105. package/dist/esm/ui/components/LivePreview/transform.js.map +1 -0
  106. package/dist/esm/ui/components/Markdown.jsx +14 -0
  107. package/dist/esm/ui/components/Markdown.jsx.map +1 -0
  108. package/dist/esm/ui/components/Page.jsx +121 -0
  109. package/dist/esm/ui/components/Page.jsx.map +1 -0
  110. package/dist/esm/ui/components/References.jsx +32 -0
  111. package/dist/esm/ui/components/References.jsx.map +1 -0
  112. package/dist/esm/ui/components/SearchPalette.jsx +178 -0
  113. package/dist/esm/ui/components/SearchPalette.jsx.map +1 -0
  114. package/dist/esm/ui/components/Sidebar.jsx +63 -0
  115. package/dist/esm/ui/components/Sidebar.jsx.map +1 -0
  116. package/dist/esm/ui/components/Syntax.jsx +10 -0
  117. package/dist/esm/ui/components/Syntax.jsx.map +1 -0
  118. package/dist/esm/ui/components/ThemeToggle.jsx +25 -0
  119. package/dist/esm/ui/components/ThemeToggle.jsx.map +1 -0
  120. package/dist/esm/ui/components/Type.jsx +444 -0
  121. package/dist/esm/ui/components/Type.jsx.map +1 -0
  122. package/dist/esm/ui/components/index.js +16 -0
  123. package/dist/esm/ui/components/index.js.map +1 -0
  124. package/dist/esm/ui/context/components.jsx +30 -0
  125. package/dist/esm/ui/context/components.jsx.map +1 -0
  126. package/dist/esm/ui/context/global.js +15 -0
  127. package/dist/esm/ui/context/global.js.map +1 -0
  128. package/dist/esm/ui/context/index.js +5 -0
  129. package/dist/esm/ui/context/index.js.map +1 -0
  130. package/dist/esm/ui/context/markup/index.jsx +25 -0
  131. package/dist/esm/ui/context/markup/index.jsx.map +1 -0
  132. package/dist/esm/ui/context/markup/markdown.js +34 -0
  133. package/dist/esm/ui/context/markup/markdown.js.map +1 -0
  134. package/dist/esm/ui/context/markup/shiki.js +58 -0
  135. package/dist/esm/ui/context/markup/shiki.js.map +1 -0
  136. package/dist/esm/ui/context/markup/util.js +22 -0
  137. package/dist/esm/ui/context/markup/util.js.map +1 -0
  138. package/dist/esm/ui/context/project/index.jsx +27 -0
  139. package/dist/esm/ui/context/project/index.jsx.map +1 -0
  140. package/dist/esm/ui/context/project/indexed.js +47 -0
  141. package/dist/esm/ui/context/project/indexed.js.map +1 -0
  142. package/dist/esm/ui/context/project/types.js +2 -0
  143. package/dist/esm/ui/context/project/types.js.map +1 -0
  144. package/dist/esm/ui/context/theme.jsx +36 -0
  145. package/dist/esm/ui/context/theme.jsx.map +1 -0
  146. package/dist/esm/ui/hooks/index.js +94 -0
  147. package/dist/esm/ui/hooks/index.js.map +1 -0
  148. package/dist/esm/ui/index.js +5 -0
  149. package/dist/esm/ui/index.js.map +1 -0
  150. package/dist/esm/ui/renderer.jsx +21 -0
  151. package/dist/esm/ui/renderer.jsx.map +1 -0
  152. package/dist/esm/ui/util/comment.js +14 -0
  153. package/dist/esm/ui/util/comment.js.map +1 -0
  154. package/dist/esm/ui/util/kind.js +85 -0
  155. package/dist/esm/ui/util/kind.js.map +1 -0
  156. package/dist/esm/ui/util/markdown.js +66 -0
  157. package/dist/esm/ui/util/markdown.js.map +1 -0
  158. package/dist/esm/ui/util/search.js +75 -0
  159. package/dist/esm/ui/util/search.js.map +1 -0
  160. package/dist/ts/_lib/fs/index.d.ts +6 -0
  161. package/dist/ts/_lib/fs/index.d.ts.map +1 -0
  162. package/dist/ts/_lib/fs/watch.d.ts +14 -0
  163. package/dist/ts/_lib/fs/watch.d.ts.map +1 -0
  164. package/dist/ts/_lib/index.d.ts +10 -0
  165. package/dist/ts/_lib/index.d.ts.map +1 -0
  166. package/dist/ts/_lib/jiti/index.d.ts +2 -0
  167. package/dist/ts/_lib/jiti/index.d.ts.map +1 -0
  168. package/dist/ts/_lib/path/index.d.ts +12 -0
  169. package/dist/ts/_lib/path/index.d.ts.map +1 -0
  170. package/dist/ts/_lib/pkg/index.d.ts +28 -0
  171. package/dist/ts/_lib/pkg/index.d.ts.map +1 -0
  172. package/dist/ts/_lib/repo/index.d.ts +30 -0
  173. package/dist/ts/_lib/repo/index.d.ts.map +1 -0
  174. package/dist/ts/_lib/slug/index.d.ts +4 -0
  175. package/dist/ts/_lib/slug/index.d.ts.map +1 -0
  176. package/dist/ts/_lib/t.d.ts +11 -0
  177. package/dist/ts/_lib/t.d.ts.map +1 -0
  178. package/dist/ts/_lib/tsconfig/index.d.ts +8 -0
  179. package/dist/ts/_lib/tsconfig/index.d.ts.map +1 -0
  180. package/dist/ts/_lib/util/index.d.ts +9 -0
  181. package/dist/ts/_lib/util/index.d.ts.map +1 -0
  182. package/dist/ts/cli/cmd/dev.d.ts +27 -0
  183. package/dist/ts/cli/cmd/dev.d.ts.map +1 -0
  184. package/dist/ts/cli/cmd/index.d.ts +4 -0
  185. package/dist/ts/cli/cmd/index.d.ts.map +1 -0
  186. package/dist/ts/cli/cmd/init.d.ts +14 -0
  187. package/dist/ts/cli/cmd/init.d.ts.map +1 -0
  188. package/dist/ts/cli/cmd/json.d.ts +12 -0
  189. package/dist/ts/cli/cmd/json.d.ts.map +1 -0
  190. package/dist/ts/cli/env.d.ts +2 -0
  191. package/dist/ts/cli/env.d.ts.map +1 -0
  192. package/dist/ts/cli/index.d.ts +78 -0
  193. package/dist/ts/cli/index.d.ts.map +1 -0
  194. package/dist/ts/cli/vite/client/index.d.ts +10 -0
  195. package/dist/ts/cli/vite/client/index.d.ts.map +1 -0
  196. package/dist/ts/cli/vite/index.d.ts +12 -0
  197. package/dist/ts/cli/vite/index.d.ts.map +1 -0
  198. package/dist/ts/cli.d.ts +3 -0
  199. package/dist/ts/cli.d.ts.map +1 -0
  200. package/dist/ts/config/defaults.d.ts +10 -0
  201. package/dist/ts/config/defaults.d.ts.map +1 -0
  202. package/dist/ts/config/file.d.ts +3 -0
  203. package/dist/ts/config/file.d.ts.map +1 -0
  204. package/dist/ts/config/index.d.ts +6 -0
  205. package/dist/ts/config/index.d.ts.map +1 -0
  206. package/dist/ts/config/load.d.ts +36 -0
  207. package/dist/ts/config/load.d.ts.map +1 -0
  208. package/dist/ts/config/types.d.ts +56 -0
  209. package/dist/ts/config/types.d.ts.map +1 -0
  210. package/dist/ts/core/index.d.ts +3 -0
  211. package/dist/ts/core/index.d.ts.map +1 -0
  212. package/dist/ts/core/project/debug.d.ts +3 -0
  213. package/dist/ts/core/project/debug.d.ts.map +1 -0
  214. package/dist/ts/core/project/index.d.ts +17 -0
  215. package/dist/ts/core/project/index.d.ts.map +1 -0
  216. package/dist/ts/core/project/naming.d.ts +23 -0
  217. package/dist/ts/core/project/naming.d.ts.map +1 -0
  218. package/dist/ts/core/project/routing.d.ts +61 -0
  219. package/dist/ts/core/project/routing.d.ts.map +1 -0
  220. package/dist/ts/core/project/types.d.ts +56 -0
  221. package/dist/ts/core/project/types.d.ts.map +1 -0
  222. package/dist/ts/core/reflect/index.d.ts +22 -0
  223. package/dist/ts/core/reflect/index.d.ts.map +1 -0
  224. package/dist/ts/core/reflect/indexed.d.ts +83 -0
  225. package/dist/ts/core/reflect/indexed.d.ts.map +1 -0
  226. package/dist/ts/core/reflect/resolve.d.ts +3 -0
  227. package/dist/ts/core/reflect/resolve.d.ts.map +1 -0
  228. package/dist/ts/core/reflect/scan.d.ts +218 -0
  229. package/dist/ts/core/reflect/scan.d.ts.map +1 -0
  230. package/dist/ts/core/reflect/state.d.ts +44 -0
  231. package/dist/ts/core/reflect/state.d.ts.map +1 -0
  232. package/dist/ts/core/reflect/types.d.ts +289 -0
  233. package/dist/ts/core/reflect/types.d.ts.map +1 -0
  234. package/dist/ts/core/reflect/walk.d.ts +28 -0
  235. package/dist/ts/core/reflect/walk.d.ts.map +1 -0
  236. package/dist/ts/solidjs/index.d.ts +2 -0
  237. package/dist/ts/solidjs/index.d.ts.map +1 -0
  238. package/dist/ts/solidjs/jsx-runtime.d.ts +2 -0
  239. package/dist/ts/solidjs/jsx-runtime.d.ts.map +1 -0
  240. package/dist/ts/ui/App.d.ts +17 -0
  241. package/dist/ts/ui/App.d.ts.map +1 -0
  242. package/dist/ts/ui/components/Breadcrumb.d.ts +4 -0
  243. package/dist/ts/ui/components/Breadcrumb.d.ts.map +1 -0
  244. package/dist/ts/ui/components/Code/index.d.ts +17 -0
  245. package/dist/ts/ui/components/Code/index.d.ts.map +1 -0
  246. package/dist/ts/ui/components/Comment.d.ts +49 -0
  247. package/dist/ts/ui/components/Comment.d.ts.map +1 -0
  248. package/dist/ts/ui/components/Declaration.d.ts +122 -0
  249. package/dist/ts/ui/components/Declaration.d.ts.map +1 -0
  250. package/dist/ts/ui/components/Header.d.ts +5 -0
  251. package/dist/ts/ui/components/Header.d.ts.map +1 -0
  252. package/dist/ts/ui/components/Layout.d.ts +5 -0
  253. package/dist/ts/ui/components/Layout.d.ts.map +1 -0
  254. package/dist/ts/ui/components/Link.d.ts +15 -0
  255. package/dist/ts/ui/components/Link.d.ts.map +1 -0
  256. package/dist/ts/ui/components/LivePreview/Example.d.ts +16 -0
  257. package/dist/ts/ui/components/LivePreview/Example.d.ts.map +1 -0
  258. package/dist/ts/ui/components/LivePreview/Sandbox.d.ts +20 -0
  259. package/dist/ts/ui/components/LivePreview/Sandbox.d.ts.map +1 -0
  260. package/dist/ts/ui/components/LivePreview/index.d.ts +4 -0
  261. package/dist/ts/ui/components/LivePreview/index.d.ts.map +1 -0
  262. package/dist/ts/ui/components/LivePreview/transform.d.ts +19 -0
  263. package/dist/ts/ui/components/LivePreview/transform.d.ts.map +1 -0
  264. package/dist/ts/ui/components/Markdown.d.ts +11 -0
  265. package/dist/ts/ui/components/Markdown.d.ts.map +1 -0
  266. package/dist/ts/ui/components/Page.d.ts +21 -0
  267. package/dist/ts/ui/components/Page.d.ts.map +1 -0
  268. package/dist/ts/ui/components/References.d.ts +2 -0
  269. package/dist/ts/ui/components/References.d.ts.map +1 -0
  270. package/dist/ts/ui/components/SearchPalette.d.ts +5 -0
  271. package/dist/ts/ui/components/SearchPalette.d.ts.map +1 -0
  272. package/dist/ts/ui/components/Sidebar.d.ts +5 -0
  273. package/dist/ts/ui/components/Sidebar.d.ts.map +1 -0
  274. package/dist/ts/ui/components/Syntax.d.ts +15 -0
  275. package/dist/ts/ui/components/Syntax.d.ts.map +1 -0
  276. package/dist/ts/ui/components/ThemeToggle.d.ts +2 -0
  277. package/dist/ts/ui/components/ThemeToggle.d.ts.map +1 -0
  278. package/dist/ts/ui/components/Type.d.ts +82 -0
  279. package/dist/ts/ui/components/Type.d.ts.map +1 -0
  280. package/dist/ts/ui/components/index.d.ts +15 -0
  281. package/dist/ts/ui/components/index.d.ts.map +1 -0
  282. package/dist/ts/ui/context/components.d.ts +124 -0
  283. package/dist/ts/ui/context/components.d.ts.map +1 -0
  284. package/dist/ts/ui/context/global.d.ts +210 -0
  285. package/dist/ts/ui/context/global.d.ts.map +1 -0
  286. package/dist/ts/ui/context/index.d.ts +5 -0
  287. package/dist/ts/ui/context/index.d.ts.map +1 -0
  288. package/dist/ts/ui/context/markup/index.d.ts +20 -0
  289. package/dist/ts/ui/context/markup/index.d.ts.map +1 -0
  290. package/dist/ts/ui/context/markup/markdown.d.ts +4 -0
  291. package/dist/ts/ui/context/markup/markdown.d.ts.map +1 -0
  292. package/dist/ts/ui/context/markup/shiki.d.ts +17 -0
  293. package/dist/ts/ui/context/markup/shiki.d.ts.map +1 -0
  294. package/dist/ts/ui/context/markup/util.d.ts +11 -0
  295. package/dist/ts/ui/context/markup/util.d.ts.map +1 -0
  296. package/dist/ts/ui/context/project/index.d.ts +25 -0
  297. package/dist/ts/ui/context/project/index.d.ts.map +1 -0
  298. package/dist/ts/ui/context/project/indexed.d.ts +4 -0
  299. package/dist/ts/ui/context/project/indexed.d.ts.map +1 -0
  300. package/dist/ts/ui/context/project/types.d.ts +13 -0
  301. package/dist/ts/ui/context/project/types.d.ts.map +1 -0
  302. package/dist/ts/ui/context/theme.d.ts +12 -0
  303. package/dist/ts/ui/context/theme.d.ts.map +1 -0
  304. package/dist/ts/ui/hooks/index.d.ts +29 -0
  305. package/dist/ts/ui/hooks/index.d.ts.map +1 -0
  306. package/dist/ts/ui/index.d.ts +5 -0
  307. package/dist/ts/ui/index.d.ts.map +1 -0
  308. package/dist/ts/ui/renderer.d.ts +200 -0
  309. package/dist/ts/ui/renderer.d.ts.map +1 -0
  310. package/dist/ts/ui/util/comment.d.ts +4 -0
  311. package/dist/ts/ui/util/comment.d.ts.map +1 -0
  312. package/dist/ts/ui/util/kind.d.ts +15 -0
  313. package/dist/ts/ui/util/kind.d.ts.map +1 -0
  314. package/dist/ts/ui/util/markdown.d.ts +8 -0
  315. package/dist/ts/ui/util/markdown.d.ts.map +1 -0
  316. package/dist/ts/ui/util/search.d.ts +20 -0
  317. package/dist/ts/ui/util/search.d.ts.map +1 -0
  318. package/package.json +89 -0
  319. package/src/_lib/fs/index.ts +23 -0
  320. package/src/_lib/fs/watch.ts +40 -0
  321. package/src/_lib/index.ts +9 -0
  322. package/src/_lib/jiti/index.ts +18 -0
  323. package/src/_lib/path/index.ts +44 -0
  324. package/src/_lib/pkg/index.ts +165 -0
  325. package/src/_lib/repo/index.ts +138 -0
  326. package/src/_lib/slug/index.ts +26 -0
  327. package/src/_lib/t.ts +17 -0
  328. package/src/_lib/tsconfig/index.ts +20 -0
  329. package/src/_lib/util/index.ts +53 -0
  330. package/src/cli/cmd/dev.ts +86 -0
  331. package/src/cli/cmd/index.ts +3 -0
  332. package/src/cli/cmd/init.ts +80 -0
  333. package/src/cli/cmd/json.ts +28 -0
  334. package/src/cli/env.ts +6 -0
  335. package/src/cli/index.ts +14 -0
  336. package/src/cli/vite/client/index.html +27 -0
  337. package/src/cli/vite/client/index.tsx +30 -0
  338. package/src/cli/vite/client/public/apple-touch-icon.png +0 -0
  339. package/src/cli/vite/client/public/favicon-96x96.png +0 -0
  340. package/src/cli/vite/client/public/favicon.ico +0 -0
  341. package/src/cli/vite/client/public/favicon.svg +1 -0
  342. package/src/cli/vite/client/public/site.webmanifest +21 -0
  343. package/src/cli/vite/client/public/web-app-manifest-192x192.png +0 -0
  344. package/src/cli/vite/client/public/web-app-manifest-512x512.png +0 -0
  345. package/src/cli/vite/index.ts +115 -0
  346. package/src/cli.ts +6 -0
  347. package/src/config/defaults.ts +36 -0
  348. package/src/config/file.ts +53 -0
  349. package/src/config/index.ts +11 -0
  350. package/src/config/load.ts +95 -0
  351. package/src/config/types.ts +59 -0
  352. package/src/core/index.ts +2 -0
  353. package/src/core/project/debug.ts +30 -0
  354. package/src/core/project/index.ts +58 -0
  355. package/src/core/project/naming.ts +49 -0
  356. package/src/core/project/routing.ts +234 -0
  357. package/src/core/project/types.ts +47 -0
  358. package/src/core/reflect/index.ts +18 -0
  359. package/src/core/reflect/indexed.ts +242 -0
  360. package/src/core/reflect/resolve.ts +159 -0
  361. package/src/core/reflect/scan.ts +816 -0
  362. package/src/core/reflect/state.ts +75 -0
  363. package/src/core/reflect/types.ts +164 -0
  364. package/src/core/reflect/walk.ts +121 -0
  365. package/src/solidjs/index.ts +1 -0
  366. package/src/solidjs/jsx-runtime.ts +1 -0
  367. package/src/ui/App.tsx +115 -0
  368. package/src/ui/components/Breadcrumb.tsx +53 -0
  369. package/src/ui/components/Code/index.tsx +112 -0
  370. package/src/ui/components/Comment.tsx +221 -0
  371. package/src/ui/components/Declaration.tsx +210 -0
  372. package/src/ui/components/Header.tsx +99 -0
  373. package/src/ui/components/Layout.tsx +62 -0
  374. package/src/ui/components/Link.tsx +43 -0
  375. package/src/ui/components/LivePreview/Example.tsx +104 -0
  376. package/src/ui/components/LivePreview/Sandbox.tsx +36 -0
  377. package/src/ui/components/LivePreview/index.ts +3 -0
  378. package/src/ui/components/LivePreview/transform.ts +28 -0
  379. package/src/ui/components/Markdown.tsx +16 -0
  380. package/src/ui/components/Page.tsx +162 -0
  381. package/src/ui/components/References.tsx +34 -0
  382. package/src/ui/components/SearchPalette.tsx +266 -0
  383. package/src/ui/components/Sidebar.tsx +107 -0
  384. package/src/ui/components/Syntax.tsx +10 -0
  385. package/src/ui/components/ThemeToggle.tsx +50 -0
  386. package/src/ui/components/Type.tsx +583 -0
  387. package/src/ui/components/index.ts +15 -0
  388. package/src/ui/context/components.tsx +103 -0
  389. package/src/ui/context/global.ts +33 -0
  390. package/src/ui/context/index.ts +4 -0
  391. package/src/ui/context/markup/index.tsx +39 -0
  392. package/src/ui/context/markup/markdown.ts +37 -0
  393. package/src/ui/context/markup/shiki.ts +72 -0
  394. package/src/ui/context/markup/util.ts +20 -0
  395. package/src/ui/context/project/index.tsx +47 -0
  396. package/src/ui/context/project/indexed.ts +52 -0
  397. package/src/ui/context/project/types.ts +14 -0
  398. package/src/ui/context/theme.tsx +45 -0
  399. package/src/ui/hooks/index.ts +116 -0
  400. package/src/ui/index.ts +4 -0
  401. package/src/ui/renderer.tsx +31 -0
  402. package/src/ui/util/comment.ts +12 -0
  403. package/src/ui/util/kind.ts +120 -0
  404. package/src/ui/util/markdown.ts +74 -0
  405. package/src/ui/util/search.ts +84 -0
  406. package/theme.css +301 -0
  407. package/tsconfig.client.json +12 -0
@@ -0,0 +1,103 @@
1
+ import { createContext, createMemo, Show, useContext } from 'solid-js'
2
+ import type { Accessor, Component } from 'solid-js'
3
+ import type { JSX } from 'solid-js/jsx-runtime'
4
+ import { Dynamic } from 'solid-js/web'
5
+
6
+ import type { Types } from '../context/index.ts'
7
+ import type { t } from '../../_lib/index.ts'
8
+
9
+ const ComponentsCtx = createContext<Accessor<Components>>(() => ({}))
10
+
11
+ /**
12
+ * Provide a component registry to descendants. When nested inside another
13
+ * `<ComponentsProvider>` the inner value is shallow-merged onto the outer one,
14
+ * so a wrapper preset can establish defaults that an app extends without
15
+ * losing the outer's entries.
16
+ */
17
+ export const ComponentsProvider = (props: { value?: Components; children: JSX.Element }) => {
18
+ const outer = useContext(ComponentsCtx)
19
+ const merged = createMemo<Components>(() => ({ ...outer(), ...window.lickle.components[0](), ...props.value }))
20
+ return <ComponentsCtx.Provider value={merged}>{props.children}</ComponentsCtx.Provider>
21
+ }
22
+
23
+ /** Read the active (already-merged) component registry. */
24
+ export const useComponents = (): Accessor<Components> => useContext(ComponentsCtx)
25
+
26
+ /**
27
+ * Build a slot dispatcher in one line: look up the override under `key`,
28
+ * forward `Default` so it can decorate, otherwise render the default. The
29
+ * override and default share the same prop shape — that's what the
30
+ * `WithDefault<P>` wrapper in {@link Slots} pins down.
31
+ */
32
+ export const createSlot =
33
+ <K extends keyof Components>(
34
+ key: K,
35
+ Default: Component<t.Compute<Omit<Params<Components[K]>[0], 'Default'>>>,
36
+ ): Component<t.Compute<Omit<Params<Components[K]>[0], 'Default'>>> =>
37
+ (props) => {
38
+ const slots = useComponents()
39
+ const override = createMemo(() => slots()[key] as Component<any> | undefined)
40
+ return (
41
+ <Show when={override()} fallback={<Default {...(props as any)} />} keyed>
42
+ {(Override) => <Dynamic component={Override} {...(props as any)} Default={Default} />}
43
+ </Show>
44
+ )
45
+ }
46
+
47
+ type Params<T> = T extends (...args: infer P) => any ? P : never
48
+
49
+ type WithDefault<P extends Record<string, any>> = P & { Default: Component<P> }
50
+
51
+ export type DeclarationProps<K extends keyof Types.DeclarationMap> = WithDefault<{
52
+ decl: Types.DeclarationMap[K]
53
+ }>
54
+
55
+ type PageProps = { decl: Types.Declaration; route: Types.RouteNode<'declaration' | 'module'> }
56
+
57
+ export type SlotComponent<K extends keyof Components> = Components[K]
58
+ /**
59
+ * Slot override signatures. Every slot receives `Default` typed to the
60
+ * stock component's props so the override can decorate (`<Default {...p} />`
61
+ * plus extras) instead of replacing wholesale.
62
+ */
63
+ export interface Components {
64
+ home?: Component<WithDefault<{}>>
65
+ layout?: Component<WithDefault<{ children: JSX.Element }>>
66
+ header?: Component<WithDefault<{ onMenu?: () => void; onSearch?: () => void }>>
67
+ sidebar?: Component<WithDefault<{ onNavigate?: () => void; class?: string }>>
68
+
69
+ // Page slots
70
+ page?: Component<WithDefault<PageProps>>
71
+ 'page.markdown'?: Component<WithDefault<{ route: Types.RouteNode<'markdown'> }>>
72
+ 'page.header'?: Component<WithDefault<PageProps>>
73
+ 'page.header.breadcrumb'?: Component<WithDefault<{ id: number }>>
74
+ 'page.source'?: Component<WithDefault<{ sources?: Types.Source[] }>>
75
+ 'page.references'?: Component<WithDefault<{ id: number }>>
76
+
77
+ // Declaration page slots
78
+ declaration?: Component<WithDefault<{ decl: Types.Declaration }>>
79
+ 'declaration.function'?: Component<DeclarationProps<'function'>>
80
+ 'declaration.variable'?: Component<DeclarationProps<'variable'>>
81
+ 'declaration.type-alias'?: Component<DeclarationProps<'type-alias'>>
82
+ 'declaration.class'?: Component<DeclarationProps<'class'>>
83
+ 'declaration.interface'?: Component<DeclarationProps<'interface'>>
84
+ 'declaration.enum'?: Component<DeclarationProps<'enum'>>
85
+ 'declaration.module'?: Component<DeclarationProps<'module'>>
86
+ 'declaration.namespace'?: Component<DeclarationProps<'namespace'>>
87
+
88
+ comment?: Component<WithDefault<{ comment?: Types.Comment; class?: string }>>
89
+ 'comment.parameters'?: Component<WithDefault<{ tags: Types.CommentTagMap['@param'][] }>>
90
+ 'comment.properties'?: Component<WithDefault<{ tags: Types.CommentTagMap['@property'][] }>>
91
+
92
+ tag?: Component<WithDefault<{ tag: Types.CommentTag }>>
93
+ 'tag.returns'?: Component<WithDefault<{ tag: t.Compute<Types.CommentTagMap['@returns']> }>>
94
+ 'tag.throws'?: Component<WithDefault<{ tag: Types.CommentTagMap['@throws'] }>>
95
+ 'tag.type'?: Component<WithDefault<{ tag: Types.CommentTagMap['@type'] }>>
96
+ 'tag.satisfies'?: Component<WithDefault<{ tag: Types.CommentTagMap['@satisfies'] }>>
97
+ 'tag.example'?: Component<WithDefault<{ tag: Types.CommentTagMap['@example'] }>>
98
+ 'tag.see'?: Component<WithDefault<{ tag: Types.CommentTagMap['@see'] }>>
99
+ 'tag.template'?: Component<WithDefault<{ tag: Types.CommentTagMap['@template'] }>>
100
+ 'tag.augments'?: Component<WithDefault<{ tag: Types.CommentTagMap['@augments'] }>>
101
+ 'tag.implements'?: Component<WithDefault<{ tag: Types.CommentTagMap['@implements'] }>>
102
+ 'tag.*'?: Component<WithDefault<{ tag: Types.CommentTag }>>
103
+ }
@@ -0,0 +1,33 @@
1
+ import { createSignal, type Signal } from 'solid-js'
2
+
3
+ import type { Types } from '../context/index.ts'
4
+ import type { Components } from './components.tsx'
5
+
6
+ declare global {
7
+ interface Lickle {
8
+ components: Signal<Components>
9
+ json: Signal<Types.ProjectJson | null>
10
+ rendered: Signal<boolean>
11
+ }
12
+ interface Window {
13
+ lickle: Lickle
14
+ }
15
+ }
16
+
17
+ if (typeof window !== 'undefined') {
18
+ window.lickle = {
19
+ components: createSignal<Components>({}),
20
+ json: createSignal<Types.ProjectJson | null>(null),
21
+ rendered: createSignal<boolean>(false),
22
+ }
23
+ }
24
+
25
+ export const getComponents = () => window.lickle.components[0]()
26
+ export const setComponents = (components: Partial<Components>) =>
27
+ window.lickle.components[1]({ ...window.lickle.components[0](), ...components })
28
+
29
+ export const getJson = () => window.lickle.json[0]()
30
+ export const setJson = (json: Types.ProjectJson | null) => window.lickle.json[1](json)
31
+
32
+ export const getRendered = () => window.lickle.rendered[0]()
33
+ export const setRendered = (rendered: boolean) => window.lickle.rendered[1](rendered)
@@ -0,0 +1,4 @@
1
+ export * from './project/index.tsx'
2
+ export * from './markup/index.tsx'
3
+ export * from './components.tsx'
4
+ export * from './theme.tsx'
@@ -0,0 +1,39 @@
1
+ import { createContext, createMemo, createResource, useContext } from 'solid-js'
2
+ import type { JSX } from 'solid-js/jsx-runtime'
3
+ import type { Marked } from 'marked'
4
+
5
+ import { highlighter, type Highlighter, type CodeToHtmlOptions } from './shiki.ts'
6
+ import { useProject } from '../project/index.tsx'
7
+ import { buildMarked } from './markdown.ts'
8
+
9
+ export * from './util.ts'
10
+
11
+ export type { Highlighter, CodeToHtmlOptions }
12
+
13
+ const H = highlighter()
14
+
15
+ type MarkupContext = {
16
+ promise: Promise<Highlighter>
17
+ highlighter: () => Highlighter | undefined
18
+ marked: () => Marked | undefined
19
+ }
20
+ const Context = createContext<MarkupContext>()
21
+
22
+ export const MarkupProvider = (props: { children: JSX.Element }) => {
23
+ const project = useProject()
24
+ const lookup = (name: string) => project().routeByName(name)?.slug
25
+ const [h] = createResource(async () => await H)
26
+ const marked = createMemo(() => buildMarked(h(), lookup))
27
+ return <Context.Provider value={{ promise: H, highlighter: () => h(), marked }}>{props.children}</Context.Provider>
28
+ }
29
+
30
+ export const useMarkup = (): MarkupContext => {
31
+ const ctx = useContext(Context)
32
+ if (!ctx) throw new Error('useMarkup must be used within a <MarkupProvider>')
33
+ return ctx
34
+ }
35
+
36
+ export const useCodeToHtml = (p: { code: string; lang?: string; structure?: 'inline' | 'classic' }) => {
37
+ const markup = useMarkup()
38
+ return createMemo(() => markup.highlighter()?.codeToHtml({ ...p, text: p.code, markdown: true }))
39
+ }
@@ -0,0 +1,37 @@
1
+ import { Marked } from 'marked'
2
+
3
+ import type { Highlighter } from './shiki.ts'
4
+ import { langOf } from './util.ts'
5
+
6
+ export const buildMarked = (h: Highlighter | undefined, lookup?: (raw: string) => string | undefined) => {
7
+ const m = new Marked({
8
+ gfm: true,
9
+ breaks: false,
10
+ renderer: {
11
+ code({ text, lang }) {
12
+ const language = langOf(lang)
13
+ if (h && language !== 'text') {
14
+ try {
15
+ return h.codeToHtml({ text, lang: language })
16
+ } catch {
17
+ /* fall through */
18
+ }
19
+ }
20
+ return `<pre class="codeblock"><code>${escape(text)}</code></pre>`
21
+ },
22
+ codespan({ text }) {
23
+ if (lookup && ID.test(text)) {
24
+ const slug = lookup(text)
25
+ if (slug) return `<a href="/${slug}" class="codelink"><code>${text}</code></a>`
26
+ }
27
+ return `<code>${text}</code>`
28
+ },
29
+ },
30
+ })
31
+ return m
32
+ }
33
+
34
+ const escape = (s: string) =>
35
+ s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
36
+
37
+ const ID = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/
@@ -0,0 +1,72 @@
1
+ import type { HighlighterCore } from 'shiki/core'
2
+
3
+ import { extractCodeBlocks } from './util.ts'
4
+
5
+ export type CodeToHtmlOptions = {
6
+ text: string
7
+ lang?: string
8
+ structure?: 'inline' | 'classic'
9
+ markdown?: boolean
10
+ }
11
+
12
+ export type Highlighter = { codeToHtml: (options: CodeToHtmlOptions) => string }
13
+
14
+ export const highlighter = async (): Promise<Highlighter> => {
15
+ const h = await getHighlighter()
16
+ const codeToHtml = (options: CodeToHtmlOptions) => {
17
+ const opts = {
18
+ lang: options.lang ?? 'ts',
19
+ themes: { light: 'github-light', dark: 'github-dark' },
20
+ defaultColor: false,
21
+ structure: options.structure,
22
+ } as const
23
+
24
+ if (options.markdown) {
25
+ const extracted = extractCodeBlocks(options.text)?.[0]
26
+ if (extracted) {
27
+ if (!h || !extracted) return ''
28
+ const text = extracted.code ?? options.text
29
+ const lang = extracted.lang ?? options.lang ?? 'ts'
30
+ return h.codeToHtml(text, { ...opts, lang: lang })
31
+ }
32
+ }
33
+ return h.codeToHtml(options.text, opts)
34
+ }
35
+ return { codeToHtml }
36
+ }
37
+
38
+ /**
39
+ * Fine-grained Shiki bundle: only the langs/themes below are emitted as chunks.
40
+ * Importing the default `shiki` entry would code-split every grammar and theme.
41
+ */
42
+ export const getHighlighter = (): Promise<HighlighterCore> => {
43
+ if (!highlighterPromise) highlighterPromise = buildHighlighter()
44
+ return highlighterPromise
45
+ }
46
+ let highlighterPromise: Promise<HighlighterCore> | null = null
47
+
48
+ const buildHighlighter = (): Promise<HighlighterCore> => {
49
+ return Promise.all([
50
+ import('shiki/core'),
51
+ import('shiki/engine/javascript'),
52
+ import('shiki/themes/github-light.mjs'),
53
+ import('shiki/themes/github-dark.mjs'),
54
+ Promise.all([
55
+ import('shiki/langs/typescript.mjs'),
56
+ import('shiki/langs/tsx.mjs'),
57
+ import('shiki/langs/javascript.mjs'),
58
+ import('shiki/langs/jsx.mjs'),
59
+ import('shiki/langs/json.mjs'),
60
+ import('shiki/langs/bash.mjs'),
61
+ import('shiki/langs/html.mjs'),
62
+ import('shiki/langs/css.mjs'),
63
+ import('shiki/langs/markdown.mjs'),
64
+ ]),
65
+ ]).then(([core, js, light, dark, langs]) =>
66
+ core.createHighlighterCore({
67
+ engine: js.createJavaScriptRegexEngine(),
68
+ themes: [light.default, dark.default],
69
+ langs: langs.map((m) => m.default),
70
+ }),
71
+ )
72
+ }
@@ -0,0 +1,20 @@
1
+ const CODE_BLOCK_RE = /```([^\n]*)\n([\s\S]*?)```/g
2
+ export const extractCodeBlocks = (input: string): { lang: string; code: string }[] => [
3
+ ...(input?.matchAll(CODE_BLOCK_RE)?.map((m) => ({ lang: m[1]!, code: m[2]! })) ?? []),
4
+ ]
5
+
6
+ export const firstCodeBlock = (input: string): { lang: string; code: string } =>
7
+ extractCodeBlocks(input)?.[0] ?? { lang: '', code: input }
8
+
9
+ export const getUnfencedCode = (code: string) => firstCodeBlock(code).code
10
+
11
+ const LANGS = ['ts', 'tsx', 'js', 'jsx', 'json', 'bash', 'html', 'css', 'md']
12
+ export const langOf = (info: string | undefined) => {
13
+ const raw = (info ?? '').trim().split(/\s+/)[0]?.toLowerCase() ?? ''
14
+ if (!raw) return 'text'
15
+ if (LANGS.includes(raw)) return raw
16
+ if (raw === 'sh' || raw === 'zsh') return 'bash'
17
+ if (raw === 'typescript') return 'ts'
18
+ if (raw === 'javascript') return 'js'
19
+ return 'text'
20
+ }
@@ -0,0 +1,47 @@
1
+ import { createContext, createMemo, useContext, type Accessor } from 'solid-js'
2
+ import type { JSX } from 'solid-js/jsx-runtime'
3
+
4
+ import type { ProjectJson } from './types.ts'
5
+
6
+ import { ComponentsProvider, type Components } from '../components.tsx'
7
+ import { createProject } from './indexed.ts'
8
+
9
+ import * as T from './types.ts'
10
+ export * as Types from './types.ts'
11
+
12
+ const ProjectCtx = createContext<Accessor<T.Project>>()
13
+
14
+ export type ProjectProviderProps = {
15
+ children: JSX.Element
16
+ json: Accessor<ProjectJson>
17
+ /** Component overrides — pages, tags, slots, member sections. */
18
+ components?: Components
19
+ }
20
+
21
+ export const ProjectProvider = (props: ProjectProviderProps) => {
22
+ const bag = createMemo<T.Project>(() => createProject(props.json()))
23
+ return (
24
+ <ComponentsProvider value={props.components}>
25
+ <ProjectCtx.Provider value={bag}>{props.children}</ProjectCtx.Provider>
26
+ </ComponentsProvider>
27
+ )
28
+ }
29
+
30
+ export const useProject = (): Accessor<T.Project> => {
31
+ const fn = useContext(ProjectCtx)
32
+ if (!fn) throw new Error('useProject must be used within <ProjectProvider>')
33
+ return fn
34
+ }
35
+
36
+ const DeclarationIdContext = createContext<Accessor<number | undefined>>(() => undefined)
37
+
38
+ /**
39
+ * Scope a subtree to a reflection id so nested `<Comment>`s pass it to tag
40
+ * handlers. The id is exposed as a reactive accessor so consumers re-track
41
+ * when the surrounding route swaps to a new declaration.
42
+ */
43
+ export const DeclarationScope = (props: { id: number; children: JSX.Element }) => (
44
+ <DeclarationIdContext.Provider value={() => props.id}>{props.children}</DeclarationIdContext.Provider>
45
+ )
46
+
47
+ export const useDeclarationId = (): Accessor<number | undefined> => useContext(DeclarationIdContext)
@@ -0,0 +1,52 @@
1
+ import type { ProjectJson, RouteNode } from '../../../core/project/index.ts'
2
+ import * as Types from './types.ts'
3
+
4
+ export const createProject = (json: ProjectJson): Types.Project => {
5
+ const _byId = new Map<number, Types.Declaration>()
6
+ const _bySlug = new Map<string, Types.Declaration>()
7
+ const _routesById = new Map<number, RouteNode>()
8
+ const _routesBySlug = new Map<string, RouteNode>()
9
+ const _slugByName = new Map<string, RouteNode>()
10
+
11
+ const sourceLink = (src: Types.Source) => {
12
+ if (!json.repository?.fileUrl) return undefined
13
+ return json.repository.fileUrl.replace('{PATH}', src.file).replace('{LINE}', src.line.toString())
14
+ }
15
+
16
+ for (const declaration of json.declarations) {
17
+ _byId.set(declaration.id, declaration)
18
+ }
19
+
20
+ const indexRoute = (r: RouteNode) => {
21
+ _routesBySlug.set(r.slug, r)
22
+ // Markdown pages carry no declaration id, so they only resolve by slug.
23
+ if (r.page.kind !== 'markdown') {
24
+ _bySlug.set(r.slug, _byId.get(r.page.id)!)
25
+ _routesById.set(r.page.id, r)
26
+ const name = _byId.get(r.page.id)?.name
27
+ if (name && !_slugByName.has(name)) _slugByName.set(name, r)
28
+ _slugByName.set(r.page.qualified, r)
29
+ }
30
+ for (const child of r.children) indexRoute(child)
31
+ }
32
+
33
+ for (const route of json.routes) indexRoute(route)
34
+
35
+ const byId = (id: number): Types.Declaration | undefined => _byId.get(id)
36
+ const bySlug = (slug: string): Types.Declaration | undefined => _bySlug.get(slug)
37
+ const routeForId = (id: number): RouteNode | undefined => _routesById.get(id)
38
+ const routeForSlug = (slug: string): RouteNode | undefined => _routesBySlug.get(slug)
39
+ const routeByName = (name: string): RouteNode | undefined => _slugByName.get(name)
40
+ const p: Types.Project = json as Types.Project
41
+
42
+ hide(p, 'byId', byId)
43
+ hide(p, 'bySlug', bySlug)
44
+ hide(p, 'routeForId', routeForId)
45
+ hide(p, 'routeForSlug', routeForSlug)
46
+ hide(p, 'routeByName', routeByName)
47
+ hide(p, 'sourceLink', sourceLink)
48
+ return p
49
+ }
50
+
51
+ const hide = <T, K extends keyof T>(obj: T, key: K, value: T[K]) =>
52
+ Object.defineProperty(obj, key, { value, enumerable: false, configurable: true })
@@ -0,0 +1,14 @@
1
+ import type { ProjectJson, RouteNode } from '../../../core/project/types.ts'
2
+ import type { Declaration, Source } from '../../../core/reflect/types.ts'
3
+
4
+ export interface Project extends ProjectJson {
5
+ byId(id: number): Declaration | undefined
6
+ bySlug(slug: string): Declaration | undefined
7
+ routeByName(name: string): RouteNode | undefined
8
+ routeForId(id: number): RouteNode | undefined
9
+ routeForSlug(slug: string): RouteNode | undefined
10
+ sourceLink(src: Source): string | undefined
11
+ }
12
+
13
+ export type * from '../../../core/project/types.ts'
14
+ export type * from '../../../core/reflect/types.ts'
@@ -0,0 +1,45 @@
1
+ import { createContext, createSignal, onMount, useContext } from 'solid-js'
2
+ import type { JSX } from 'solid-js/jsx-runtime'
3
+
4
+ export type ThemeMode = 'light' | 'dark' | 'system'
5
+ const STORAGE_KEY = 'lickle-docs-theme'
6
+
7
+ type ThemeCtx = {
8
+ mode: () => ThemeMode
9
+ setMode: (m: ThemeMode) => void
10
+ }
11
+
12
+ const Ctx = createContext<ThemeCtx>()
13
+
14
+ const read = (): ThemeMode => {
15
+ if (typeof localStorage === 'undefined') return 'system'
16
+ const v = localStorage.getItem(STORAGE_KEY)
17
+ return v === 'light' || v === 'dark' ? v : 'system'
18
+ }
19
+
20
+ const apply = (m: ThemeMode) => {
21
+ const el = document.documentElement
22
+ if (m === 'system') delete el.dataset['theme']
23
+ else el.dataset['theme'] = m
24
+ }
25
+
26
+ export const ThemeProvider = (props: { children: JSX.Element }) => {
27
+ const [mode, set] = createSignal<ThemeMode>(read())
28
+
29
+ onMount(() => apply(mode()))
30
+
31
+ const setMode = (m: ThemeMode) => {
32
+ if (m === 'system') localStorage.removeItem(STORAGE_KEY)
33
+ else localStorage.setItem(STORAGE_KEY, m)
34
+ set(m)
35
+ apply(m)
36
+ }
37
+
38
+ return <Ctx.Provider value={{ mode, setMode }}>{props.children}</Ctx.Provider>
39
+ }
40
+
41
+ export const useTheme = (): ThemeCtx => {
42
+ const ctx = useContext(Ctx)
43
+ if (!ctx) throw new Error('useTheme must be used within a <ThemeProvider>')
44
+ return ctx
45
+ }
@@ -0,0 +1,116 @@
1
+ import { createMemo, type Accessor } from 'solid-js'
2
+
3
+ import { createSearchEngine, type SearchEngine } from '../util/search.ts'
4
+ import { useProject, type Types } from '../context/index.ts'
5
+ import { commentSummaryText } from '../util/comment.ts'
6
+
7
+ // ============================================================================
8
+ // SELECTOR HOOKS
9
+ // Thin readers over the project bag. Components should reach for these instead
10
+ // of pulling `project` apart directly.
11
+ // ============================================================================
12
+
13
+ /**
14
+ * Slug accessors keyed two ways. `byId` is the id-driven path used by render
15
+ * code; `byName` powers `{@link Foo}` / `<code>Foo</code>` resolution (short
16
+ * names and qualified names both resolve via the project's name index).
17
+ */
18
+ export const useSlugFor = () => {
19
+ const project = useProject()
20
+ return {
21
+ byId: (id: number): string | undefined => project().routeForId(id)?.slug,
22
+ byName: (name: string): string | undefined => project().routeByName(name)?.slug,
23
+ }
24
+ }
25
+
26
+ // ============================================================================
27
+ // REFERENCES
28
+ // "Used in" rows, materialized from each page's `referencedIn` id list.
29
+ // ============================================================================
30
+
31
+ export interface ReferenceRow {
32
+ decl: Types.Declaration
33
+ slug: string
34
+ /** Everything before the final dot of the qualified name. Empty for top-level symbols. */
35
+ module: string
36
+ name: string
37
+ qualified: string
38
+ summary: string
39
+ }
40
+
41
+ export const useReferences = (id: () => number): Accessor<ReferenceRow[]> => {
42
+ const project = useProject()
43
+ return createMemo(() => buildReferenceRows(project(), id()))
44
+ }
45
+
46
+ const buildReferenceRows = (project: Types.Project, id: number): ReferenceRow[] => {
47
+ const route = project.routeForId(id)
48
+ if (!route || route.page.kind === 'markdown') return []
49
+
50
+ const seen = new Set<number>()
51
+ const out: ReferenceRow[] = []
52
+ for (const refId of route.page.referencedIn) {
53
+ if (refId === id || seen.has(refId)) continue
54
+ seen.add(refId)
55
+ const refRoute = project.routeForId(refId)
56
+ const decl = project.byId(refId)
57
+ if (!refRoute || refRoute.page.kind === 'markdown' || !decl) continue
58
+ const qualified = refRoute.page.qualified
59
+ const dot = qualified.lastIndexOf('.')
60
+ out.push({
61
+ decl,
62
+ slug: refRoute.slug,
63
+ module: dot < 0 ? '' : qualified.slice(0, dot),
64
+ name: dot < 0 ? qualified : qualified.slice(dot + 1),
65
+ qualified,
66
+ summary: commentSummaryText(decl.comment),
67
+ })
68
+ }
69
+ return out.sort((a, b) => a.qualified.localeCompare(b.qualified))
70
+ }
71
+
72
+ // ============================================================================
73
+ // SEARCH
74
+ // `createSearchEngine` is async (Orama indexing). Cached per project so the
75
+ // palette pays the cost once per session, even if it opens and closes.
76
+ // ============================================================================
77
+
78
+ const searchCache = new WeakMap<object, Promise<SearchEngine>>()
79
+
80
+ /**
81
+ * Returns a thunk that builds (or returns the cached) search engine for the
82
+ * current project. Callers wrap the thunk in their own resource/effect.
83
+ */
84
+ export const useSearch = (): (() => Promise<SearchEngine>) => {
85
+ const project = useProject()
86
+ return () => buildSearch(project())
87
+ }
88
+
89
+ const buildSearch = (project: Types.Project): Promise<SearchEngine> => {
90
+ const cached = searchCache.get(project)
91
+ if (cached) return cached
92
+ const p = createSearchEngine(project)
93
+ searchCache.set(project, p)
94
+ return p
95
+ }
96
+
97
+ export const useCommentMarkdown = (comment: () => Types.Comment) => {
98
+ const slugs = useSlugFor()
99
+ const slugOf = (name: string) => slugs.byName(name)
100
+ return createMemo(() => commentToMarkdown(comment(), slugOf))
101
+ }
102
+
103
+ const commentToMarkdown = (comment: Types.Comment, slugOf: (name: string) => string | undefined): string => {
104
+ let out = ''
105
+ for (const p of comment.parts) {
106
+ if (p.kind === 'text') {
107
+ out += p.text
108
+ continue
109
+ }
110
+ const label = p.text ?? p.target
111
+ const slug = slugOf(p.target)
112
+ const display = p.style === 'code' ? `\`${label}\`` : label
113
+ out += slug ? `[${display}](/${slug})` : display
114
+ }
115
+ return out
116
+ }
@@ -0,0 +1,4 @@
1
+ export * from './components/index.ts'
2
+ export * from './context/index.ts'
3
+ export * from './renderer.tsx'
4
+ export * from './App.tsx'
@@ -0,0 +1,31 @@
1
+ import { createMemo, type Accessor } from 'solid-js'
2
+ import { render } from 'solid-js/web'
3
+
4
+ import type { Components } from './context/components.tsx'
5
+ import { App } from './App.tsx'
6
+
7
+ import { getJson, getComponents, setComponents } from './context/global.ts'
8
+ import type { Types } from './context/index.ts'
9
+
10
+ export const renderApp = (props?: {
11
+ json?: Accessor<Types.ProjectJson | null> | Types.ProjectJson | null
12
+ components?: Accessor<Components> | Components
13
+ root?: HTMLElement
14
+ }) => {
15
+ const json = createMemo(() => {
16
+ const j = typeof props?.json === 'function' ? props?.json() : (props?.json ?? null)
17
+ if (!j) return getJson()
18
+ return j
19
+ })
20
+
21
+ const components = createMemo(() => {
22
+ const c = typeof props?.components === 'function' ? props?.components() : (props?.components ?? null)
23
+ if (!c) return getComponents()
24
+ return c
25
+ })
26
+
27
+ render(() => <App json={json} components={components} />, props?.root ?? document.getElementById('root')!)
28
+ }
29
+
30
+ export const registerComponent = <K extends keyof Components>(key: K, Component: Components[K]) =>
31
+ setComponents({ [key]: Component })
@@ -0,0 +1,12 @@
1
+ import type { Types } from '../context/index.ts'
2
+
3
+ /** Single-line plain-text preview of a comment. Used by listings/cards. */
4
+ export const commentSummaryText = (comment: Types.Comment | undefined): string => {
5
+ if (!comment) return ''
6
+ let out = ''
7
+ for (const p of comment.parts) {
8
+ if (p.kind === 'text') out += p.text
9
+ else out += p.text ?? p.target
10
+ }
11
+ return out.trim()
12
+ }