@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.25.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 (404) hide show
  1. package/dist/cli/adapters/netlify.js +4 -2
  2. package/dist/cli/adapters/netlify.js.map +1 -1
  3. package/dist/cli/checks/lighthouse.d.ts +26 -0
  4. package/dist/cli/checks/lighthouse.d.ts.map +1 -0
  5. package/dist/cli/checks/lighthouse.js +121 -0
  6. package/dist/cli/checks/lighthouse.js.map +1 -0
  7. package/dist/cli/checks/links.d.ts +12 -0
  8. package/dist/cli/checks/links.d.ts.map +1 -0
  9. package/dist/cli/checks/links.js +89 -0
  10. package/dist/cli/checks/links.js.map +1 -0
  11. package/dist/cli/checks/performance.d.ts +17 -0
  12. package/dist/cli/checks/performance.d.ts.map +1 -0
  13. package/dist/cli/checks/performance.js +61 -0
  14. package/dist/cli/checks/performance.js.map +1 -0
  15. package/dist/cli/commands/check.d.ts +3 -0
  16. package/dist/cli/commands/check.d.ts.map +1 -0
  17. package/dist/cli/commands/check.js +85 -0
  18. package/dist/cli/commands/check.js.map +1 -0
  19. package/dist/cli/commands/preview.d.ts.map +1 -1
  20. package/dist/cli/commands/preview.js +4 -2
  21. package/dist/cli/commands/preview.js.map +1 -1
  22. package/dist/cli/create/index.d.ts +11 -1
  23. package/dist/cli/create/index.d.ts.map +1 -1
  24. package/dist/cli/create/index.js +135 -65
  25. package/dist/cli/create/index.js.map +1 -1
  26. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  27. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  28. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  29. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  30. package/dist/cli/index.js +2 -0
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/index.d.ts +4 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/plugin/build-ssg.d.ts +22 -6
  35. package/dist/plugin/build-ssg.d.ts.map +1 -1
  36. package/dist/plugin/build-ssg.js +226 -17
  37. package/dist/plugin/build-ssg.js.map +1 -1
  38. package/dist/plugin/content/index.d.ts +1 -1
  39. package/dist/plugin/content/index.d.ts.map +1 -1
  40. package/dist/plugin/content/index.js +8 -8
  41. package/dist/plugin/content/index.js.map +1 -1
  42. package/dist/plugin/content/parser.d.ts +3 -3
  43. package/dist/plugin/content/parser.d.ts.map +1 -1
  44. package/dist/plugin/content/parser.js +103 -24
  45. package/dist/plugin/content/parser.js.map +1 -1
  46. package/dist/plugin/dev-server.d.ts +4 -1
  47. package/dist/plugin/dev-server.d.ts.map +1 -1
  48. package/dist/plugin/dev-server.js.map +1 -1
  49. package/dist/plugin/dts-generator.d.ts.map +1 -1
  50. package/dist/plugin/dts-generator.js +50 -8
  51. package/dist/plugin/dts-generator.js.map +1 -1
  52. package/dist/plugin/generated-dir.d.ts +2 -0
  53. package/dist/plugin/generated-dir.d.ts.map +1 -1
  54. package/dist/plugin/generated-dir.js +17 -6
  55. package/dist/plugin/generated-dir.js.map +1 -1
  56. package/dist/plugin/html-post-process.d.ts +7 -0
  57. package/dist/plugin/html-post-process.d.ts.map +1 -1
  58. package/dist/plugin/html-post-process.js +26 -0
  59. package/dist/plugin/html-post-process.js.map +1 -1
  60. package/dist/plugin/index.d.ts.map +1 -1
  61. package/dist/plugin/index.js +60 -13
  62. package/dist/plugin/index.js.map +1 -1
  63. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  64. package/dist/plugin/transforms/auto-import.js +7 -0
  65. package/dist/plugin/transforms/auto-import.js.map +1 -1
  66. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  67. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  68. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  69. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  70. package/dist/runtime/app-template.d.ts +1 -1
  71. package/dist/runtime/app-template.d.ts.map +1 -1
  72. package/dist/runtime/app-template.js +206 -36
  73. package/dist/runtime/app-template.js.map +1 -1
  74. package/dist/runtime/composables/index.d.ts +4 -0
  75. package/dist/runtime/composables/index.d.ts.map +1 -1
  76. package/dist/runtime/composables/index.js +2 -0
  77. package/dist/runtime/composables/index.js.map +1 -1
  78. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  79. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  80. package/dist/runtime/composables/use-active-headings.js +112 -0
  81. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  82. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  83. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  84. package/dist/runtime/composables/use-content-page.js +181 -0
  85. package/dist/runtime/composables/use-content-page.js.map +1 -0
  86. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  87. package/dist/runtime/composables/use-content-search.js +1 -5
  88. package/dist/runtime/composables/use-content-search.js.map +1 -1
  89. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  90. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  91. package/dist/runtime/composables/use-fetch.js +112 -43
  92. package/dist/runtime/composables/use-fetch.js.map +1 -1
  93. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  94. package/dist/runtime/composables/use-route.js +39 -11
  95. package/dist/runtime/composables/use-route.js.map +1 -1
  96. package/dist/runtime/content/client.js +2 -2
  97. package/dist/runtime/content/client.js.map +1 -1
  98. package/dist/runtime/entry-server-template.d.ts +16 -1
  99. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  100. package/dist/runtime/entry-server-template.js +120 -13
  101. package/dist/runtime/entry-server-template.js.map +1 -1
  102. package/dist/types/config.d.ts +45 -4
  103. package/dist/types/config.d.ts.map +1 -1
  104. package/dist/types/config.js.map +1 -1
  105. package/dist/types/content.d.ts +18 -1
  106. package/dist/types/content.d.ts.map +1 -1
  107. package/dist/types/middleware.d.ts +2 -2
  108. package/dist/types/middleware.d.ts.map +1 -1
  109. package/package.json +22 -19
  110. package/.github/copilot-instructions.md +0 -169
  111. package/.github/workflows/publish.yml +0 -257
  112. package/.nvmrc +0 -1
  113. package/CHANGELOG.md +0 -236
  114. package/CLAUDE.md +0 -113
  115. package/commits.txt +0 -1
  116. package/cypress.config.ts +0 -16
  117. package/docs/authentication.md +0 -285
  118. package/docs/cli.md +0 -324
  119. package/docs/components.md +0 -237
  120. package/docs/composables.md +0 -907
  121. package/docs/configuration.md +0 -696
  122. package/docs/content.md +0 -570
  123. package/docs/data-loading.md +0 -336
  124. package/docs/getting-started.md +0 -237
  125. package/docs/head-management.md +0 -212
  126. package/docs/i18n.md +0 -159
  127. package/docs/layouts.md +0 -224
  128. package/docs/middleware.md +0 -234
  129. package/docs/plugins.md +0 -170
  130. package/docs/rendering-modes.md +0 -377
  131. package/docs/routing.md +0 -485
  132. package/docs/server-api.md +0 -253
  133. package/docs/testing.md +0 -455
  134. package/docs/use-fetch.md +0 -183
  135. package/e2e/cypress/e2e/api.cy.ts +0 -123
  136. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  137. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  138. package/e2e/cypress/e2e/content.cy.ts +0 -425
  139. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  140. package/e2e/cypress/e2e/data.cy.ts +0 -158
  141. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  142. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  143. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  144. package/e2e/cypress/e2e/head.cy.ts +0 -89
  145. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  146. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  147. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  148. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  149. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  150. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  151. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  152. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  153. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  154. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  155. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  156. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  157. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  158. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  159. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  160. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  161. package/e2e/cypress/e2e/session.cy.ts +0 -73
  162. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  163. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  164. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  165. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  166. package/e2e/cypress/support/commands.ts +0 -120
  167. package/e2e/cypress/support/e2e.ts +0 -10
  168. package/e2e/cypress/tsconfig.json +0 -14
  169. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  170. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  171. package/e2e/kitchen-sink/app/error.ts +0 -18
  172. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  173. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  174. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  175. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  176. package/e2e/kitchen-sink/app/loading.ts +0 -9
  177. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  178. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  179. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  180. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  181. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  182. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  183. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  184. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  185. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  186. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  187. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  188. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  189. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  190. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  191. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  192. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  193. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  194. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  195. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  196. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  197. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  198. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  199. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  200. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  201. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  202. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  203. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  204. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  205. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  206. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  207. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  208. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  209. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  210. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  211. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  212. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  213. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  214. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  215. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  216. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  217. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  218. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  219. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  220. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  221. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  222. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  223. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  224. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  225. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  226. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  227. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  228. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  229. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  230. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  231. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  232. package/e2e/kitchen-sink/cer.config.ts +0 -43
  233. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  234. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  235. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  236. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  237. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  238. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  239. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  240. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  241. package/e2e/kitchen-sink/content/index.md +0 -16
  242. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  243. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  244. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  245. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  246. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  247. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  248. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  249. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  250. package/e2e/kitchen-sink/tsconfig.json +0 -3
  251. package/e2e/scripts/clean.mjs +0 -14
  252. package/eslint.config.ts +0 -22
  253. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  254. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  255. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  256. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  257. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  258. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  259. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  260. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  261. package/src/__tests__/index.test.ts +0 -21
  262. package/src/__tests__/plugin/app-template.test.ts +0 -166
  263. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  264. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  265. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  266. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  267. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  268. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  269. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  270. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  271. package/src/__tests__/plugin/content/search.test.ts +0 -119
  272. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  273. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  274. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  275. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  276. package/src/__tests__/plugin/html-post-process.test.ts +0 -146
  277. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  278. package/src/__tests__/plugin/resolve-config.test.ts +0 -233
  279. package/src/__tests__/plugin/scanner.test.ts +0 -186
  280. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  281. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  282. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  283. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  284. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  285. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  286. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  287. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  288. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  289. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  290. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  291. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  292. package/src/__tests__/runtime/app-template.test.ts +0 -208
  293. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  294. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  295. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  296. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  297. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  298. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  299. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  300. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  301. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  302. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  303. package/src/__tests__/runtime/use-content.test.ts +0 -226
  304. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  305. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  306. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  307. package/src/__tests__/runtime/use-head.test.ts +0 -311
  308. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  309. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  310. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  311. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  312. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  313. package/src/__tests__/runtime/use-route.test.ts +0 -156
  314. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  315. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  316. package/src/__tests__/runtime/use-session.test.ts +0 -320
  317. package/src/__tests__/runtime/use-state.test.ts +0 -340
  318. package/src/__tests__/types/config.test.ts +0 -18
  319. package/src/cli/adapters/cloudflare.ts +0 -335
  320. package/src/cli/adapters/netlify.ts +0 -326
  321. package/src/cli/adapters/vercel.ts +0 -311
  322. package/src/cli/commands/adapt.ts +0 -84
  323. package/src/cli/commands/build.ts +0 -165
  324. package/src/cli/commands/dev.ts +0 -125
  325. package/src/cli/commands/generate.ts +0 -91
  326. package/src/cli/commands/preview-isr.ts +0 -172
  327. package/src/cli/commands/preview.ts +0 -523
  328. package/src/cli/create/index.ts +0 -275
  329. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  330. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  331. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  332. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  333. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  334. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  335. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  336. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  337. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  338. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  339. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  340. package/src/cli/index.ts +0 -22
  341. package/src/index.ts +0 -20
  342. package/src/plugin/build-ssg.ts +0 -403
  343. package/src/plugin/build-ssr.ts +0 -134
  344. package/src/plugin/content/emitter.ts +0 -50
  345. package/src/plugin/content/index.ts +0 -233
  346. package/src/plugin/content/parser.ts +0 -259
  347. package/src/plugin/content/path-utils.ts +0 -55
  348. package/src/plugin/content/scanner.ts +0 -26
  349. package/src/plugin/content/search.ts +0 -28
  350. package/src/plugin/dev-server.ts +0 -379
  351. package/src/plugin/dts-generator.ts +0 -273
  352. package/src/plugin/generated-dir.ts +0 -121
  353. package/src/plugin/html-post-process.ts +0 -96
  354. package/src/plugin/index.ts +0 -584
  355. package/src/plugin/path-utils.ts +0 -186
  356. package/src/plugin/scanner.ts +0 -65
  357. package/src/plugin/transforms/auto-import.ts +0 -206
  358. package/src/plugin/transforms/head-inject.ts +0 -161
  359. package/src/plugin/virtual/composables.ts +0 -28
  360. package/src/plugin/virtual/content-components.ts +0 -83
  361. package/src/plugin/virtual/error.ts +0 -34
  362. package/src/plugin/virtual/layouts.ts +0 -41
  363. package/src/plugin/virtual/loading.ts +0 -32
  364. package/src/plugin/virtual/middleware.ts +0 -45
  365. package/src/plugin/virtual/plugins.ts +0 -46
  366. package/src/plugin/virtual/routes.ts +0 -514
  367. package/src/plugin/virtual/server-api.ts +0 -85
  368. package/src/plugin/virtual/server-middleware.ts +0 -44
  369. package/src/runtime/app-template.ts +0 -377
  370. package/src/runtime/composables/define-middleware.ts +0 -17
  371. package/src/runtime/composables/define-server-middleware.ts +0 -18
  372. package/src/runtime/composables/index.ts +0 -27
  373. package/src/runtime/composables/use-auth.ts +0 -125
  374. package/src/runtime/composables/use-content-search.ts +0 -205
  375. package/src/runtime/composables/use-content.ts +0 -146
  376. package/src/runtime/composables/use-cookie.ts +0 -135
  377. package/src/runtime/composables/use-fetch.ts +0 -438
  378. package/src/runtime/composables/use-head.ts +0 -234
  379. package/src/runtime/composables/use-inject.ts +0 -49
  380. package/src/runtime/composables/use-locale.ts +0 -109
  381. package/src/runtime/composables/use-navigate.ts +0 -58
  382. package/src/runtime/composables/use-page-data.ts +0 -93
  383. package/src/runtime/composables/use-route.ts +0 -71
  384. package/src/runtime/composables/use-runtime-config.ts +0 -123
  385. package/src/runtime/composables/use-seo-meta.ts +0 -80
  386. package/src/runtime/composables/use-session.ts +0 -186
  387. package/src/runtime/composables/use-state.ts +0 -92
  388. package/src/runtime/content/client.ts +0 -168
  389. package/src/runtime/entry-client-template.ts +0 -39
  390. package/src/runtime/entry-server-template.ts +0 -493
  391. package/src/runtime/isr-handler.ts +0 -184
  392. package/src/runtime/oauth/handler.ts +0 -407
  393. package/src/runtime/oauth/index.ts +0 -49
  394. package/src/runtime/oauth/providers.ts +0 -38
  395. package/src/types/api.ts +0 -40
  396. package/src/types/config.ts +0 -379
  397. package/src/types/content.ts +0 -66
  398. package/src/types/index.ts +0 -7
  399. package/src/types/middleware.ts +0 -63
  400. package/src/types/page.ts +0 -117
  401. package/src/types/plugin.ts +0 -34
  402. package/tsconfig.build.json +0 -10
  403. package/tsconfig.json +0 -19
  404. package/vitest.config.ts +0 -33
