@rocket/js 0.0.0 → 0.1.0

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 (340) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -2
  3. package/dist-types/exports/MainMenu.d.ts +2 -0
  4. package/dist-types/exports/MainMenu.d.ts.map +1 -0
  5. package/dist-types/exports/PageData.d.ts +2 -0
  6. package/dist-types/exports/PageData.d.ts.map +1 -0
  7. package/dist-types/exports/RocketCodeBlock.d.ts +2 -0
  8. package/dist-types/exports/RocketCodeBlock.d.ts.map +1 -0
  9. package/dist-types/exports/RocketIcon.d.ts +2 -0
  10. package/dist-types/exports/RocketIcon.d.ts.map +1 -0
  11. package/dist-types/exports/RocketJsDemo.d.ts +2 -0
  12. package/dist-types/exports/RocketJsDemo.d.ts.map +1 -0
  13. package/dist-types/exports/RocketRequestDemo.d.ts +2 -0
  14. package/dist-types/exports/RocketRequestDemo.d.ts.map +1 -0
  15. package/dist-types/exports/SocialPreviewPlayground.d.ts +2 -0
  16. package/dist-types/exports/SocialPreviewPlayground.d.ts.map +1 -0
  17. package/dist-types/exports/adapters/netlify.d.ts +2 -0
  18. package/dist-types/exports/adapters/netlify.d.ts.map +1 -0
  19. package/dist-types/exports/asyncMessage.d.ts +2 -0
  20. package/dist-types/exports/asyncMessage.d.ts.map +1 -0
  21. package/dist-types/exports/component-hydration.d.ts +2 -0
  22. package/dist-types/exports/component-hydration.d.ts.map +1 -0
  23. package/dist-types/exports/components/web-awesome.d.ts +3 -0
  24. package/dist-types/exports/components/web-awesome.d.ts.map +1 -0
  25. package/dist-types/exports/components.d.ts +2 -0
  26. package/dist-types/exports/components.d.ts.map +1 -0
  27. package/dist-types/exports/config.d.ts +2 -0
  28. package/dist-types/exports/config.d.ts.map +1 -0
  29. package/dist-types/exports/debounce.d.ts +2 -0
  30. package/dist-types/exports/debounce.d.ts.map +1 -0
  31. package/dist-types/exports/define/RocketCodeBlock.d.ts +2 -0
  32. package/dist-types/exports/define/RocketCodeBlock.d.ts.map +1 -0
  33. package/dist-types/exports/define/RocketIcon.d.ts +2 -0
  34. package/dist-types/exports/define/RocketIcon.d.ts.map +1 -0
  35. package/dist-types/exports/define/RocketJsDemo.d.ts +2 -0
  36. package/dist-types/exports/define/RocketJsDemo.d.ts.map +1 -0
  37. package/dist-types/exports/define/RocketRequestDemo.d.ts +2 -0
  38. package/dist-types/exports/define/RocketRequestDemo.d.ts.map +1 -0
  39. package/dist-types/exports/define/menus.d.ts +2 -0
  40. package/dist-types/exports/define/menus.d.ts.map +1 -0
  41. package/dist-types/exports/extractCode.d.ts +2 -0
  42. package/dist-types/exports/extractCode.d.ts.map +1 -0
  43. package/dist-types/exports/globalData.d.ts +2 -0
  44. package/dist-types/exports/globalData.d.ts.map +1 -0
  45. package/dist-types/exports/hydration/hydrationLoader.d.ts +2 -0
  46. package/dist-types/exports/hydration/hydrationLoader.d.ts.map +1 -0
  47. package/dist-types/exports/icons.d.ts +2 -0
  48. package/dist-types/exports/icons.d.ts.map +1 -0
  49. package/dist-types/exports/layout-helper.d.ts +2 -0
  50. package/dist-types/exports/layout-helper.d.ts.map +1 -0
  51. package/dist-types/exports/layout.d.ts +2 -0
  52. package/dist-types/exports/layout.d.ts.map +1 -0
  53. package/dist-types/exports/layouts/atlasDoc.d.ts +2 -0
  54. package/dist-types/exports/layouts/atlasDoc.d.ts.map +1 -0
  55. package/dist-types/exports/layouts/atlasHero.d.ts +2 -0
  56. package/dist-types/exports/layouts/atlasHero.d.ts.map +1 -0
  57. package/dist-types/exports/layouts/atlasNotFound.d.ts +2 -0
  58. package/dist-types/exports/layouts/atlasNotFound.d.ts.map +1 -0
  59. package/dist-types/exports/loaded-page-module.d.ts +2 -0
  60. package/dist-types/exports/loaded-page-module.d.ts.map +1 -0
  61. package/dist-types/exports/markdownHook.d.ts +2 -0
  62. package/dist-types/exports/markdownHook.d.ts.map +1 -0
  63. package/dist-types/exports/menu.d.ts +2 -0
  64. package/dist-types/exports/menu.d.ts.map +1 -0
  65. package/dist-types/exports/menus.d.ts +6 -0
  66. package/dist-types/exports/menus.d.ts.map +1 -0
  67. package/dist-types/exports/page-runtime.d.ts +2 -0
  68. package/dist-types/exports/page-runtime.d.ts.map +1 -0
  69. package/dist-types/exports/pages.d.ts +2 -0
  70. package/dist-types/exports/pages.d.ts.map +1 -0
  71. package/dist-types/exports/resolve.d.ts +2 -0
  72. package/dist-types/exports/resolve.d.ts.map +1 -0
  73. package/dist-types/exports/ssr.d.ts +2 -0
  74. package/dist-types/exports/ssr.d.ts.map +1 -0
  75. package/dist-types/exports/standalone-demo-url.d.ts +2 -0
  76. package/dist-types/exports/standalone-demo-url.d.ts.map +1 -0
  77. package/dist-types/exports/transform.d.ts +2 -0
  78. package/dist-types/exports/transform.d.ts.map +1 -0
  79. package/dist-types/exports/types/hydration.d.ts +23 -0
  80. package/dist-types/exports/types/hydration.d.ts.map +1 -0
  81. package/dist-types/exports/types/rocket.d.ts +504 -0
  82. package/dist-types/exports/types/rocket.d.ts.map +1 -0
  83. package/dist-types/exports/types.d.ts +3 -0
  84. package/dist-types/exports/types.d.ts.map +1 -0
  85. package/dist-types/exports/wds-plugin.d.ts +2 -0
  86. package/dist-types/exports/wds-plugin.d.ts.map +1 -0
  87. package/dist-types/src/PageData.d.ts +82 -0
  88. package/dist-types/src/PageData.d.ts.map +1 -0
  89. package/dist-types/src/RocketCodeBlock.d.ts +64 -0
  90. package/dist-types/src/RocketCodeBlock.d.ts.map +1 -0
  91. package/dist-types/src/RocketIcon.d.ts +35 -0
  92. package/dist-types/src/RocketIcon.d.ts.map +1 -0
  93. package/dist-types/src/RocketJsDemo.d.ts +59 -0
  94. package/dist-types/src/RocketJsDemo.d.ts.map +1 -0
  95. package/dist-types/src/RocketJsDemo.test-browser.d.ts +3 -0
  96. package/dist-types/src/RocketJsDemo.test-browser.d.ts.map +1 -0
  97. package/dist-types/src/RocketRequestDemo.d.ts +57 -0
  98. package/dist-types/src/RocketRequestDemo.d.ts.map +1 -0
  99. package/dist-types/src/RocketRequestDemo.test-browser.d.ts +3 -0
  100. package/dist-types/src/RocketRequestDemo.test-browser.d.ts.map +1 -0
  101. package/dist-types/src/SocialPreviewPlayground.d.ts +102 -0
  102. package/dist-types/src/SocialPreviewPlayground.d.ts.map +1 -0
  103. package/dist-types/src/adapters/netlify.d.ts +54 -0
  104. package/dist-types/src/adapters/netlify.d.ts.map +1 -0
  105. package/dist-types/src/asyncMessage.d.ts +14 -0
  106. package/dist-types/src/asyncMessage.d.ts.map +1 -0
  107. package/dist-types/src/cli/RocketBuild.d.ts +78 -0
  108. package/dist-types/src/cli/RocketBuild.d.ts.map +1 -0
  109. package/dist-types/src/cli/RocketCli.d.ts +17 -0
  110. package/dist-types/src/cli/RocketCli.d.ts.map +1 -0
  111. package/dist-types/src/cli/RocketInit.d.ts +22 -0
  112. package/dist-types/src/cli/RocketInit.d.ts.map +1 -0
  113. package/dist-types/src/cli/RocketStart.d.ts +13 -0
  114. package/dist-types/src/cli/RocketStart.d.ts.map +1 -0
  115. package/dist-types/src/cli/cli.d.ts +3 -0
  116. package/dist-types/src/cli/cli.d.ts.map +1 -0
  117. package/dist-types/src/component-hydration.d.ts +26 -0
  118. package/dist-types/src/component-hydration.d.ts.map +1 -0
  119. package/dist-types/src/components/FeatureList.d.ts +15 -0
  120. package/dist-types/src/components/FeatureList.d.ts.map +1 -0
  121. package/dist-types/src/components/Footer.d.ts +17 -0
  122. package/dist-types/src/components/Footer.d.ts.map +1 -0
  123. package/dist-types/src/components/Header.d.ts +6 -0
  124. package/dist-types/src/components/Header.d.ts.map +1 -0
  125. package/dist-types/src/components/RocketDrawer.d.ts +20 -0
  126. package/dist-types/src/components/RocketDrawer.d.ts.map +1 -0
  127. package/dist-types/src/components/RocketSocialLink.d.ts +30 -0
  128. package/dist-types/src/components/RocketSocialLink.d.ts.map +1 -0
  129. package/dist-types/src/components.d.ts +5 -0
  130. package/dist-types/src/components.d.ts.map +1 -0
  131. package/dist-types/src/config.d.ts +6 -0
  132. package/dist-types/src/config.d.ts.map +1 -0
  133. package/dist-types/src/debounce.d.ts +8 -0
  134. package/dist-types/src/debounce.d.ts.map +1 -0
  135. package/dist-types/src/defaultSocialPreviewTemplate.d.ts +31 -0
  136. package/dist-types/src/defaultSocialPreviewTemplate.d.ts.map +1 -0
  137. package/dist-types/src/development-page-module-loader.d.ts +15 -0
  138. package/dist-types/src/development-page-module-loader.d.ts.map +1 -0
  139. package/dist-types/src/extractCode.d.ts +5 -0
  140. package/dist-types/src/extractCode.d.ts.map +1 -0
  141. package/dist-types/src/hydration/evaluate.d.ts +20 -0
  142. package/dist-types/src/hydration/evaluate.d.ts.map +1 -0
  143. package/dist-types/src/hydration/extractStrategies.d.ts +5 -0
  144. package/dist-types/src/hydration/extractStrategies.d.ts.map +1 -0
  145. package/dist-types/src/hydration/hydrationLoader.d.ts +64 -0
  146. package/dist-types/src/hydration/hydrationLoader.d.ts.map +1 -0
  147. package/dist-types/src/icons.d.ts +170 -0
  148. package/dist-types/src/icons.d.ts.map +1 -0
  149. package/dist-types/src/layouts/atlas/atlasDocLayout.d.ts +45 -0
  150. package/dist-types/src/layouts/atlas/atlasDocLayout.d.ts.map +1 -0
  151. package/dist-types/src/layouts/atlas/atlasHeroLayout.d.ts +7 -0
  152. package/dist-types/src/layouts/atlas/atlasHeroLayout.d.ts.map +1 -0
  153. package/dist-types/src/layouts/atlas/atlasNotFoundLayout.d.ts +5 -0
  154. package/dist-types/src/layouts/atlas/atlasNotFoundLayout.d.ts.map +1 -0
  155. package/dist-types/src/layouts/layout-helper.d.ts +16 -0
  156. package/dist-types/src/layouts/layout-helper.d.ts.map +1 -0
  157. package/dist-types/src/layouts/layout.d.ts +9 -0
  158. package/dist-types/src/layouts/layout.d.ts.map +1 -0
  159. package/dist-types/src/loaded-page-module.d.ts +51 -0
  160. package/dist-types/src/loaded-page-module.d.ts.map +1 -0
  161. package/dist-types/src/main.d.ts +2 -0
  162. package/dist-types/src/main.d.ts.map +1 -0
  163. package/dist-types/src/markdownCompiler.d.ts +22 -0
  164. package/dist-types/src/markdownCompiler.d.ts.map +1 -0
  165. package/dist-types/src/markdownHook.d.ts +6 -0
  166. package/dist-types/src/markdownHook.d.ts.map +1 -0
  167. package/dist-types/src/menu.d.ts +22 -0
  168. package/dist-types/src/menu.d.ts.map +1 -0
  169. package/dist-types/src/menus/MainMenu.d.ts +23 -0
  170. package/dist-types/src/menus/MainMenu.d.ts.map +1 -0
  171. package/dist-types/src/menus/RocketMenu.d.ts +23 -0
  172. package/dist-types/src/menus/RocketMenu.d.ts.map +1 -0
  173. package/dist-types/src/menus/RocketNextPage.d.ts +18 -0
  174. package/dist-types/src/menus/RocketNextPage.d.ts.map +1 -0
  175. package/dist-types/src/menus/RocketPreviousPage.d.ts +18 -0
  176. package/dist-types/src/menus/RocketPreviousPage.d.ts.map +1 -0
  177. package/dist-types/src/menus/RocketToc.d.ts +54 -0
  178. package/dist-types/src/menus/RocketToc.d.ts.map +1 -0
  179. package/dist-types/src/menus/pageNavigation.d.ts +41 -0
  180. package/dist-types/src/menus/pageNavigation.d.ts.map +1 -0
  181. package/dist-types/src/page-pagination.d.ts +69 -0
  182. package/dist-types/src/page-pagination.d.ts.map +1 -0
  183. package/dist-types/src/page-runtime.d.ts +110 -0
  184. package/dist-types/src/page-runtime.d.ts.map +1 -0
  185. package/dist-types/src/pages.d.ts +10 -0
  186. package/dist-types/src/pages.d.ts.map +1 -0
  187. package/dist-types/src/publicAssets.d.ts +70 -0
  188. package/dist-types/src/publicAssets.d.ts.map +1 -0
  189. package/dist-types/src/requestDemoMetadata.d.ts +19 -0
  190. package/dist-types/src/requestDemoMetadata.d.ts.map +1 -0
  191. package/dist-types/src/resolve.d.ts +7 -0
  192. package/dist-types/src/resolve.d.ts.map +1 -0
  193. package/dist-types/src/siteDiscoverability.d.ts +33 -0
  194. package/dist-types/src/siteDiscoverability.d.ts.map +1 -0
  195. package/dist-types/src/siteHeadMetadata.d.ts +20 -0
  196. package/dist-types/src/siteHeadMetadata.d.ts.map +1 -0
  197. package/dist-types/src/socialPreviewImages.d.ts +186 -0
  198. package/dist-types/src/socialPreviewImages.d.ts.map +1 -0
  199. package/dist-types/src/socialPreviewTemplatePreview.d.ts +22 -0
  200. package/dist-types/src/socialPreviewTemplatePreview.d.ts.map +1 -0
  201. package/dist-types/src/ssr.d.ts +6 -0
  202. package/dist-types/src/ssr.d.ts.map +1 -0
  203. package/dist-types/src/standalone-demo-url.d.ts +60 -0
  204. package/dist-types/src/standalone-demo-url.d.ts.map +1 -0
  205. package/dist-types/src/static-page-module-loader.d.ts +15 -0
  206. package/dist-types/src/static-page-module-loader.d.ts.map +1 -0
  207. package/dist-types/src/transform.d.ts +10 -0
  208. package/dist-types/src/transform.d.ts.map +1 -0
  209. package/dist-types/src/urlLifecycle.d.ts +23 -0
  210. package/dist-types/src/urlLifecycle.d.ts.map +1 -0
  211. package/dist-types/src/wds-plugin.d.ts +14 -0
  212. package/dist-types/src/wds-plugin.d.ts.map +1 -0
  213. package/docs/assets/home-background.svg +1 -0
  214. package/docs/assets/prism-one-light.css +368 -0
  215. package/docs/assets/rocket-logo-dark-with-text-below.svg +8 -0
  216. package/docs/assets/rocket-logo-dark-with-text.svg +7 -0
  217. package/docs/assets/rocket-logo-dark.svg +7 -0
  218. package/docs/assets/rocket-logo-light-with-text-below.svg +14 -0
  219. package/docs/assets/rocket-logo-light-with-text.svg +13 -0
  220. package/docs/assets/rocket-logo-light.svg +12 -0
  221. package/docs/assets/rocket-text-no-logo.svg +3 -0
  222. package/exports/MainMenu.js +1 -0
  223. package/exports/PageData.js +1 -0
  224. package/exports/RocketCodeBlock.js +1 -0
  225. package/exports/RocketIcon.js +1 -0
  226. package/exports/RocketJsDemo.js +1 -0
  227. package/exports/RocketRequestDemo.js +1 -0
  228. package/exports/SocialPreviewPlayground.js +1 -0
  229. package/exports/adapters/netlify.js +1 -0
  230. package/exports/asyncMessage.js +1 -0
  231. package/exports/component-hydration.js +1 -0
  232. package/exports/components/web-awesome.js +63 -0
  233. package/exports/components.js +1 -0
  234. package/exports/config.js +1 -0
  235. package/exports/debounce.js +1 -0
  236. package/exports/define/RocketCodeBlock.js +2 -0
  237. package/exports/define/RocketIcon.js +3 -0
  238. package/exports/define/RocketJsDemo.js +5 -0
  239. package/exports/define/RocketRequestDemo.js +5 -0
  240. package/exports/define/menus.js +14 -0
  241. package/exports/extractCode.js +1 -0
  242. package/exports/globalData.js +1 -0
  243. package/exports/hydration/hydrationLoader.js +1 -0
  244. package/exports/icons.js +8 -0
  245. package/exports/layout-helper.js +1 -0
  246. package/exports/layout.js +1 -0
  247. package/exports/layouts/_atlas.css +3 -0
  248. package/exports/layouts/atlasDoc.js +5 -0
  249. package/exports/layouts/atlasHero.js +1 -0
  250. package/exports/layouts/atlasNotFound.js +4 -0
  251. package/exports/loaded-page-module.js +5 -0
  252. package/exports/markdownHook.js +4 -0
  253. package/exports/menu.js +4 -0
  254. package/exports/menus.js +5 -0
  255. package/exports/page-runtime.js +5 -0
  256. package/exports/pages.js +1 -0
  257. package/exports/resolve.js +1 -0
  258. package/exports/ssr.js +1 -0
  259. package/exports/standalone-demo-url.js +10 -0
  260. package/exports/transform.js +1 -0
  261. package/exports/types/hydration.ts +26 -0
  262. package/exports/types/rocket.ts +598 -0
  263. package/exports/types.ts +71 -0
  264. package/exports/wds-plugin.js +1 -0
  265. package/package.json +192 -9
  266. package/src/PageData.js +244 -0
  267. package/src/RocketCodeBlock.js +516 -0
  268. package/src/RocketIcon.js +291 -0
  269. package/src/RocketJsDemo.js +397 -0
  270. package/src/RocketJsDemo.test-browser.js +228 -0
  271. package/src/RocketRequestDemo.js +439 -0
  272. package/src/RocketRequestDemo.test-browser.js +301 -0
  273. package/src/SocialPreviewPlayground.js +573 -0
  274. package/src/adapters/netlify.js +814 -0
  275. package/src/asyncMessage.js +21 -0
  276. package/src/cli/RocketBuild.js +545 -0
  277. package/src/cli/RocketCli.js +47 -0
  278. package/src/cli/RocketInit.js +323 -0
  279. package/src/cli/RocketStart.js +79 -0
  280. package/src/cli/cli.js +7 -0
  281. package/src/component-hydration.js +86 -0
  282. package/src/components/FeatureList.js +114 -0
  283. package/src/components/Footer.js +116 -0
  284. package/src/components/Header.js +122 -0
  285. package/src/components/RocketDrawer.js +193 -0
  286. package/src/components/RocketSocialLink.js +128 -0
  287. package/src/components/assets/discord.svg +7 -0
  288. package/src/components/assets/github.svg +4 -0
  289. package/src/components/assets/gitlab.svg +1 -0
  290. package/src/components/assets/info.txt +1 -0
  291. package/src/components/assets/license.svg +3 -0
  292. package/src/components/assets/npm.svg +5 -0
  293. package/src/components/assets/slack.svg +5 -0
  294. package/src/components/assets/telegram.svg +4 -0
  295. package/src/components/assets/twitter.svg +1 -0
  296. package/src/components.js +15 -0
  297. package/src/config.js +319 -0
  298. package/src/debounce.js +21 -0
  299. package/src/defaultSocialPreviewTemplate.js +118 -0
  300. package/src/development-page-module-loader.js +29 -0
  301. package/src/extractCode.js +41 -0
  302. package/src/hydration/evaluate.js +54 -0
  303. package/src/hydration/extractStrategies.js +91 -0
  304. package/src/hydration/hydrationLoader.js +330 -0
  305. package/src/icons.js +883 -0
  306. package/src/layouts/atlas/atlasDoc.css +877 -0
  307. package/src/layouts/atlas/atlasDocLayout.js +288 -0
  308. package/src/layouts/atlas/atlasHero.css +774 -0
  309. package/src/layouts/atlas/atlasHeroLayout.js +346 -0
  310. package/src/layouts/atlas/atlasNotFound.css +365 -0
  311. package/src/layouts/atlas/atlasNotFoundLayout.js +69 -0
  312. package/src/layouts/layout-helper.js +92 -0
  313. package/src/layouts/layout.js +62 -0
  314. package/src/loaded-page-module.js +97 -0
  315. package/src/main.js +55 -0
  316. package/src/markdownCompiler.js +303 -0
  317. package/src/markdownHook.js +148 -0
  318. package/src/menu.js +210 -0
  319. package/src/menus/MainMenu.js +58 -0
  320. package/src/menus/RocketMenu.js +191 -0
  321. package/src/menus/RocketNextPage.js +25 -0
  322. package/src/menus/RocketPreviousPage.js +29 -0
  323. package/src/menus/RocketToc.js +309 -0
  324. package/src/menus/pageNavigation.js +285 -0
  325. package/src/page-pagination.js +241 -0
  326. package/src/page-runtime.js +481 -0
  327. package/src/pages.js +537 -0
  328. package/src/publicAssets.js +336 -0
  329. package/src/requestDemoMetadata.js +97 -0
  330. package/src/resolve.js +15 -0
  331. package/src/siteDiscoverability.js +184 -0
  332. package/src/siteHeadMetadata.js +69 -0
  333. package/src/socialPreviewImages.js +482 -0
  334. package/src/socialPreviewTemplatePreview.js +352 -0
  335. package/src/ssr.js +14 -0
  336. package/src/standalone-demo-url.js +134 -0
  337. package/src/static-page-module-loader.js +29 -0
  338. package/src/transform.js +633 -0
  339. package/src/urlLifecycle.js +57 -0
  340. package/src/wds-plugin.js +302 -0