@@ -73,7 +73,7 @@ export const ContentClient = {
73
73
  // and dist/client/_content/ by cerContent's closeBundle hook.
74
74
  // _ssrManifest is a module-level cache — populated once and reused for the
75
75
  // lifetime of the process so manifest.json is only read and parsed once at scale.
76
- if (typeof window === 'undefined' && typeof process !== 'undefined') {
76
+ if (import.meta.env.SSR) {
77
77
  if (_ssrManifest)
78
78
  return _ssrManifest;
79
79
  try {
@@ -116,7 +116,7 @@ export const ContentClient = {
116
116
  // _ssrItemCache is a module-level Map so each document is read and parsed at
117
117
  // most once per process lifetime, regardless of how many concurrent requests
118
118
  // ask for the same path.
119
- if (typeof window === 'undefined' && typeof process !== 'undefined') {
119
+ if (import.meta.env.SSR) {
120
120
  if (_ssrItemCache.has(path))
121
121
  return _ssrItemCache.get(path) ?? null;
122
122
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/runtime/content/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/runtime/content/client.ts"],"names":[],"mappings":"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"}
@@ -11,5 +11,20 @@
11
11
  * - useHead() support via beginHeadCollection / endHeadCollection
12
12
  * - DSD polyfill injected at end of <body> after client-template merge
13
13
  */
14
- export declare const ENTRY_SERVER_TEMPLATE = "// Server-side entry \u2014 AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport 'virtual:cer-content-components'\nimport routes from 'virtual:cer-routes'\nimport layouts from 'virtual:cer-layouts'\nimport plugins from 'virtual:cer-plugins'\nimport apiRoutes from 'virtual:cer-server-api'\nimport serverMiddleware from 'virtual:cer-server-middleware'\nimport { runtimeConfig, _runtimePrivateDefaults, _authSessionKey, _hooks } from 'virtual:cer-app-config'\nimport { registerBuiltinComponents, setDevMode } from '@jasonshimmy/custom-elements-runtime'\nimport { registerEntityMap, renderToStreamWithJITCSSDSD, DSD_POLYFILL_SCRIPT } from '@jasonshimmy/custom-elements-runtime/ssr'\nimport entitiesJson from '@jasonshimmy/custom-elements-runtime/entities.json'\nimport { initRouter } from '@jasonshimmy/custom-elements-runtime/router'\nimport { beginHeadCollection, endHeadCollection, serializeHeadTags, initRuntimeConfig, resolvePrivateConfig, useSession } from '@jasonshimmy/vite-plugin-cer-app/composables'\nimport { errorTag } from 'virtual:cer-error'\nimport { createIsrHandler } from '@jasonshimmy/vite-plugin-cer-app/isr'\n\nconst _cerProcess = (globalThis).process\nconst _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE\nconst _cerRuntimeDev =\n typeof _cerNodeEnv === 'string'\n ? _cerNodeEnv !== 'production'\n : typeof import.meta.env?.DEV === 'boolean'\n ? import.meta.env.DEV\n : typeof import.meta.env?.PROD === 'boolean'\n ? !import.meta.env.PROD\n : typeof import.meta.env?.MODE === 'string'\n ? import.meta.env.MODE !== 'production'\n : false\n;(globalThis).__CE_RUNTIME_DEV__ = _cerRuntimeDev\n\nregisterBuiltinComponents()\nsetDevMode(_cerRuntimeDev)\n\n// Resolve private config from environment variables at server startup.\n// Each key declared in runtimeConfig.private is looked up in process.env,\n// first as-is, then as ALL_CAPS. The declared default is used as fallback.\ninitRuntimeConfig({ ...runtimeConfig, private: resolvePrivateConfig(_runtimePrivateDefaults ?? {}) })\n\n// Pre-load the full HTML entity map so named entities like &mdash; decode\n// correctly during SSR. Without this the bundled runtime falls back to a\n// minimal set (&lt;, &gt;, &amp; \u2026) and re-escapes everything else.\nregisterEntityMap(entitiesJson)\n\n// Run plugins once at server startup so their provide() values are available\n// to useInject() during every SSR/SSG render pass. Stored on globalThis so all\n// dynamically-imported page chunks share the same reference.\nconst _pluginProvides = new Map()\n;(globalThis).__cerPluginProvides = _pluginProvides\nconst _pluginsReady = (async () => {\n const _bootstrapRouter = initRouter({ routes })\n for (const plugin of plugins) {\n if (plugin && typeof plugin.setup === 'function') {\n await plugin.setup({\n router: _bootstrapRouter,\n provide: (key, value) => _pluginProvides.set(key, value),\n config: {},\n })\n }\n }\n})()\n\n// Async-local storage for request-scoped SSR loader data.\n// Using AsyncLocalStorage ensures concurrent SSR renders (e.g. SSG with\n// concurrency > 1) never see each other's data \u2014 each request's async chain\n// carries its own store value, so usePageData() is always race-condition-free.\nconst _cerDataStore = new AsyncLocalStorage()\n// Expose the store so the usePageData() composable can read it server-side.\n;(globalThis).__CER_DATA_STORE__ = _cerDataStore\n\n// Async-local storage for request-scoped req/res access.\n// Allows isomorphic composables (e.g. useCookie) to read/write HTTP headers\n// without prop-drilling the request context through the component tree.\nconst _cerReqStore = new AsyncLocalStorage()\n;(globalThis).__CER_REQ_STORE__ = _cerReqStore\n\n// Async-local storage for the authenticated user resolved before each render.\n// useAuth() reads this store server-side to return the current user synchronously.\nconst _cerAuthStore = new AsyncLocalStorage()\n;(globalThis).__CER_AUTH_STORE__ = _cerAuthStore\n\n// Async-local storage for per-request useFetch() data.\n// useFetch() writes fetched results here; the handler serialises the map into\n// window.__CER_FETCH_DATA__ for client-side hydration.\nconst _cerFetchStore = new AsyncLocalStorage()\n;(globalThis).__CER_FETCH_STORE__ = _cerFetchStore\n\n// Async-local storage for the current route info (path, params, query, meta).\n// useRoute() reads this on the server so layouts and components can access\n// route metadata without prop-drilling.\nconst _cerRouteStore = new AsyncLocalStorage()\n;(globalThis).__CER_ROUTE_STORE__ = _cerRouteStore\n\n// Async-local storage for per-request useState() reactive state.\n// Each request gets a fresh Map so concurrent SSR/SSG renders never share\n// reactive state set by different pages or loaders.\nconst _cerStateStore = new AsyncLocalStorage()\n;(globalThis).__CER_STATE_STORE__ = _cerStateStore\n\n// Runs fn inside the per-request AsyncLocalStorage context so that isomorphic\n// composables (useCookie, useSession, etc.) can access req/res without prop-drilling.\n// Call this for every API handler invocation \u2014 not just SSR renders.\nexport function runWithRequestContext(req, res, fn) {\n return _cerReqStore.run({ req, res }, fn)\n}\n\n// Runs the server/middleware/ chain for a request.\n// Returns false if a middleware short-circuited the response; true to continue.\n// Exported so Netlify / Vercel / Cloudflare bridges can also call it for API routes.\n// P1-2: Middleware may throw { status: 401 } (or any numeric .status) to produce\n// a non-500 response \u2014 the status is extracted and forwarded to res.statusCode.\nexport async function runServerMiddleware(req, res) {\n for (const { handler: mw } of (serverMiddleware ?? [])) {\n if (typeof mw !== 'function') continue\n let calledNext = false\n try {\n await new Promise((resolve, reject) => {\n Promise.resolve(mw(req, res, (err) => {\n if (err) reject(err)\n else { calledNext = true; resolve() }\n })).catch(reject)\n })\n } catch (err) {\n if (_hooks?.onError) {\n try { await _hooks.onError(err, { type: 'middleware', path: new URL(req.url ?? '/', 'http://x').pathname, req }) } catch { /* hooks must not crash the handler */ }\n }\n if (!res.writableEnded) {\n const statusCode = (typeof err === 'object' && err !== null && 'status' in err && typeof err.status === 'number')\n ? (isNaN(err.status) ? 500 : err.status)\n : 500\n res.statusCode = statusCode\n res.end('Internal Server Error')\n }\n return false\n }\n if (res.writableEnded || !calledNext) return false\n }\n return true\n}\n\n// Load the Vite-built client index.html (dist/client/index.html) so every SSR\n// response includes the client-side scripts needed for hydration and routing.\n// The server bundle lives at dist/server/server.js, so ../client resolves correctly.\n//\n// Cloudflare Workers (and other runtimes without node:fs) can inject the\n// template before this module loads by setting globalThis.__CER_CLIENT_TEMPLATE__.\n// The Cloudflare adapter inlines dist/client/index.html as a string constant in\n// _worker.js and sets the global before dynamically importing the server bundle.\nlet _clientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? null\nif (!_clientTemplate) {\n try {\n const _clientTemplatePath = join(dirname(fileURLToPath(import.meta.url)), '../client/index.html')\n _clientTemplate = existsSync(_clientTemplatePath)\n ? readFileSync(_clientTemplatePath, 'utf-8')\n : null\n } catch {\n // node:fs not available in this runtime \u2014 Cloudflare adapter must set\n // globalThis.__CER_CLIENT_TEMPLATE__ before importing this bundle.\n }\n}\n\n// Merge the SSR rendered body with the Vite client shell so the final page\n// contains both pre-rendered DSD content and the client bundle scripts.\nfunction _mergeWithClientTemplate(ssrHtml, clientTemplate) {\n const headTag = '<head>', headCloseTag = '</head>'\n const bodyTag = '<body>', bodyCloseTag = '</body>'\n const headStart = ssrHtml.indexOf(headTag)\n const headEnd = ssrHtml.indexOf(headCloseTag)\n const bodyStart = ssrHtml.indexOf(bodyTag)\n const bodyEnd = ssrHtml.lastIndexOf(bodyCloseTag)\n const ssrHead = headStart >= 0 && headEnd > headStart\n ? ssrHtml.slice(headStart + headTag.length, headEnd).trim() : ''\n const ssrBody = bodyStart >= 0 && bodyEnd > bodyStart\n ? ssrHtml.slice(bodyStart + bodyTag.length, bodyEnd).trim() : ssrHtml\n // Hoist only top-level <style id=...> elements (cer-ssr-jit, cer-ssr-global)\n // from the SSR body into the document <head>. Plain <style> blocks without\n // an id attribute belong to shadow DOM templates and must stay in place \u2014\n // hoisting them to <head> breaks shadow DOM style encapsulation (document\n // styles do not pierce shadow roots), which is the root cause of FOUC.\n const headParts = ssrHead ? [ssrHead] : []\n let ssrBodyContent = ssrBody\n let pos = 0\n while (pos < ssrBodyContent.length) {\n const styleOpen = ssrBodyContent.indexOf('<style id=', pos)\n if (styleOpen < 0) break\n const styleClose = ssrBodyContent.indexOf('</style>', styleOpen)\n if (styleClose < 0) break\n headParts.push(ssrBodyContent.slice(styleOpen, styleClose + 8))\n ssrBodyContent = ssrBodyContent.slice(0, styleOpen) + ssrBodyContent.slice(styleClose + 8)\n pos = styleOpen\n }\n ssrBodyContent = ssrBodyContent.trim()\n // Inject the pre-rendered layout+page as light DOM of the app mount element\n // so it is visible before JS boots, then the client router takes over.\n let merged = clientTemplate\n if (merged.includes('<cer-layout-view></cer-layout-view>')) {\n merged = merged.replace('<cer-layout-view></cer-layout-view>',\n '<cer-layout-view>' + ssrBodyContent + '</cer-layout-view>')\n } else if (merged.includes('<div id=\"app\"></div>')) {\n merged = merged.replace('<div id=\"app\"></div>',\n '<div id=\"app\">' + ssrBodyContent + '</div>')\n }\n const headAdditions = headParts.filter(Boolean).join('\\n')\n if (headAdditions) {\n // If SSR provides a <title>, replace the client template's <title> so the\n // SSR title wins (client template title is the fallback default).\n if (headAdditions.includes('<title>')) {\n merged = merged.replace(/<title>[^<]*<\\/title>/, '')\n }\n merged = merged.replace('</head>', headAdditions + '\\n</head>')\n }\n return merged\n}\n\n// Per-request async setup: initialize a fresh router, resolve the matched\n// route and layout, pre-load the page module, and call the data loader.\n// Loader data is returned so the handler can scope it to _cerDataStore.run()\n// during rendering. (AsyncLocalStorage.enterWith() inside an awaited child\n// function does not propagate back to the parent continuation, so run() is\n// the only reliable approach.)\nconst _prepareRequest = async (req) => {\n await _pluginsReady\n const router = initRouter({ routes, initialUrl: req.url ?? '/' })\n const current = router.getCurrent()\n const { route, params } = router.matchRoute(current.path)\n\n // Store the current route info so useRoute() can read it synchronously\n // from any layout or component during this render pass.\n _cerRouteStore.enterWith({\n path: current.path,\n params,\n query: current.query ?? {},\n meta: route?.meta ?? null,\n })\n\n // Pre-load the page module so we can embed the component tag directly.\n // This avoids the async router-view (which injects content via script tags\n // and breaks Declarative Shadow DOM on initial parse).\n let pageVnode = { tag: 'div', props: {}, children: [] }\n let head\n // Loader data to pass to usePageData() during rendering. Declared here\n // (outside try/catch) so it's visible in all return paths.\n let loaderData = null\n if (route?.load) {\n try {\n const mod = await route.load()\n const pageTag = mod.default\n // P2-2: Route-level error tag (from co-located .error.ts or _error.ts).\n // Preferred over the global errorTag when rendering loader errors for this route.\n const routeErrorTag = mod.errorTag ?? null\n\n // P1-1: Synthetic 404 catch-all \u2014 no page component registered.\n if (!pageTag) {\n const notFoundErrorTag = routeErrorTag ?? errorTag\n const notFoundVnode = notFoundErrorTag\n ? { tag: notFoundErrorTag, props: { attrs: { error: 'Not Found', status: '404' } }, children: [] }\n : { tag: 'div', props: {}, children: [] }\n return { vnode: notFoundVnode, router, head: undefined, status: 404 }\n }\n\n // Run the loader before creating the page vnode so we can pass its\n // primitive return values as HTML attributes. useProps() in the page\n // component reads element attributes, so merging loader data here makes\n // both useProps() and usePageData() work in SSR / SSG.\n let loaderAttrs = {}\n if (typeof mod.loader === 'function') {\n const query = current.query ?? {}\n const data = await mod.loader({ params, query, req })\n if (data !== undefined && data !== null) {\n // Store loader data so the handler can pass it to _cerDataStore.run()\n // below. Using enterWith() here doesn't work because it only modifies\n // the async context *inside* this awaited function, not the outer\n // handler's continuation where renderToStreamWithJITCSSDSD runs.\n loaderData = data\n head = `<script>window.__CER_DATA__ = ${JSON.stringify(data)}</script>`\n // Expose primitive loader values as element attributes so useProps()\n // can read them. Complex objects are only accessible via usePageData().\n loaderAttrs = Object.fromEntries(\n Object.entries(data).filter(([, v]) => v !== null && v !== undefined && typeof v !== 'object' && typeof v !== 'function')\n )\n }\n }\n\n pageVnode = { tag: pageTag, props: { attrs: { ...params, ...loaderAttrs } }, children: [] }\n } catch (err) {\n // Loader threw \u2014 render the error page server-side if app/error.ts exists.\n const status = (err && typeof err === 'object' && 'status' in err && typeof err.status === 'number')\n ? err.status : 500\n const message = (err instanceof Error) ? err.message : String(err)\n if (_hooks?.onError) {\n try { await _hooks.onError(err, { type: 'loader', path: new URL(req.url ?? '/', 'http://x').pathname, req }) } catch { /* hooks must not crash the handler */ }\n }\n // P2-2: Prefer the route-level errorTag over the global one.\n // routeErrorTag is not in scope here; use route?.meta?.errorTag from the matched route.\n const effectiveErrorTag = route?.meta?.errorTag ?? errorTag\n if (!effectiveErrorTag) {\n console.error('[cer-app] Loader error (no app/error.ts defined):', err)\n }\n const errVnode = effectiveErrorTag\n ? { tag: effectiveErrorTag, props: { attrs: { error: message, status: String(status) } }, children: [] }\n : { tag: 'div', props: {}, children: [] }\n return { vnode: errVnode, router, head: undefined, status }\n }\n }\n\n // Resolve layout chain: nested layouts (meta.layoutChain) or single layout.\n const chain = route?.meta?.layoutChain\n ? route.meta.layoutChain\n : [route?.meta?.layout ?? 'default']\n\n // Wrap pageVnode in the layout chain from innermost to outermost.\n let vnode = pageVnode\n for (let i = chain.length - 1; i >= 0; i--) {\n const tag = layouts[chain[i]]\n if (tag) vnode = { tag, props: {}, children: [vnode] }\n }\n\n // Only framework-owned not-found routes should force a 404 status. A user\n // catch-all page ([...all].ts) may successfully resolve real content paths\n // and should stay 200 unless its loader explicitly throws a 404.\n const isNotFoundRoute = route?.meta?._cerNotFound === true\n return { vnode, router, head, status: isNotFoundRoute ? 404 : null, loaderData }\n}\n\nexport const handler = async (req, res) => {\n const _requestPath = new URL(req.url ?? '/', 'http://x').pathname\n const _requestStart = Date.now()\n if (_hooks?.onRequest) {\n try { await _hooks.onRequest({ path: _requestPath, method: req.method ?? 'GET', req }) } catch { /* hooks must not crash the handler */ }\n }\n await _cerStateStore.run(new Map(), async () => {\n await _cerReqStore.run({ req, res }, async () => {\n await _cerDataStore.run(null, async () => {\n // Fresh per-request fetch map \u2014 populated by useFetch() calls inside loaders.\n const _fetchMap = new Map()\n await _cerFetchStore.run(_fetchMap, async () => {\n // Pre-resolve the authenticated user so useAuth() works synchronously during rendering.\n let _authUser = null\n if (_authSessionKey) {\n try { _authUser = await useSession({ name: _authSessionKey }).get() } catch { /* no session secret */ }\n }\n await _cerAuthStore.run(_authUser, async () => {\n const { vnode, router, head, status, loaderData } = await _prepareRequest(req)\n if (status != null) res.statusCode = status\n\n let _headCollectionOpen = false\n // Wrap the entire render pass in _cerDataStore.run(loaderData) so that\n // usePageData() inside component renderFn calls sees the correct store\n // value. AsyncLocalStorage.enterWith() inside _prepareRequest does NOT\n // propagate back to this outer async continuation \u2014 it only affects the\n // async chain inside _prepareRequest itself. Using run() here is the only\n // reliable way to scope the data store to the synchronous render pass.\n await _cerDataStore.run(loaderData ?? null, async () => {\n try {\n // Begin collecting useHead() calls made during the synchronous render pass.\n // IMPORTANT: the stream's start() function runs synchronously on construction,\n // so ALL useHead() calls happen before the stream object is returned. We must\n // call endHeadCollection() immediately \u2014 before any await \u2014 to avoid a race\n // window where a concurrent request (e.g. SSG concurrency > 1) resets the\n // shared globalThis collector while this handler is suspended at an await.\n _headCollectionOpen = true\n beginHeadCollection()\n\n // dsdPolyfill: false \u2014 we inject the polyfill manually after merging so it\n // lands at the end of <body>, not inside <cer-layout-view> light DOM where\n // scripts may not execute.\n // The first chunk from the stream is the full synchronous render. Subsequent\n // chunks are async component swap scripts streamed as they resolve.\n const stream = renderToStreamWithJITCSSDSD(vnode, { dsdPolyfill: false, router })\n\n // Collect head tags synchronously \u2014 all useHead() calls have already fired\n // inside the stream constructor's start() before it returned.\n const headTags = serializeHeadTags(endHeadCollection())\n _headCollectionOpen = false\n\n const reader = stream.getReader()\n\n // Read the first (synchronous) chunk \u2014 rejects if the sync render failed.\n const { value: firstChunk = '' } = await reader.read()\n\n // Serialise useFetch() results collected during loader execution.\n const _fetchObj = Object.fromEntries(_fetchMap)\n const _fetchScript = Object.keys(_fetchObj).length > 0\n ? `<script>window.__CER_FETCH_DATA__ = ${JSON.stringify(_fetchObj)}</script>`\n : ''\n\n // Serialise the auth user for client-side hydration via useAuth().\n const _authScript = _authUser\n ? `<script>window.__CER_AUTH_USER__ = ${JSON.stringify(_authUser)}</script>`\n : ''\n\n // Serialise useState() values for client-side hydration.\n // The state Map is populated by loader calls (in _prepareRequest) and by component\n // render functions (during renderToStreamWithJITCSSDSD above). Both run before this\n // point. Injected as window.__CER_STATE_INIT__ so the client useState() can\n // pre-populate its singleton Map on first use \u2014 no flash to default values.\n const _stateMap = _cerStateStore.getStore()\n let _stateScript = ''\n if (_stateMap && _stateMap.size > 0) {\n const _stateObj = {}\n for (const [k, v] of _stateMap) { _stateObj[k] = v.value }\n _stateScript = `<script>window.__CER_STATE_INIT__ = ${JSON.stringify(_stateObj)}</script>`\n }\n\n // Merge loader data script + useHead() tags + fetch/auth/state hydration scripts.\n const headContent = [head, headTags, _fetchScript, _authScript, _stateScript].filter(Boolean).join('\\n')\n\n // Wrap the rendered body in a full HTML document and inject the head additions\n // (loader data script, useHead() tags, JIT styles). No polyfill in body yet.\n const ssrHtml = `<!DOCTYPE html><html><head>${headContent}</head><body>${firstChunk}</body></html>`\n\n // In dev mode the module-level _clientTemplate is null (only the\n // production dist/client/index.html path is searched at init time).\n // The dev server sets (globalThis).__CER_CLIENT_TEMPLATE__ per-request\n // after running server.transformIndexHtml so the Vite client scripts\n // (/@vite/client, HMR) are included in every SSR response.\n const _resolvedClientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? _clientTemplate\n const merged = _resolvedClientTemplate\n ? _mergeWithClientTemplate(ssrHtml, _resolvedClientTemplate)\n : ssrHtml\n\n // Split at </body> so async swap scripts and the DSD polyfill can be streamed\n // in before the document is closed.\n const bodyCloseIdx = merged.lastIndexOf('</body>')\n const beforeBodyClose = bodyCloseIdx >= 0 ? merged.slice(0, bodyCloseIdx) : merged\n const fromBodyClose = bodyCloseIdx >= 0 ? merged.slice(bodyCloseIdx) : ''\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.setHeader('Transfer-Encoding', 'chunked')\n res.write(beforeBodyClose)\n\n // Stream async component swap scripts through as-is.\n while (true) {\n const { value, done } = await reader.read()\n if (done) break\n res.write(value)\n }\n\n // Inject DSD polyfill immediately before </body>, then close the document.\n res.end(DSD_POLYFILL_SCRIPT + fromBodyClose)\n if (_hooks?.onResponse) {\n try { void _hooks.onResponse({ path: _requestPath, method: req.method ?? 'GET', statusCode: res.statusCode, duration: Date.now() - _requestStart, req }) } catch { /* ignore */ }\n }\n } catch (_renderErr) {\n if (_hooks?.onError) {\n try { await _hooks.onError(_renderErr, { type: 'render', path: _requestPath, req }) } catch { /* hooks must not crash the handler */ }\n }\n // Ensure the head collector is never left open on error.\n if (_headCollectionOpen) { try { endHeadCollection() } catch { /* ignore */ } }\n // If headers have not been flushed yet we can still send a proper 500 page.\n // If writing has already started we can only close the connection cleanly.\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end('<!DOCTYPE html><html><head></head><body><h1>500 Internal Server Error</h1><p>An unexpected error occurred while rendering this page.</p></body></html>')\n } else {\n res.end()\n }\n if (_hooks?.onResponse) {\n try { void _hooks.onResponse({ path: _requestPath, method: req.method ?? 'GET', statusCode: res.statusCode, duration: Date.now() - _requestStart, req }) } catch { /* ignore */ }\n }\n }\n }) // _cerDataStore.run(loaderData)\n }) // _cerAuthStore.run\n }) // _cerFetchStore.run\n }) // _cerDataStore.run\n }) // _cerReqStore.run\n }) // _cerStateStore.run\n}\n\n// ISR-wrapped handler for production integrations (Express, Hono, Fastify).\n// Routes with meta.ssg.revalidate are served stale-while-revalidate.\nexport const isrHandler = createIsrHandler(routes, handler)\n\nexport { apiRoutes, plugins, layouts, routes, serverMiddleware }\nexport default handler\n";
14
+ export declare function serializeForInlineScript(value: unknown): string;
15
+ /**
16
+ * Collect DSD tag names that are safe to define incrementally. A tag is only
17
+ * deferrable when every rendered instance explicitly carries a hydration
18
+ * strategy; one eager instance makes the shared custom-element definition
19
+ * part of the interactive shell and excludes that tag from the manifest.
20
+ */
21
+ export declare function collectDsdHostTags(html: string): string[];
22
+ /**
23
+ * Converts Vite's external module entry into an eagerly fetched, post-paint
24
+ * bootstrap. Static SSR routes can paint their complete HTML before framework
25
+ * and island modules evaluate, while modulepreload keeps interaction latency
26
+ * low once the first frame has committed.
27
+ */
28
+ export declare function deferEntryModulesForFirstPaint(html: string, dsdTags?: string[]): string;
29
+ export declare const ENTRY_SERVER_TEMPLATE: string;
15
30
  //# sourceMappingURL=entry-server-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entry-server-template.d.ts","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,+/vBA+djC,CAAA"}
1
+ {"version":3,"file":"entry-server-template.d.ts","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAS/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBzD;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,EAAO,GACrB,MAAM,CAoBR;AAaD,eAAO,MAAM,qBAAqB,QAggBjC,CAAA"}
@@ -11,6 +11,80 @@
11
11
  * - useHead() support via beginHeadCollection / endHeadCollection
12
12
  * - DSD polyfill injected at end of <body> after client-template merge
13
13
  */
14
+ export function serializeForInlineScript(value) {
15
+ const serialized = JSON.stringify(value);
16
+ if (serialized === undefined)
17
+ return 'null';
18
+ return serialized
19
+ .replace(/&/g, '\\u0026')
20
+ .replace(/</g, '\\u003c')
21
+ .replace(/>/g, '\\u003e')
22
+ .replace(/\u2028/g, '\\u2028')
23
+ .replace(/\u2029/g, '\\u2029');
24
+ }
25
+ /**
26
+ * Collect DSD tag names that are safe to define incrementally. A tag is only
27
+ * deferrable when every rendered instance explicitly carries a hydration
28
+ * strategy; one eager instance makes the shared custom-element definition
29
+ * part of the interactive shell and excludes that tag from the manifest.
30
+ */
31
+ export function collectDsdHostTags(html) {
32
+ const orderedTags = [];
33
+ const seen = new Set();
34
+ const deferred = new Set();
35
+ const eager = new Set();
36
+ const pattern = /<([a-z][a-z0-9._-]*-[a-z0-9._-]+)\b([^>]*)>\s*<template\b[^>]*\bshadowrootmode\s*=/gi;
37
+ let match;
38
+ while ((match = pattern.exec(html)) !== null) {
39
+ const tag = match[1].toLowerCase();
40
+ if (!seen.has(tag)) {
41
+ seen.add(tag);
42
+ orderedTags.push(tag);
43
+ }
44
+ if (/\bdata-cer-hydrate\s*=\s*(["'])[^"']+\1/i.test(match[2])) {
45
+ deferred.add(tag);
46
+ }
47
+ else {
48
+ eager.add(tag);
49
+ }
50
+ }
51
+ return orderedTags.filter((tag) => deferred.has(tag) && !eager.has(tag));
52
+ }
53
+ /**
54
+ * Converts Vite's external module entry into an eagerly fetched, post-paint
55
+ * bootstrap. Static SSR routes can paint their complete HTML before framework
56
+ * and island modules evaluate, while modulepreload keeps interaction latency
57
+ * low once the first frame has committed.
58
+ */
59
+ export function deferEntryModulesForFirstPaint(html, dsdTags = []) {
60
+ return html.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (tag, attrs, body) => {
61
+ if (body.trim() !== '' || !/\btype\s*=\s*(["'])module\1/i.test(attrs))
62
+ return tag;
63
+ const srcMatch = attrs.match(/\bsrc\s*=\s*(["'])([^"']+)\1/i);
64
+ if (!srcMatch)
65
+ return tag;
66
+ const src = srcMatch[2];
67
+ const escapedHref = src
68
+ .replace(/&/g, '&amp;')
69
+ .replace(/"/g, '&quot;')
70
+ .replace(/</g, '&lt;')
71
+ .replace(/>/g, '&gt;');
72
+ const serializedSrc = serializeForInlineScript(src);
73
+ const serializedDsdTags = serializeForInlineScript(dsdTags);
74
+ const start = `function(){if(typeof performance==='object'&&typeof performance.mark==='function')performance.mark('cer:entry-start');globalThis.__CER_STATIC_ENTRY__=true;globalThis.__CER_DSD_TAGS__=new Set(${serializedDsdTags});return import(${serializedSrc}).catch(function(error){console.error('[cer-app] Failed to start client entry:',error)})}`;
75
+ return `<link rel="modulepreload" crossorigin href="${escapedHref}"><script data-cer-deferred-entry>(function(start){var observer=null,fallback=null,started=false,guarding=true,queued=[];function capture(event){if(!guarding||event.defaultPrevented)return;var path=typeof event.composedPath==='function'?event.composedPath():[];if(!path.some(function(node){return node&&typeof node.localName==='string'&&node.localName.indexOf('-')>0}))return;event.preventDefault();event.stopImmediatePropagation();queued.push({target:path[0]||event.target,event:event})}function replay(){guarding=false;document.removeEventListener('click',capture,true);queued.splice(0).forEach(function(item){var event=item.event,target=item.target,init={bubbles:true,composed:true,cancelable:true},clone;if(typeof KeyboardEvent==='function'&&event instanceof KeyboardEvent){clone=new KeyboardEvent(event.type,Object.assign(init,{key:event.key,code:event.code,ctrlKey:event.ctrlKey,metaKey:event.metaKey,shiftKey:event.shiftKey,altKey:event.altKey,repeat:event.repeat}))}else{clone=new MouseEvent(event.type,Object.assign(init,{button:event.button,buttons:event.buttons,clientX:event.clientX,clientY:event.clientY,ctrlKey:event.ctrlKey,metaKey:event.metaKey,shiftKey:event.shiftKey,altKey:event.altKey}))}if(target&&target.isConnected)target.dispatchEvent(clone)})}function ready(){var view=document.querySelector('cer-layout-view'),shell=view&&Array.prototype.find.call(view.children,function(element){return element.localName&&element.localName!=='script'});if(!shell||shell.hasAttribute('data-cer-hydrated')){replay();return}if(typeof MutationObserver!=='function'){setTimeout(replay,0);return}var readiness=new MutationObserver(function(){if(shell.hasAttribute('data-cer-hydrated')){readiness.disconnect();replay()}});readiness.observe(shell,{attributes:true,attributeFilter:['data-cer-hydrated']});setTimeout(function(){readiness.disconnect();replay()},1000)}function boot(){Promise.resolve(start()).then(ready,replay)}function run(){if(started)return;started=true;if(observer)observer.disconnect();if(fallback!==null)clearTimeout(fallback);setTimeout(boot,0)}function byFrame(){if(typeof requestAnimationFrame==='function'){requestAnimationFrame(function(){requestAnimationFrame(function(){requestAnimationFrame(run)})})}else{run()}}document.addEventListener('click',capture,true);if(typeof PerformanceObserver==='function'){try{observer=new PerformanceObserver(function(list){if(list.getEntriesByName('first-contentful-paint').length)run()});fallback=setTimeout(run,1000);observer.observe({type:'paint',buffered:true})}catch(error){byFrame()}}else{byFrame()}})(${start})</script>`;
76
+ });
77
+ }
78
+ const inlineSerializerSource = serializeForInlineScript
79
+ .toString()
80
+ .replace('serializeForInlineScript', '_serializeForInlineScript');
81
+ const dsdTagCollectorSource = collectDsdHostTags
82
+ .toString()
83
+ .replace('collectDsdHostTags', '_collectDsdHostTags');
84
+ const deferredEntrySource = deferEntryModulesForFirstPaint
85
+ .toString()
86
+ .replace('deferEntryModulesForFirstPaint', '_deferEntryModulesForFirstPaint')
87
+ .replaceAll('serializeForInlineScript', '_serializeForInlineScript');
14
88
  export const ENTRY_SERVER_TEMPLATE = `// Server-side entry — AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app
15
89
  import { readFileSync, existsSync } from 'node:fs'
16
90
  import { dirname, join } from 'node:path'
@@ -25,12 +99,17 @@ import serverMiddleware from 'virtual:cer-server-middleware'
25
99
  import { runtimeConfig, _runtimePrivateDefaults, _authSessionKey, _hooks } from 'virtual:cer-app-config'
26
100
  import { registerBuiltinComponents, setDevMode } from '@jasonshimmy/custom-elements-runtime'
27
101
  import { registerEntityMap, renderToStreamWithJITCSSDSD, DSD_POLYFILL_SCRIPT } from '@jasonshimmy/custom-elements-runtime/ssr'
102
+ import ssrConfig from 'virtual:cer-ssr-config'
28
103
  import entitiesJson from '@jasonshimmy/custom-elements-runtime/entities.json'
29
104
  import { initRouter } from '@jasonshimmy/custom-elements-runtime/router'
30
105
  import { beginHeadCollection, endHeadCollection, serializeHeadTags, initRuntimeConfig, resolvePrivateConfig, useSession } from '@jasonshimmy/vite-plugin-cer-app/composables'
31
106
  import { errorTag } from 'virtual:cer-error'
32
107
  import { createIsrHandler } from '@jasonshimmy/vite-plugin-cer-app/isr'
33
108
 
109
+ ${inlineSerializerSource}
110
+ ${dsdTagCollectorSource}
111
+ ${deferredEntrySource}
112
+
34
113
  const _cerProcess = (globalThis).process
35
114
  const _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE
36
115
  const _cerRuntimeDev =
@@ -177,7 +256,10 @@ if (!_clientTemplate) {
177
256
 
178
257
  // Merge the SSR rendered body with the Vite client shell so the final page
179
258
  // contains both pre-rendered DSD content and the client bundle scripts.
180
- function _mergeWithClientTemplate(ssrHtml, clientTemplate) {
259
+ function _mergeWithClientTemplate(ssrHtml, clientTemplate, renderedPath, hydrationStrategy = 'load', dsdTags = []) {
260
+ if (hydrationStrategy === 'none') {
261
+ clientTemplate = _deferEntryModulesForFirstPaint(clientTemplate, dsdTags)
262
+ }
181
263
  const headTag = '<head>', headCloseTag = '</head>'
182
264
  const bodyTag = '<body>', bodyCloseTag = '</body>'
183
265
  const headStart = ssrHtml.indexOf(headTag)
@@ -211,7 +293,9 @@ function _mergeWithClientTemplate(ssrHtml, clientTemplate) {
211
293
  let merged = clientTemplate
212
294
  if (merged.includes('<cer-layout-view></cer-layout-view>')) {
213
295
  merged = merged.replace('<cer-layout-view></cer-layout-view>',
214
- '<cer-layout-view>' + ssrBodyContent + '</cer-layout-view>')
296
+ '<cer-layout-view data-cer-route="' + encodeURIComponent(renderedPath) +
297
+ '" data-cer-route-hydrate="' + hydrationStrategy + '">' +
298
+ ssrBodyContent + '</cer-layout-view>')
215
299
  } else if (merged.includes('<div id="app"></div>')) {
216
300
  merged = merged.replace('<div id="app"></div>',
217
301
  '<div id="app">' + ssrBodyContent + '</div>')
@@ -239,6 +323,7 @@ const _prepareRequest = async (req) => {
239
323
  const router = initRouter({ routes, initialUrl: req.url ?? '/' })
240
324
  const current = router.getCurrent()
241
325
  const { route, params } = router.matchRoute(current.path)
326
+ const hydrationStrategy = route?.meta?.hydrate ?? 'load'
242
327
 
243
328
  // Store the current route info so useRoute() can read it synchronously
244
329
  // from any layout or component during this render pass.
@@ -271,7 +356,7 @@ const _prepareRequest = async (req) => {
271
356
  const notFoundVnode = notFoundErrorTag
272
357
  ? { tag: notFoundErrorTag, props: { attrs: { error: 'Not Found', status: '404' } }, children: [] }
273
358
  : { tag: 'div', props: {}, children: [] }
274
- return { vnode: notFoundVnode, router, head: undefined, status: 404 }
359
+ return { vnode: notFoundVnode, router, head: undefined, status: 404, hydrationStrategy: 'load' }
275
360
  }
276
361
 
277
362
  // Run the loader before creating the page vnode so we can pass its
@@ -288,7 +373,12 @@ const _prepareRequest = async (req) => {
288
373
  // the async context *inside* this awaited function, not the outer
289
374
  // handler's continuation where renderToStreamWithJITCSSDSD runs.
290
375
  loaderData = data
291
- head = \`<script>window.__CER_DATA__ = \${JSON.stringify(data)}</script>\`
376
+ // A hydrate:none subtree never executes client component logic (the
377
+ // runtime also suppresses all of its shadow descendants), so shipping
378
+ // a duplicate loader payload cannot be observed and only delays paint.
379
+ if (hydrationStrategy !== 'none') {
380
+ head = \`<script>window.__CER_DATA__ = \${_serializeForInlineScript(data)}</script>\`
381
+ }
292
382
  // Expose primitive loader values as element attributes so useProps()
293
383
  // can read them. Complex objects are only accessible via usePageData().
294
384
  loaderAttrs = Object.fromEntries(
@@ -297,7 +387,17 @@ const _prepareRequest = async (req) => {
297
387
  }
298
388
  }
299
389
 
300
- pageVnode = { tag: pageTag, props: { attrs: { ...params, ...loaderAttrs } }, children: [] }
390
+ pageVnode = {
391
+ tag: pageTag,
392
+ props: {
393
+ attrs: {
394
+ ...params,
395
+ ...loaderAttrs,
396
+ ...(hydrationStrategy === 'none' ? { 'data-cer-hydrate': 'none' } : {}),
397
+ },
398
+ },
399
+ children: [],
400
+ }
301
401
  } catch (err) {
302
402
  // Loader threw — render the error page server-side if app/error.ts exists.
303
403
  const status = (err && typeof err === 'object' && 'status' in err && typeof err.status === 'number')
@@ -315,7 +415,7 @@ const _prepareRequest = async (req) => {
315
415
  const errVnode = effectiveErrorTag
316
416
  ? { tag: effectiveErrorTag, props: { attrs: { error: message, status: String(status) } }, children: [] }
317
417
  : { tag: 'div', props: {}, children: [] }
318
- return { vnode: errVnode, router, head: undefined, status }
418
+ return { vnode: errVnode, router, head: undefined, status, hydrationStrategy: 'load' }
319
419
  }
320
420
  }
321
421
 
@@ -335,7 +435,7 @@ const _prepareRequest = async (req) => {
335
435
  // catch-all page ([...all].ts) may successfully resolve real content paths
336
436
  // and should stay 200 unless its loader explicitly throws a 404.
337
437
  const isNotFoundRoute = route?.meta?._cerNotFound === true
338
- return { vnode, router, head, status: isNotFoundRoute ? 404 : null, loaderData }
438
+ return { vnode, router, head, status: isNotFoundRoute ? 404 : null, loaderData, hydrationStrategy }
339
439
  }
340
440
 
341
441
  export const handler = async (req, res) => {
@@ -356,7 +456,7 @@ export const handler = async (req, res) => {
356
456
  try { _authUser = await useSession({ name: _authSessionKey }).get() } catch { /* no session secret */ }
357
457
  }
358
458
  await _cerAuthStore.run(_authUser, async () => {
359
- const { vnode, router, head, status, loaderData } = await _prepareRequest(req)
459
+ const { vnode, router, head, status, loaderData, hydrationStrategy = 'load' } = await _prepareRequest(req)
360
460
  if (status != null) res.statusCode = status
361
461
 
362
462
  let _headCollectionOpen = false
@@ -382,7 +482,11 @@ export const handler = async (req, res) => {
382
482
  // scripts may not execute.
383
483
  // The first chunk from the stream is the full synchronous render. Subsequent
384
484
  // chunks are async component swap scripts streamed as they resolve.
385
- const stream = renderToStreamWithJITCSSDSD(vnode, { dsdPolyfill: false, router })
485
+ const stream = renderToStreamWithJITCSSDSD(vnode, {
486
+ dsdPolyfill: false,
487
+ router,
488
+ jit: ssrConfig?.jit,
489
+ })
386
490
 
387
491
  // Collect head tags synchronously — all useHead() calls have already fired
388
492
  // inside the stream constructor's start() before it returned.
@@ -393,16 +497,19 @@ export const handler = async (req, res) => {
393
497
 
394
498
  // Read the first (synchronous) chunk — rejects if the sync render failed.
395
499
  const { value: firstChunk = '' } = await reader.read()
500
+ const _dsdTags = hydrationStrategy === 'none'
501
+ ? _collectDsdHostTags(firstChunk)
502
+ : []
396
503
 
397
504
  // Serialise useFetch() results collected during loader execution.
398
505
  const _fetchObj = Object.fromEntries(_fetchMap)
399
506
  const _fetchScript = Object.keys(_fetchObj).length > 0
400
- ? \`<script>window.__CER_FETCH_DATA__ = \${JSON.stringify(_fetchObj)}</script>\`
507
+ ? \`<script>window.__CER_FETCH_DATA__ = \${_serializeForInlineScript(_fetchObj)}</script>\`
401
508
  : ''
402
509
 
403
510
  // Serialise the auth user for client-side hydration via useAuth().
404
511
  const _authScript = _authUser
405
- ? \`<script>window.__CER_AUTH_USER__ = \${JSON.stringify(_authUser)}</script>\`
512
+ ? \`<script>window.__CER_AUTH_USER__ = \${_serializeForInlineScript(_authUser)}</script>\`
406
513
  : ''
407
514
 
408
515
  // Serialise useState() values for client-side hydration.
@@ -415,7 +522,7 @@ export const handler = async (req, res) => {
415
522
  if (_stateMap && _stateMap.size > 0) {
416
523
  const _stateObj = {}
417
524
  for (const [k, v] of _stateMap) { _stateObj[k] = v.value }
418
- _stateScript = \`<script>window.__CER_STATE_INIT__ = \${JSON.stringify(_stateObj)}</script>\`
525
+ _stateScript = \`<script>window.__CER_STATE_INIT__ = \${_serializeForInlineScript(_stateObj)}</script>\`
419
526
  }
420
527
 
421
528
  // Merge loader data script + useHead() tags + fetch/auth/state hydration scripts.
@@ -432,7 +539,7 @@ export const handler = async (req, res) => {
432
539
  // (/@vite/client, HMR) are included in every SSR response.
433
540
  const _resolvedClientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? _clientTemplate
434
541
  const merged = _resolvedClientTemplate
435
- ? _mergeWithClientTemplate(ssrHtml, _resolvedClientTemplate)
542
+ ? _mergeWithClientTemplate(ssrHtml, _resolvedClientTemplate, _requestPath, hydrationStrategy, _dsdTags)
436
543
  : ssrHtml
437
544
 
438
545
  // Split at </body> so async swap scripts and the DSD polyfill can be streamed
@@ -1 +1 @@
1
- {"version":3,"file":"entry-server-template.js","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+dpC,CAAA"}
1
+ {"version":3,"file":"entry-server-template.js","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,16 @@
1
1
  import type { RouterConfig } from '@jasonshimmy/custom-elements-runtime/router';
2
2
  import type { IncomingMessage } from 'node:http';
3
+ /** A package-provided bundle of component resolution, global imports, and Vite plugins. */
4
+ export interface CerAppIntegration {
5
+ /** Stable name used in diagnostics. */
6
+ name: string;
7
+ /** Resolve a rendered custom-element tag to its side-effect registration module. */
8
+ componentResolver?: (tag: string) => string | undefined;
9
+ /** Imports that must run once in the generated client entry (for example global CSS). */
10
+ globalImports?: readonly string[];
11
+ /** Build plugins required by the integration. */
12
+ plugins?: import('vite').Plugin[];
13
+ }
3
14
  /**
4
15
  * Context passed to the `onError` hook.
5
16
  * `type` indicates which layer the error originated from so reporters can
@@ -120,17 +131,31 @@ export interface SsgConfig {
120
131
  * - `string[]` — explicit list of paths (e.g. `['/about', '/contact']`).
121
132
  */
122
133
  routes?: 'auto' | string[];
123
- /** Maximum number of pages rendered in parallel. Defaults to `1`. Increase for faster SSG builds at the cost of higher memory usage. */
134
+ /** Maximum number of pages rendered in parallel. Defaults to `4`. Increase for faster SSG builds at the cost of higher memory usage. */
124
135
  concurrency?: number;
125
136
  /** When `true`, unenumerated routes fall back to SSR at runtime instead of returning 404. */
126
137
  fallback?: boolean;
138
+ /** Fail the build when any route cannot be rendered. Defaults to `true`; set to `false` only for intentionally partial output. */
139
+ failOnError?: boolean;
140
+ /**
141
+ * Inline root-relative CSS assets into each generated HTML document.
142
+ *
143
+ * - `false` (default) keeps stylesheet links unchanged.
144
+ * - `true` inlines every root-relative stylesheet.
145
+ * - A positive number inlines only stylesheets at or below that UTF-8 byte size.
146
+ *
147
+ * This removes a render-blocking request for small critical stylesheets at the
148
+ * cost of repeating their bytes in each page. Inline styles also require an
149
+ * appropriate Content Security Policy (`style-src`) when CSP is enabled.
150
+ */
151
+ inlineStylesheets?: boolean | number;
127
152
  }
128
153
  /** JIT (Just-In-Time) CSS configuration for shadow-DOM style injection. */
129
154
  export interface JitCssConfig {
130
155
  /** Additional glob patterns for content files scanned by the JIT CSS engine. */
131
156
  content?: string[];
132
- /** Enable the extended color palette. Defaults to `false`. */
133
- extendedColors?: boolean;
157
+ /** Enable every extended color family or list only the families to retain. Defaults to `false`. */
158
+ extendedColors?: boolean | string[];
134
159
  /**
135
160
  * Project-specific color families registered in the JIT CSS engine at both
136
161
  * build time and runtime. Each key is a color family name (e.g. `brand`);
@@ -251,6 +276,8 @@ export interface CerAppConfig {
251
276
  router?: Pick<RouterConfig, 'base' | 'scrollToFragment'>;
252
277
  jitCss?: JitCssConfig;
253
278
  autoImports?: AutoImportsConfig;
279
+ /** UI/framework integrations composed into generated entries and component code splitting. */
280
+ integrations?: CerAppIntegration[];
254
281
  port?: number;
255
282
  /**
256
283
  * Runtime configuration accessible via `useRuntimeConfig()`.
@@ -278,8 +305,22 @@ export interface CerAppConfig {
278
305
  * ```
279
306
  *
280
307
  * You can also run the built-in adapters independently with `cer-app adapt --platform <name>`.
281
- */
308
+ */
282
309
  adapter?: 'vercel' | 'netlify' | 'cloudflare' | ((root: string) => Promise<void>);
310
+ /**
311
+ * Additional standalone Vite plugins to include alongside the built-in cerApp plugins.
312
+ * UI libraries that also resolve components or add global entry imports should
313
+ * use `integrations` instead.
314
+ *
315
+ * @example
316
+ * ```ts
317
+ * import inspect from 'vite-plugin-inspect'
318
+ * export default defineConfig({
319
+ * plugins: [inspect()],
320
+ * })
321
+ * ```
322
+ */
323
+ plugins?: import('vite').Plugin[];
283
324
  /**
284
325
  * Authentication configuration.
285
326
  * Enables OAuth login flows via `useAuth()` and auto-generates
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAqWA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AA+YA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -47,7 +47,18 @@ export interface ContentSearchResult {
47
47
  title: string;
48
48
  description?: string;
49
49
  }
50
- /** Content layer configuration. Controls the directory and draft behaviour. */
50
+ /** Metadata supplied when resolving a relation for a rendered Markdown link. */
51
+ export interface ContentLinkContext {
52
+ href: string;
53
+ title: string | null;
54
+ text: string;
55
+ }
56
+ /**
57
+ * Relation applied to rendered Markdown links. A callback can selectively
58
+ * qualify links (for example, affiliate URLs) while leaving other links alone.
59
+ */
60
+ export type ContentLinkRel = string | ((link: ContentLinkContext) => string | null | undefined | false);
61
+ /** Content layer configuration. Controls parsing, directory, and draft behaviour. */
51
62
  export interface CerContentConfig {
52
63
  /**
53
64
  * Content directory relative to the project root. Defaults to `'content'`,
@@ -59,5 +70,11 @@ export interface CerContentConfig {
59
70
  * production builds. Defaults to `false`.
60
71
  */
61
72
  drafts?: boolean;
73
+ /**
74
+ * Adds a `rel` attribute to links rendered from Markdown. Provide a string to
75
+ * apply the same relation to every link, or a callback to qualify links
76
+ * selectively. Empty callback results leave the link unchanged.
77
+ */
78
+ linkRel?: ContentLinkRel;
62
79
  }
63
80
  //# sourceMappingURL=content.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/types/content.ts"],"names":[],"mappings":"AAAA,uIAAuI;AACvI,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,qFAAqF;IACrF,EAAE,EAAE,MAAM,CAAA;IACV,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,wBAAwB;IACxB,KAAK,EAAE,UAAU,GAAG,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,GAAG,EAAE,cAAc,EAAE,CAAA;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/types/content.ts"],"names":[],"mappings":"AAAA,uIAAuI;AACvI,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,qFAAqF;IACrF,EAAE,EAAE,MAAM,CAAA;IACV,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,wBAAwB;IACxB,KAAK,EAAE,UAAU,GAAG,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,GAAG,EAAE,cAAc,EAAE,CAAA;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,CAAC,CAAC,IAAI,EAAE,kBAAkB,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC,CAAA;AAErE,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB"}
@@ -6,7 +6,7 @@ import type { IncomingMessage, ServerResponse } from 'node:http';
6
6
  * - `false` — block navigation
7
7
  * - `string` — redirect to that path
8
8
  */
9
- export type GuardResult = boolean | string | Promise<boolean | string>;
9
+ export type GuardResult = boolean | string | void | Promise<boolean | string | void>;
10
10
  /**
11
11
  * Route middleware function.
12
12
  *
@@ -32,7 +32,7 @@ export type GuardResult = boolean | string | Promise<boolean | string>;
32
32
  * })
33
33
  * ```
34
34
  */
35
- export type MiddlewareFn = (to: RouteState, from: RouteState | null, next: () => Promise<void>) => GuardResult | void;
35
+ export type MiddlewareFn = (to: RouteState, from: RouteState | null, next: () => Promise<void>) => GuardResult;
36
36
  /**
37
37
  * Server middleware function. Receives the raw Node.js `req`/`res` pair and a `next`
38
38
  * callback. Call `next()` to pass control to the next middleware in the chain,
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/types/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAA;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAA;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,UAAU,GAAG,IAAI,EACvB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KACtB,WAAW,GAAG,IAAI,CAAA;AAEvB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,KAC1B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/types/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAA;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,UAAU,GAAG,IAAI,EACvB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KACtB,WAAW,CAAA;AAEhB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,KAC1B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}