@@ -0,0 +1,21 @@
1
+ /** @typedef {import('node:worker_threads').MessagePort} MessagePort */
2
+ /** @typedef {MessagePort & {sendAndWait: (message: any) => any; _wait: PromiseWithResolvers<any>}} AsyncPort */
3
+
4
+ /**
5
+ * Turns a MessagePort into an AsyncPort, which can wait for responses.
6
+ * @param {MessagePort} port
7
+ * @returns {AsyncPort}
8
+ */
9
+ export function makeAsyncPort(port) {
10
+ const p = /** @type {AsyncPort} */ (port);
11
+ p._wait = Promise.withResolvers();
12
+ p.on('message', message => {
13
+ p._wait.resolve(message);
14
+ p._wait = Promise.withResolvers();
15
+ });
16
+ p.sendAndWait = async message => {
17
+ p.postMessage(message);
18
+ return p._wait;
19
+ };
20
+ return p;
21
+ }
@@ -0,0 +1,545 @@
1
+ import { getPages } from '../pages.js';
2
+ import { copyFileSync, existsSync, globSync, mkdirSync, rmSync, statSync, writeFileSync } from 'fs';
3
+ import { register } from 'node:module';
4
+ import { MessageChannel } from 'node:worker_threads';
5
+ import { build } from 'vite';
6
+ import path from 'node:path';
7
+ import { PageRuntime } from '../page-runtime.js';
8
+ import { createIconAssetStore, rocketIconRuntimeOutputs } from '../icons.js';
9
+ import { paginatedArchivePaths } from '../page-pagination.js';
10
+ import { createStaticPageModuleLoader } from '../static-page-module-loader.js';
11
+ import { writeSiteDiscoverabilityOutputs } from '../siteDiscoverability.js';
12
+ import { normalizeDocumentPath, standaloneDemoPaths } from '../standalone-demo-url.js';
13
+ import {
14
+ assertPublicAssetsOutputDir,
15
+ copyPublicAssets,
16
+ discoverPublicAssets,
17
+ validatePublicAssetCollisions,
18
+ } from '../publicAssets.js';
19
+ import {
20
+ validateUrlLifecycleGeneratedOutputCollisions,
21
+ validateUrlLifecyclePageCollisions,
22
+ } from '../urlLifecycle.js';
23
+ import {
24
+ captureSocialPreviewImageWithBrowser,
25
+ generateStaticDefaultSocialPreviewImages,
26
+ publicSocialPreviewPages,
27
+ } from '../socialPreviewImages.js';
28
+
29
+ export class RocketBuild {
30
+ /**
31
+ * @type {((options: {
32
+ * html: string;
33
+ * width: number;
34
+ * height: number;
35
+ * pathname: string;
36
+ * }) => Promise<Uint8Array> | Uint8Array) | undefined}
37
+ */
38
+ socialPreviewCapture;
39
+
40
+ /**
41
+ * @param {import('commander').Command} program
42
+ * @param {import('./RocketCli.js').RocketCli} cli
43
+ */
44
+ async setupCommand(program, cli) {
45
+ this.cli = cli;
46
+
47
+ program
48
+ .command('build')
49
+ .option('-o, --output-dir <path>', 'Path where to output built files')
50
+ .action(async ({ outputDir }) => {
51
+ if (outputDir) {
52
+ this.outputDir = outputDir;
53
+ }
54
+ await this.build();
55
+ });
56
+ }
57
+
58
+ async build() {
59
+ await this.cli?.getConfig?.();
60
+ if (!this.cli?.config) {
61
+ throw new Error('Missing Config');
62
+ }
63
+
64
+ const { port1 } = new MessageChannel();
65
+
66
+ // register must be AFTER the config is read
67
+ register('../markdownHook.js', {
68
+ parentURL: import.meta.url,
69
+ data: { port: port1 },
70
+ transferList: [port1],
71
+ });
72
+
73
+ process.env.ENVIRONMENT = 'BUILD';
74
+
75
+ const pages = await getPages(
76
+ process.cwd(),
77
+ this.cli.config.includeGlobs,
78
+ this.cli.config.excludeRegex,
79
+ );
80
+ validateUrlLifecyclePageCollisions({
81
+ redirects: this.cli.config.urlLifecycle?.redirects,
82
+ pages,
83
+ });
84
+ const { staticPages, serverPages } = splitPages(pages);
85
+ if (serverPages.size && !this.cli.config.adapter) {
86
+ throw new Error(
87
+ `${serverPages.size} page(s) use config.render = 'server', but no adapter is configured`,
88
+ );
89
+ }
90
+ const publicAssets = discoverPublicAssets(process.cwd());
91
+ validatePublicAssetCollisions({
92
+ publicAssets,
93
+ pages,
94
+ generatedPages: staticPages,
95
+ config: this.cli.config,
96
+ emitRedirectFallbacks: !this.cli.config.adapter,
97
+ });
98
+ const outDir = this.outputDir ? path.resolve(this.outputDir) : path.resolve('dist');
99
+ assertPublicAssetsOutputDir({ projectRoot: process.cwd(), outDir });
100
+
101
+ try {
102
+ if (existsSync('tmp-dist-rocket')) {
103
+ rmSync('tmp-dist-rocket', { recursive: true });
104
+ }
105
+
106
+ const { defaultSocialPreviewImages } = await renderStaticPages({
107
+ pages,
108
+ staticPages,
109
+ urlLifecycle: this.cli.config.urlLifecycle,
110
+ siteHeadMetadata: this.cli.config.siteHeadMetadata,
111
+ siteOrigin: this.cli.config.siteOrigin,
112
+ iconLibraries: this.cli.config.iconLibraries,
113
+ defaultIconLibrary: this.cli.config.defaultIconLibrary,
114
+ socialPreviewCacheDirectory: path.resolve('.rocket/social-preview-images'),
115
+ captureSocialPreviewImage: this.socialPreviewCapture,
116
+ emitRedirectFallbacks: !this.cli.config.adapter,
117
+ });
118
+
119
+ const entries = existsSync('tmp-dist-rocket')
120
+ ? globSync('**/*.html', { cwd: 'tmp-dist-rocket' }).map(p =>
121
+ path.resolve('tmp-dist-rocket', p),
122
+ )
123
+ : [];
124
+
125
+ if (entries.length) {
126
+ await build({
127
+ configFile: false,
128
+ root: 'tmp-dist-rocket',
129
+ build: {
130
+ outDir,
131
+ target: 'esnext',
132
+ emptyOutDir: true,
133
+ manifest: true,
134
+ rollupOptions: {
135
+ external: [/^\/assets\//, /^\/_rocket\//, '/src/components/RocketDrawer.js'],
136
+ input: entries,
137
+ },
138
+ },
139
+ });
140
+ } else {
141
+ clearExistingOutputDir(outDir);
142
+ mkdirSync(outDir, { recursive: true });
143
+ }
144
+
145
+ copyStaticFileOutputs(outDir);
146
+ writeSiteDiscoverabilityOutputs({ pages, outDir, config: this.cli.config });
147
+
148
+ if (this.cli.config.adapter) {
149
+ await this.cli.config.adapter.build({
150
+ pages,
151
+ staticPages,
152
+ serverPages,
153
+ outDir,
154
+ projectRoot: process.cwd(),
155
+ config: this.cli.config,
156
+ defaultSocialPreviewImages,
157
+ });
158
+ }
159
+
160
+ copyPublicAssets({ publicAssets, outDir });
161
+ } finally {
162
+ if (existsSync('tmp-dist-rocket')) {
163
+ rmSync('tmp-dist-rocket', { recursive: true });
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * @param {import('@rocket/js/types.js').PageRegistry} pages
171
+ * @returns {{ staticPages: import('@rocket/js/types.js').PageRegistry; serverPages: import('@rocket/js/types.js').PageRegistry }}
172
+ */
173
+ export function splitPages(pages) {
174
+ /** @type {import('@rocket/js/types.js').PageRegistry} */
175
+ const staticPages = new Map();
176
+ /** @type {import('@rocket/js/types.js').PageRegistry} */
177
+ const serverPages = new Map();
178
+ for (const [pagePath, page] of pages) {
179
+ const renderMode = page.module.config.render || 'static';
180
+ if (renderMode === 'server') {
181
+ serverPages.set(pagePath, page);
182
+ } else if (renderMode === 'static') {
183
+ staticPages.set(pagePath, page);
184
+ } else {
185
+ throw new Error(
186
+ `Invalid render mode ${JSON.stringify(renderMode)} for page ${page.file}. ` +
187
+ `Expected "static" or "server".`,
188
+ );
189
+ }
190
+ }
191
+ return { staticPages, serverPages };
192
+ }
193
+
194
+ /**
195
+ * @param {{
196
+ * pages: import('@rocket/js/types.js').PageRegistry;
197
+ * staticPages: import('@rocket/js/types.js').PageRegistry;
198
+ * pageModuleLoader?: import('../page-runtime.js').PageModuleLoader;
199
+ * origin?: string;
200
+ * urlLifecycle?: import('@rocket/js/types.js').UrlLifecycleConfig;
201
+ * siteHeadMetadata?: import('@rocket/js/types.js').SiteHeadMetadataConfig;
202
+ * siteOrigin?: string;
203
+ * iconLibraries?: import('@rocket/js/types.js').IconLibrariesConfig;
204
+ * defaultIconLibrary?: string;
205
+ * iconAssetStore?: import('../icons.js').IconAssetStore;
206
+ * socialPreviewCacheDirectory?: string;
207
+ * captureSocialPreviewImage?: (options: {
208
+ * html: string;
209
+ * width: number;
210
+ * height: number;
211
+ * pathname: string;
212
+ * }) => Promise<Uint8Array> | Uint8Array;
213
+ * emitRedirectFallbacks?: boolean;
214
+ * }} options
215
+ * @returns {Promise<{ defaultSocialPreviewImages: Map<string, string> }>}
216
+ */
217
+ export async function renderStaticPages({
218
+ pages,
219
+ staticPages,
220
+ pageModuleLoader = createStaticPageModuleLoader(),
221
+ origin = 'http://localhost',
222
+ urlLifecycle,
223
+ siteHeadMetadata,
224
+ siteOrigin,
225
+ iconLibraries,
226
+ defaultIconLibrary,
227
+ iconAssetStore = createIconAssetStore(),
228
+ socialPreviewCacheDirectory,
229
+ captureSocialPreviewImage = captureSocialPreviewImageWithBrowser,
230
+ emitRedirectFallbacks = true,
231
+ }) {
232
+ assertStaticJavaScriptPagesHaveConcretePaths(staticPages);
233
+ assertNoStandaloneDemoPathCollisions(pages, staticPages);
234
+ assertNoPaginatedArchivePathCollisions(pages, staticPages);
235
+ validateUrlLifecycleGeneratedOutputCollisions({
236
+ redirects: urlLifecycle?.redirects,
237
+ pages,
238
+ staticPages,
239
+ });
240
+ const socialPreviewPages = publicSocialPreviewPages(pages);
241
+ const defaultSocialPreviewImageOutputs = await generateStaticDefaultSocialPreviewImages({
242
+ pages: socialPreviewPages,
243
+ siteHeadMetadata,
244
+ siteOrigin,
245
+ cacheDirectory: socialPreviewCacheDirectory,
246
+ captureSocialPreviewImage,
247
+ });
248
+ /** @type {Map<string, string>} */
249
+ const defaultSocialPreviewImages = new Map();
250
+ for (const [pagePath, output] of defaultSocialPreviewImageOutputs) {
251
+ defaultSocialPreviewImages.set(pagePath, output.publicUrl);
252
+ }
253
+ for (const output of defaultSocialPreviewImageOutputs.values()) {
254
+ writeFileOutput(output.publicPath, output.data);
255
+ }
256
+ const pageRuntime = new PageRuntime({
257
+ pages,
258
+ pageModuleLoader,
259
+ siteHeadMetadata,
260
+ siteOrigin,
261
+ iconLibraries,
262
+ defaultIconLibrary,
263
+ iconAssetStore,
264
+ defaultSocialPreviewImages,
265
+ });
266
+ for (const [pagePath, page] of staticPages) {
267
+ try {
268
+ const response = await pageRuntime.render(new Request(new URL(pagePath, origin)));
269
+ await writeStaticResponse(pagePath, response);
270
+ for (const archivePath of paginatedArchivePaths({ pages, page, pagePath })) {
271
+ const archiveResponse = await pageRuntime.render(new Request(new URL(archivePath, origin)));
272
+ await writeStaticResponse(archivePath, archiveResponse);
273
+ }
274
+ for (const demoPath of standaloneDemoPaths(pagePath, page)) {
275
+ const demoResponse = await pageRuntime.render(new Request(new URL(demoPath, origin)));
276
+ writeHtml(demoPath, await demoResponse.text());
277
+ }
278
+ } catch (error) {
279
+ throw new Error('Failed to render page: ' + pagePath, { cause: error });
280
+ }
281
+ }
282
+ writeIconAssetOutputs(iconAssetStore);
283
+ if (emitRedirectFallbacks) {
284
+ writeRedirectFallbackFiles(urlLifecycle?.redirects);
285
+ }
286
+ return { defaultSocialPreviewImages };
287
+ }
288
+
289
+ /**
290
+ * @param {import('@rocket/js/types.js').PageRegistry} staticPages
291
+ */
292
+ function assertStaticJavaScriptPagesHaveConcretePaths(staticPages) {
293
+ for (const [pagePath, page] of staticPages) {
294
+ if (!page.file.endsWith('.js') || !hasPathParameter(pagePath)) {
295
+ continue;
296
+ }
297
+ throw new Error(
298
+ `Static JavaScript Page ${pagePath} (${page.file}) cannot be rendered as one static ` +
299
+ `output document because its path is parameterized. Parameterized JavaScript Pages need ` +
300
+ `request-time rendering until Rocket has an API for enumerating static params. Use ` +
301
+ `render: 'server' for this Page today.`,
302
+ );
303
+ }
304
+ }
305
+
306
+ /**
307
+ * @param {string} pagePath
308
+ */
309
+ function hasPathParameter(pagePath) {
310
+ return /(^|\/):[^/]+/.test(pagePath);
311
+ }
312
+
313
+ /**
314
+ * @param {import('@rocket/js/types.js').PageRegistry} pages
315
+ * @param {import('@rocket/js/types.js').PageRegistry} staticPages
316
+ */
317
+ function assertNoStandaloneDemoPathCollisions(pages, staticPages) {
318
+ const configuredPages = configuredPageOutputPaths(pages);
319
+ for (const [pagePath, page] of staticPages) {
320
+ for (const demoPath of standaloneDemoPaths(pagePath, page)) {
321
+ const collision = configuredPages.get(normalizeDocumentPath(demoPath));
322
+ if (collision) {
323
+ throw new Error(
324
+ `Standalone Demo URL ${demoPath} for page ${page.file} collides with configured ` +
325
+ `Page ${collision.page.file} at ${collision.path}`,
326
+ );
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ /**
333
+ * @param {import('@rocket/js/types.js').PageRegistry} pages
334
+ * @param {import('@rocket/js/types.js').PageRegistry} staticPages
335
+ */
336
+ function assertNoPaginatedArchivePathCollisions(pages, staticPages) {
337
+ const configuredPages = configuredPageOutputPaths(pages);
338
+ const standaloneDemoPages = standaloneDemoOutputPaths(staticPages);
339
+ const archivePages = new Map();
340
+ for (const [pagePath, page] of staticPages) {
341
+ for (const archivePath of paginatedArchivePaths({ pages, page, pagePath })) {
342
+ const archiveOutputPath = normalizeDocumentPath(archivePath);
343
+ const collision = configuredPages.get(archiveOutputPath);
344
+ if (collision) {
345
+ throw new Error(
346
+ `Generated archive Page ${archivePath} for page ${page.file} collides with ` +
347
+ `configured Page ${collision.page.file} at ${collision.path}`,
348
+ );
349
+ }
350
+ const archiveCollision = archivePages.get(archiveOutputPath);
351
+ if (archiveCollision) {
352
+ throw new Error(
353
+ `Generated archive Page ${archivePath} for page ${page.file} collides with ` +
354
+ `generated archive Page ${archiveCollision.path} for page ${archiveCollision.page.file}`,
355
+ );
356
+ }
357
+ const standaloneDemoCollision = standaloneDemoPages.get(archiveOutputPath);
358
+ if (standaloneDemoCollision) {
359
+ throw new Error(
360
+ `Generated archive Page ${archivePath} for page ${page.file} collides with ` +
361
+ `Standalone Demo URL ${standaloneDemoCollision.path} for page ${standaloneDemoCollision.page.file}`,
362
+ );
363
+ }
364
+ archivePages.set(archiveOutputPath, { path: archivePath, page });
365
+ }
366
+ }
367
+ }
368
+
369
+ /**
370
+ * @param {import('@rocket/js/types.js').PageRegistry} staticPages
371
+ */
372
+ function standaloneDemoOutputPaths(staticPages) {
373
+ const paths = new Map();
374
+ for (const [pagePath, page] of staticPages) {
375
+ for (const demoPath of standaloneDemoPaths(pagePath, page)) {
376
+ paths.set(normalizeDocumentPath(demoPath), { path: demoPath, page });
377
+ }
378
+ }
379
+ return paths;
380
+ }
381
+
382
+ /**
383
+ * @param {import('@rocket/js/types.js').PageRegistry} pages
384
+ * @returns {Map<string, { path: string; page: import('../page-runtime.js').Page }>}
385
+ */
386
+ function configuredPageOutputPaths(pages) {
387
+ const paths = new Map();
388
+ for (const [pagePath, page] of pages) {
389
+ paths.set(normalizeDocumentPath(pagePath), { path: pagePath, page });
390
+ }
391
+ return paths;
392
+ }
393
+
394
+ /**
395
+ * @param {string} outDir
396
+ */
397
+ function copyStaticFileOutputs(outDir) {
398
+ if (!existsSync('tmp-dist-rocket')) {
399
+ return;
400
+ }
401
+ for (const file of globSync('**/*', { cwd: 'tmp-dist-rocket' })) {
402
+ const source = path.join('tmp-dist-rocket', file);
403
+ if (!statSync(source).isFile() || file.endsWith('.html')) {
404
+ continue;
405
+ }
406
+ const destination = path.join(outDir, file);
407
+ mkdirSync(path.dirname(destination), { recursive: true });
408
+ copyFileSync(source, destination);
409
+ }
410
+ }
411
+
412
+ /**
413
+ * @param {import('../icons.js').IconAssetStore} iconAssetStore
414
+ */
415
+ function writeIconAssetOutputs(iconAssetStore) {
416
+ for (const output of iconAssetStore.outputs()) {
417
+ writeFileOutput(output.url, Buffer.from(output.svg, 'utf8'));
418
+ }
419
+ if (!iconAssetStore.needsRuntime) {
420
+ return;
421
+ }
422
+ for (const output of rocketIconRuntimeOutputs()) {
423
+ writeFileOutput(output.path, Buffer.from(output.data, 'utf8'));
424
+ }
425
+ }
426
+
427
+ /**
428
+ * @param {string} outDir
429
+ */
430
+ function clearExistingOutputDir(outDir) {
431
+ if (!existsSync(outDir)) {
432
+ return;
433
+ }
434
+ const projectRoot = path.resolve(process.cwd());
435
+ const relativeOutDir = path.relative(projectRoot, outDir);
436
+ if (
437
+ relativeOutDir === '' ||
438
+ relativeOutDir.startsWith(`..${path.sep}`) ||
439
+ relativeOutDir === '..' ||
440
+ path.isAbsolute(relativeOutDir)
441
+ ) {
442
+ throw new Error(
443
+ `Invalid build output directory ${outDir}. ` +
444
+ `Rocket can only clear an existing output directory inside the project root.`,
445
+ );
446
+ }
447
+ rmSync(outDir, { recursive: true });
448
+ }
449
+
450
+ /**
451
+ * @param {import('@rocket/js/types.js').RedirectConfig[] | undefined} redirects
452
+ */
453
+ function writeRedirectFallbackFiles(redirects = []) {
454
+ for (const redirect of redirects) {
455
+ const html = redirectFallbackHtml(redirect.target);
456
+ if (isFileOutputPath(redirect.source)) {
457
+ writeFileOutput(redirect.source, Buffer.from(html, 'utf8'));
458
+ continue;
459
+ }
460
+ writeHtml(redirect.source, html);
461
+ }
462
+ }
463
+
464
+ /**
465
+ * @param {string} target
466
+ */
467
+ function redirectFallbackHtml(target) {
468
+ const escapedTarget = escapeHtml(target);
469
+ const scriptTarget = JSON.stringify(target).replaceAll('<', '\\u003C');
470
+ return [
471
+ '<!doctype html>',
472
+ '<html lang="en">',
473
+ '<head>',
474
+ ' <meta charset="utf-8">',
475
+ ` <meta http-equiv="refresh" content="0; url=${escapedTarget}">`,
476
+ ` <link rel="canonical" href="${escapedTarget}" vite-ignore>`,
477
+ ' <title>Redirecting</title>',
478
+ '</head>',
479
+ '<body>',
480
+ ` <p>Redirecting to <a href="${escapedTarget}">${escapedTarget}</a>.</p>`,
481
+ ` <script>window.location.replace(${scriptTarget});</script>`,
482
+ '</body>',
483
+ '</html>',
484
+ '',
485
+ ].join('\n');
486
+ }
487
+
488
+ /**
489
+ * @param {string} pagePath
490
+ * @param {Response} response
491
+ */
492
+ async function writeStaticResponse(pagePath, response) {
493
+ const data = new Uint8Array(await response.arrayBuffer());
494
+ if (isFileOutputPath(pagePath)) {
495
+ writeFileOutput(pagePath, data);
496
+ return;
497
+ }
498
+ writeHtml(pagePath, Buffer.from(data).toString('utf8'));
499
+ }
500
+
501
+ /**
502
+ * @param {string} pagePath
503
+ * @returns {boolean}
504
+ */
505
+ function isFileOutputPath(pagePath) {
506
+ return path.extname(pagePath) !== '';
507
+ }
508
+
509
+ /**
510
+ * @param {string} pagePath
511
+ * @param {Uint8Array} data
512
+ */
513
+ function writeFileOutput(pagePath, data) {
514
+ if (!pagePath.startsWith('/')) {
515
+ pagePath = '/' + pagePath;
516
+ }
517
+ const outputPath = 'tmp-dist-rocket' + pagePath;
518
+ mkdirSync(path.dirname(outputPath), { recursive: true });
519
+ writeFileSync(outputPath, data);
520
+ }
521
+
522
+ /**
523
+ * @param {string} pagePath
524
+ * @param {string} data
525
+ */
526
+ function writeHtml(pagePath, data) {
527
+ pagePath = normalizeDocumentPath(pagePath);
528
+ const outputPath = 'tmp-dist-rocket' + pagePath;
529
+ if (!existsSync(outputPath)) {
530
+ mkdirSync(outputPath, { recursive: true });
531
+ }
532
+ writeFileSync(outputPath + 'index.html', data);
533
+ }
534
+
535
+ /**
536
+ * @param {string} value
537
+ */
538
+ function escapeHtml(value) {
539
+ return value
540
+ .replaceAll('&', '&amp;')
541
+ .replaceAll('"', '&quot;')
542
+ .replaceAll("'", '&#39;')
543
+ .replaceAll('<', '&lt;')
544
+ .replaceAll('>', '&gt;');
545
+ }
@@ -0,0 +1,47 @@
1
+ import { Command } from 'commander';
2
+ import { readConfig } from '../config.js';
3
+ import { RocketBuild } from './RocketBuild.js';
4
+ import { RocketInit } from './RocketInit.js';
5
+ import { RocketStart } from './RocketStart.js';
6
+
7
+ export class RocketCli {
8
+ /** @type {string[]} */
9
+ argv;
10
+
11
+ /** @type {Command} */
12
+ program;
13
+
14
+ /** @type {string | undefined} */
15
+ configFilePath;
16
+
17
+ /** @type {import('@rocket/js/types.js').ResolvedRocketConfig | undefined} */
18
+ config;
19
+
20
+ constructor({ argv = process.argv } = {}) {
21
+ this.argv = argv;
22
+
23
+ this.program = new Command();
24
+ this.program.allowUnknownOption(true).option('-c, --config-file <path>', 'path to config file');
25
+ this.program.parseOptions(this.argv);
26
+
27
+ this.program.allowUnknownOption(false);
28
+
29
+ if (this.program.opts().configFile) {
30
+ this.configFilePath = this.program.opts().configFile;
31
+ }
32
+ }
33
+
34
+ async getConfig() {
35
+ this.config ??= await readConfig(this.configFilePath);
36
+ return this.config;
37
+ }
38
+
39
+ async start() {
40
+ for (const progClass of [RocketInit, RocketBuild, RocketStart]) {
41
+ const prog = new progClass();
42
+ await prog.setupCommand(this.program, this);
43
+ }
44
+
45
+ await this.program.parseAsync(this.argv);
46
+ }
47
+ }