create-jen-app 1.2.3 → 1.2.4

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 (355) hide show
  1. package/dist/colors.js +0 -17
  2. package/dist/create.js +5 -17
  3. package/dist/generator.js +14 -31
  4. package/dist/index.js +6 -1
  5. package/package.json +1 -1
  6. package/templates/ssr-isr/README.md +77 -0
  7. package/templates/ssr-isr/build.js +118 -0
  8. package/templates/ssr-isr/jen.config.ts +109 -0
  9. package/templates/ssr-isr/jenjs.d.ts +22 -0
  10. package/templates/ssr-isr/lib/api/(hello).js +9 -0
  11. package/templates/ssr-isr/lib/auth/cookie-utils.js +79 -0
  12. package/templates/ssr-isr/lib/auth/index.js +2 -0
  13. package/templates/ssr-isr/lib/auth/jwt.js +57 -0
  14. package/templates/ssr-isr/lib/auth/session.js +92 -0
  15. package/templates/ssr-isr/lib/build/asset-hashing.d.ts +10 -0
  16. package/templates/ssr-isr/lib/build/asset-hashing.js +25 -0
  17. package/templates/ssr-isr/lib/build/asset-manifest.d.ts +11 -0
  18. package/templates/ssr-isr/lib/build/asset-manifest.js +21 -0
  19. package/templates/{static → ssr-isr}/lib/build/build.d.ts +1 -1
  20. package/templates/ssr-isr/lib/build/build.js +141 -0
  21. package/templates/{static → ssr-isr}/lib/build/island-hydration.d.ts +8 -5
  22. package/templates/ssr-isr/lib/build/island-hydration.js +44 -0
  23. package/templates/ssr-isr/lib/build/minifier.d.ts +20 -0
  24. package/templates/ssr-isr/lib/build/minifier.js +46 -0
  25. package/templates/ssr-isr/lib/build/page-renderer.d.ts +17 -0
  26. package/templates/ssr-isr/lib/build/page-renderer.js +28 -0
  27. package/templates/ssr-isr/lib/build/production-build.d.ts +10 -0
  28. package/templates/ssr-isr/lib/build/production-build.js +13 -0
  29. package/templates/ssr-isr/lib/build/ssg-pipeline.d.ts +15 -0
  30. package/templates/ssr-isr/lib/build/ssg-pipeline.js +113 -0
  31. package/templates/ssr-isr/lib/build-tools/build-site.js +36 -0
  32. package/templates/ssr-isr/lib/cache/index.js +10 -0
  33. package/templates/ssr-isr/lib/cache/memory.js +40 -0
  34. package/templates/ssr-isr/lib/cache/redis.js +61 -0
  35. package/templates/ssr-isr/lib/cli/banner.js +28 -0
  36. package/templates/ssr-isr/lib/cli/templates/ssg/jen.config.js +32 -0
  37. package/templates/ssr-isr/lib/cli/templates/ssg/site/index.js +9 -0
  38. package/templates/ssr-isr/lib/cli/templates/ssr/jen.config.js +32 -0
  39. package/templates/ssr-isr/lib/cli/templates/ssr/site/index.js +9 -0
  40. package/templates/ssr-isr/lib/compilers/esbuild-plugins.js +111 -0
  41. package/templates/ssr-isr/lib/compilers/svelte.js +44 -0
  42. package/templates/ssr-isr/lib/compilers/vue.js +90 -0
  43. package/templates/ssr-isr/lib/core/http.js +71 -0
  44. package/templates/ssr-isr/lib/core/middleware-hooks.js +97 -0
  45. package/templates/ssr-isr/lib/core/paths.js +39 -0
  46. package/templates/ssr-isr/lib/core/routes/match.js +47 -0
  47. package/templates/ssr-isr/lib/core/routes/scan.js +190 -0
  48. package/templates/ssr-isr/lib/core/types.js +1 -0
  49. package/templates/ssr-isr/lib/css/compiler.js +74 -0
  50. package/templates/ssr-isr/lib/db/connector.js +42 -0
  51. package/templates/ssr-isr/lib/db/drivers/jdb.js +44 -0
  52. package/templates/ssr-isr/lib/db/drivers/sql.js +182 -0
  53. package/templates/ssr-isr/lib/db/index.js +48 -0
  54. package/templates/ssr-isr/lib/db/types.js +1 -0
  55. package/templates/ssr-isr/lib/graphql/index.js +52 -0
  56. package/templates/ssr-isr/lib/graphql/resolvers.js +25 -0
  57. package/templates/ssr-isr/lib/graphql/schema.js +35 -0
  58. package/templates/ssr-isr/lib/i18n/en.json +4 -0
  59. package/templates/ssr-isr/lib/i18n/es.json +4 -0
  60. package/templates/ssr-isr/lib/i18n/index.js +15 -0
  61. package/templates/ssr-isr/lib/import/jen-import.js +161 -0
  62. package/templates/ssr-isr/lib/index.js +116 -0
  63. package/templates/ssr-isr/lib/jdb/engine.js +275 -0
  64. package/templates/ssr-isr/lib/jdb/index.js +34 -0
  65. package/templates/ssr-isr/lib/jdb/types.js +1 -0
  66. package/templates/ssr-isr/lib/jdb/utils.js +176 -0
  67. package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.js +0 -17
  68. package/templates/ssr-isr/lib/middleware/builtins/cors.js +54 -0
  69. package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.js +0 -17
  70. package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.js +0 -17
  71. package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.js +0 -17
  72. package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.js +0 -17
  73. package/templates/ssr-isr/lib/middleware/context.js +124 -0
  74. package/templates/{static → ssr-isr}/lib/middleware/decorators.js +0 -17
  75. package/templates/{static → ssr-isr}/lib/middleware/errors/handler.js +0 -17
  76. package/templates/ssr-isr/lib/middleware/errors/http-error.js +10 -0
  77. package/templates/ssr-isr/lib/middleware/kernel.js +85 -0
  78. package/templates/ssr-isr/lib/middleware/pipeline.js +148 -0
  79. package/templates/ssr-isr/lib/middleware/registry.js +85 -0
  80. package/templates/ssr-isr/lib/middleware/response.js +107 -0
  81. package/templates/ssr-isr/lib/middleware/types.d.ts +1 -0
  82. package/templates/ssr-isr/lib/middleware/types.js +1 -0
  83. package/templates/ssr-isr/lib/middleware/utils/matcher.js +13 -0
  84. package/templates/{static → ssr-isr}/lib/native/bundle.js +0 -17
  85. package/templates/{static → ssr-isr}/lib/native/dev-server.js +0 -17
  86. package/templates/{static → ssr-isr}/lib/native/index.js +0 -17
  87. package/templates/{static → ssr-isr}/lib/native/optimizer.js +0 -17
  88. package/templates/ssr-isr/lib/native/style-compiler.js +19 -0
  89. package/templates/ssr-isr/lib/plugin/loader.js +36 -0
  90. package/templates/ssr-isr/lib/runtime/client-runtime.js +25 -0
  91. package/templates/ssr-isr/lib/runtime/hmr.js +59 -0
  92. package/templates/ssr-isr/lib/runtime/hydrate.js +55 -0
  93. package/templates/ssr-isr/lib/runtime/island-hydration-client.js +146 -0
  94. package/templates/ssr-isr/lib/runtime/islands.js +110 -0
  95. package/templates/ssr-isr/lib/runtime/render.js +244 -0
  96. package/templates/ssr-isr/lib/server/api-routes.js +237 -0
  97. package/templates/ssr-isr/lib/server/api.js +108 -0
  98. package/templates/ssr-isr/lib/server/app.js +438 -0
  99. package/templates/ssr-isr/lib/server/runtimeServe.js +169 -0
  100. package/templates/ssr-isr/lib/server/ssr.js +202 -0
  101. package/templates/ssr-isr/lib/shared/log.js +64 -0
  102. package/templates/ssr-isr/package.json +23 -0
  103. package/templates/ssr-isr/server.js +128 -0
  104. package/templates/ssr-isr/site/pages/(index).tsx +11 -0
  105. package/templates/ssr-isr/site/styles/global.scss +37 -0
  106. package/templates/ssr-isr/tsconfig.json +39 -0
  107. package/templates/static/build.js +30 -18
  108. package/templates/static/jen.config.ts +0 -18
  109. package/templates/static/jenjs.d.ts +0 -18
  110. package/templates/static/lib/api/(hello).js +0 -17
  111. package/templates/static/lib/api/examples/files/[...slug].js +22 -0
  112. package/templates/static/lib/api/examples/hello.js +11 -0
  113. package/templates/static/lib/api/examples/posts/[id].js +37 -0
  114. package/templates/static/lib/api/examples/posts.js +37 -0
  115. package/templates/static/lib/api/examples/search.js +23 -0
  116. package/templates/static/lib/api/index.js +41 -0
  117. package/templates/static/lib/api/loader.js +234 -0
  118. package/templates/static/lib/api/router.js +259 -0
  119. package/templates/static/lib/assets/types.js +1 -0
  120. package/templates/static/lib/auth/cookie-utils.js +3 -16
  121. package/templates/static/lib/auth/index.js +0 -17
  122. package/templates/static/lib/auth/jwt.js +0 -17
  123. package/templates/static/lib/auth/session.js +0 -17
  124. package/templates/static/lib/build/asset-hashing.js +44 -36
  125. package/templates/static/lib/build/asset-manifest.js +16 -33
  126. package/templates/static/lib/build/build.js +270 -125
  127. package/templates/static/lib/build/bundle-analyzer-ui.js +417 -0
  128. package/templates/static/lib/build/bundle-analyzer.js +945 -0
  129. package/templates/static/lib/build/code-splitter.js +194 -0
  130. package/templates/static/lib/build/feature-analyzer.js +190 -0
  131. package/templates/static/lib/build/feature-gate.js +257 -0
  132. package/templates/static/lib/build/island-hydration.js +17 -35
  133. package/templates/static/lib/build/lazy-loader.js +322 -0
  134. package/templates/static/lib/build/minifier.js +40 -59
  135. package/templates/static/lib/build/page-renderer.js +23 -40
  136. package/templates/static/lib/build/production-build.js +9 -26
  137. package/templates/static/lib/build/rust-hashing.js +71 -0
  138. package/templates/static/lib/build/script-optimizer.js +285 -0
  139. package/templates/static/lib/build/ssg-pipeline.js +100 -106
  140. package/templates/static/lib/build/vercel-output.js +298 -0
  141. package/templates/static/lib/build-tools/build-site.js +0 -17
  142. package/templates/static/lib/cache/index.js +0 -17
  143. package/templates/static/lib/cache/memory.js +0 -17
  144. package/templates/static/lib/cache/redis.js +0 -17
  145. package/templates/static/lib/cli/banner.js +0 -17
  146. package/templates/static/lib/cli/templates/ssg/jen.config.js +0 -17
  147. package/templates/static/lib/cli/templates/ssr/jen.config.js +0 -17
  148. package/templates/static/lib/client/Image.js +42 -0
  149. package/templates/static/lib/client/Link.js +190 -0
  150. package/templates/static/lib/client/PWA.js +46 -0
  151. package/templates/static/lib/client/Seo.js +97 -0
  152. package/templates/static/lib/client/index.js +9 -0
  153. package/templates/static/lib/client/useNavigation.js +25 -0
  154. package/templates/static/lib/client/useRouter.js +64 -0
  155. package/templates/static/lib/client-routing/Link.js +17 -0
  156. package/templates/static/lib/client-routing/index.js +19 -0
  157. package/templates/static/lib/client-routing/router.js +151 -0
  158. package/templates/static/lib/client-routing/signal.js +147 -0
  159. package/templates/static/lib/compilers/esbuild-plugins.js +0 -17
  160. package/templates/static/lib/compilers/svelte.js +0 -17
  161. package/templates/static/lib/compilers/vue.js +0 -17
  162. package/templates/static/lib/core/config.js +0 -17
  163. package/templates/static/lib/core/feature-guard.js +136 -0
  164. package/templates/static/lib/core/features.js +99 -0
  165. package/templates/static/lib/core/http.js +0 -17
  166. package/templates/static/lib/core/layouts/index.js +10 -0
  167. package/templates/static/lib/core/layouts/render.js +158 -0
  168. package/templates/static/lib/core/layouts/scan.js +112 -0
  169. package/templates/static/lib/core/layouts/types.js +1 -0
  170. package/templates/static/lib/core/lifecycle.js +129 -0
  171. package/templates/static/lib/core/loader-schema.js +81 -0
  172. package/templates/static/lib/core/middleware-hooks.js +0 -17
  173. package/templates/static/lib/core/paths.js +0 -17
  174. package/templates/static/lib/core/routes/advanced.js +114 -0
  175. package/templates/static/lib/core/routes/handlers.js +181 -0
  176. package/templates/static/lib/core/routes/match.js +89 -17
  177. package/templates/static/lib/core/routes/orchestrator.js +171 -0
  178. package/templates/static/lib/core/routes/rendering-config.js +131 -0
  179. package/templates/static/lib/core/routes/scan.js +0 -17
  180. package/templates/static/lib/core/types.js +0 -17
  181. package/templates/static/lib/css/compiler.js +1 -18
  182. package/templates/static/lib/data-fetching/cache.js +223 -0
  183. package/templates/static/lib/data-fetching/client.js +202 -0
  184. package/templates/static/lib/data-fetching/feature-guard.js +29 -0
  185. package/templates/static/lib/data-fetching/graphql.js +265 -0
  186. package/templates/static/lib/data-fetching/index.js +57 -0
  187. package/templates/static/lib/data-fetching/rest.js +256 -0
  188. package/templates/static/lib/data-fetching/server.js +182 -0
  189. package/templates/static/lib/data-fetching/types.js +5 -0
  190. package/templates/static/lib/db/connector.js +0 -17
  191. package/templates/static/lib/db/drivers/jdb.js +0 -17
  192. package/templates/static/lib/db/drivers/sql.js +0 -17
  193. package/templates/static/lib/db/index.js +0 -17
  194. package/templates/static/lib/db/types.js +0 -17
  195. package/templates/static/lib/devtools/component-tree.js +106 -0
  196. package/templates/static/lib/devtools/devtools.js +638 -0
  197. package/templates/static/lib/devtools/event-bus.js +29 -0
  198. package/templates/static/lib/devtools/event-logger.js +67 -0
  199. package/templates/static/lib/devtools/index.js +9 -0
  200. package/templates/static/lib/devtools/integration.js +149 -0
  201. package/templates/static/lib/devtools/performance.js +84 -0
  202. package/templates/static/lib/devtools/persistence.js +57 -0
  203. package/templates/static/lib/devtools/plugins.js +97 -0
  204. package/templates/static/lib/devtools/search.js +89 -0
  205. package/templates/static/lib/devtools/ui.js +769 -0
  206. package/templates/static/lib/features/api/handler.js +10 -0
  207. package/templates/static/lib/features/api/index.js +5 -0
  208. package/templates/static/lib/features/api/types.js +4 -0
  209. package/templates/static/lib/features/middleware/compiled.js +7 -0
  210. package/templates/static/lib/features/middleware/index.js +5 -0
  211. package/templates/static/lib/features/middleware/types.js +4 -0
  212. package/templates/static/lib/fonts/index.js +46 -0
  213. package/templates/static/lib/fonts/inject.js +125 -0
  214. package/templates/static/lib/fonts/loader.js +196 -0
  215. package/templates/static/lib/fonts/types.js +1 -0
  216. package/templates/static/lib/graphql/index.js +1 -18
  217. package/templates/static/lib/graphql/resolvers.js +20 -13
  218. package/templates/static/lib/graphql/schema.js +0 -17
  219. package/templates/static/lib/i18n/index.js +7 -19
  220. package/templates/static/lib/import/jen-import.js +1 -18
  221. package/templates/static/lib/index.js +79 -125
  222. package/templates/static/lib/jdb/engine.js +0 -17
  223. package/templates/static/lib/jdb/index.js +1 -18
  224. package/templates/static/lib/jdb/types.js +0 -17
  225. package/templates/static/lib/jdb/utils.js +0 -17
  226. package/templates/static/lib/middleware/builtins/cors.js +3 -16
  227. package/templates/static/lib/middleware/context.js +0 -17
  228. package/templates/static/lib/middleware/kernel.js +117 -25
  229. package/templates/static/lib/middleware/pipeline.js +0 -17
  230. package/templates/static/lib/middleware/registry.js +0 -17
  231. package/templates/static/lib/middleware/response.js +0 -17
  232. package/templates/static/lib/plugin/examples/analytics-plugin.js +183 -0
  233. package/templates/static/lib/plugin/examples/cdn-upload-plugin.js +94 -0
  234. package/templates/static/lib/plugin/loader.js +0 -17
  235. package/templates/static/lib/plugin/plugin-manager.js +177 -0
  236. package/templates/static/lib/plugin/types.js +28 -0
  237. package/templates/static/lib/runtime/client-runtime.js +0 -17
  238. package/templates/static/lib/runtime/hmr.js +0 -17
  239. package/templates/static/lib/runtime/hydrate.js +0 -17
  240. package/templates/static/lib/runtime/island-hydration-client.js +0 -17
  241. package/templates/static/lib/runtime/islands.js +0 -17
  242. package/templates/static/lib/runtime/render.js +208 -50
  243. package/templates/static/lib/security/security-config.js +60 -0
  244. package/templates/static/lib/security/security-middleware.js +229 -0
  245. package/templates/static/lib/server/api-routes.js +153 -43
  246. package/templates/static/lib/server/api.js +0 -17
  247. package/templates/static/lib/server/app.js +539 -223
  248. package/templates/static/lib/server/isr.js +365 -0
  249. package/templates/static/lib/server/runtimeServe.js +31 -24
  250. package/templates/static/lib/server/ssr.js +98 -22
  251. package/templates/static/lib/server-actions/handler.js +180 -0
  252. package/templates/static/lib/server-actions/index.js +19 -0
  253. package/templates/static/lib/server-actions/middleware.js +146 -0
  254. package/templates/static/lib/server-actions/scan.js +152 -0
  255. package/templates/static/lib/server-actions/types.js +1 -0
  256. package/templates/static/lib/server-actions/validators.js +156 -0
  257. package/templates/static/lib/shared/log.js +19 -20
  258. package/templates/static/lib/telemetry/api/rate-limiter.js +32 -0
  259. package/templates/static/lib/telemetry/api/validator.js +67 -0
  260. package/templates/static/lib/telemetry/client.js +121 -0
  261. package/templates/static/lib/telemetry/tests/rate-limiter.test.js +46 -0
  262. package/templates/static/lib/telemetry/tests/validator.test.js +62 -0
  263. package/templates/static/lib/vendor/glob/glob.js +4766 -0
  264. package/templates/static/lib/vendor/preact/LICENSE +21 -0
  265. package/templates/static/lib/vendor/preact/preact.module.js +797 -0
  266. package/templates/static/lib/vendor/sass/sass.node.mjs +212 -0
  267. package/templates/static/package.json +4 -0
  268. package/templates/static/server.js +22 -22
  269. package/templates/static/site/(home).tsx +0 -18
  270. package/templates/static/tsconfig.json +5 -1
  271. package/templates/static/.esbuild/jen.config.js +0 -19
  272. package/templates/static/lib/build/asset-hashing.d.ts +0 -10
  273. package/templates/static/lib/build/asset-manifest.d.ts +0 -11
  274. package/templates/static/lib/build/minifier.d.ts +0 -20
  275. package/templates/static/lib/build/page-renderer.d.ts +0 -17
  276. package/templates/static/lib/build/production-build.d.ts +0 -10
  277. package/templates/static/lib/build/ssg-pipeline.d.ts +0 -15
  278. package/templates/static/lib/middleware/errors/http-error.js +0 -27
  279. package/templates/static/lib/middleware/types.js +0 -18
  280. package/templates/static/lib/middleware/utils/matcher.js +0 -30
  281. package/templates/static/lib/native/style-compiler.js +0 -36
  282. /package/templates/{static → ssr-isr}/lib/api/(hello).d.ts +0 -0
  283. /package/templates/{static → ssr-isr}/lib/auth/cookie-utils.d.ts +0 -0
  284. /package/templates/{static → ssr-isr}/lib/auth/index.d.ts +0 -0
  285. /package/templates/{static → ssr-isr}/lib/auth/jwt.d.ts +0 -0
  286. /package/templates/{static → ssr-isr}/lib/auth/session.d.ts +0 -0
  287. /package/templates/{static → ssr-isr}/lib/build-tools/build-site.d.ts +0 -0
  288. /package/templates/{static → ssr-isr}/lib/cache/index.d.ts +0 -0
  289. /package/templates/{static → ssr-isr}/lib/cache/memory.d.ts +0 -0
  290. /package/templates/{static → ssr-isr}/lib/cache/redis.d.ts +0 -0
  291. /package/templates/{static → ssr-isr}/lib/cli/banner.d.ts +0 -0
  292. /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/jen.config.d.ts +0 -0
  293. /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/site/index.d.ts +0 -0
  294. /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/jen.config.d.ts +0 -0
  295. /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/site/index.d.ts +0 -0
  296. /package/templates/{static → ssr-isr}/lib/compilers/esbuild-plugins.d.ts +0 -0
  297. /package/templates/{static → ssr-isr}/lib/compilers/svelte.d.ts +0 -0
  298. /package/templates/{static → ssr-isr}/lib/compilers/vue.d.ts +0 -0
  299. /package/templates/{static → ssr-isr}/lib/core/config.d.ts +0 -0
  300. /package/templates/{static/lib/middleware/types.d.ts → ssr-isr/lib/core/config.js} +0 -0
  301. /package/templates/{static → ssr-isr}/lib/core/http.d.ts +0 -0
  302. /package/templates/{static → ssr-isr}/lib/core/middleware-hooks.d.ts +0 -0
  303. /package/templates/{static → ssr-isr}/lib/core/paths.d.ts +0 -0
  304. /package/templates/{static → ssr-isr}/lib/core/routes/match.d.ts +0 -0
  305. /package/templates/{static → ssr-isr}/lib/core/routes/scan.d.ts +0 -0
  306. /package/templates/{static → ssr-isr}/lib/core/types.d.ts +0 -0
  307. /package/templates/{static → ssr-isr}/lib/css/compiler.d.ts +0 -0
  308. /package/templates/{static → ssr-isr}/lib/db/connector.d.ts +0 -0
  309. /package/templates/{static → ssr-isr}/lib/db/drivers/jdb.d.ts +0 -0
  310. /package/templates/{static → ssr-isr}/lib/db/drivers/sql.d.ts +0 -0
  311. /package/templates/{static → ssr-isr}/lib/db/index.d.ts +0 -0
  312. /package/templates/{static → ssr-isr}/lib/db/types.d.ts +0 -0
  313. /package/templates/{static → ssr-isr}/lib/graphql/index.d.ts +0 -0
  314. /package/templates/{static → ssr-isr}/lib/graphql/resolvers.d.ts +0 -0
  315. /package/templates/{static → ssr-isr}/lib/graphql/schema.d.ts +0 -0
  316. /package/templates/{static → ssr-isr}/lib/i18n/index.d.ts +0 -0
  317. /package/templates/{static → ssr-isr}/lib/import/jen-import.d.ts +0 -0
  318. /package/templates/{static → ssr-isr}/lib/index.d.ts +0 -0
  319. /package/templates/{static → ssr-isr}/lib/jdb/engine.d.ts +0 -0
  320. /package/templates/{static → ssr-isr}/lib/jdb/index.d.ts +0 -0
  321. /package/templates/{static → ssr-isr}/lib/jdb/types.d.ts +0 -0
  322. /package/templates/{static → ssr-isr}/lib/jdb/utils.d.ts +0 -0
  323. /package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.d.ts +0 -0
  324. /package/templates/{static → ssr-isr}/lib/middleware/builtins/cors.d.ts +0 -0
  325. /package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.d.ts +0 -0
  326. /package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.d.ts +0 -0
  327. /package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.d.ts +0 -0
  328. /package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.d.ts +0 -0
  329. /package/templates/{static → ssr-isr}/lib/middleware/context.d.ts +0 -0
  330. /package/templates/{static → ssr-isr}/lib/middleware/decorators.d.ts +0 -0
  331. /package/templates/{static → ssr-isr}/lib/middleware/errors/handler.d.ts +0 -0
  332. /package/templates/{static → ssr-isr}/lib/middleware/errors/http-error.d.ts +0 -0
  333. /package/templates/{static → ssr-isr}/lib/middleware/kernel.d.ts +0 -0
  334. /package/templates/{static → ssr-isr}/lib/middleware/pipeline.d.ts +0 -0
  335. /package/templates/{static → ssr-isr}/lib/middleware/registry.d.ts +0 -0
  336. /package/templates/{static → ssr-isr}/lib/middleware/response.d.ts +0 -0
  337. /package/templates/{static → ssr-isr}/lib/middleware/utils/matcher.d.ts +0 -0
  338. /package/templates/{static → ssr-isr}/lib/native/bundle.d.ts +0 -0
  339. /package/templates/{static → ssr-isr}/lib/native/dev-server.d.ts +0 -0
  340. /package/templates/{static → ssr-isr}/lib/native/index.d.ts +0 -0
  341. /package/templates/{static → ssr-isr}/lib/native/optimizer.d.ts +0 -0
  342. /package/templates/{static → ssr-isr}/lib/native/style-compiler.d.ts +0 -0
  343. /package/templates/{static → ssr-isr}/lib/plugin/loader.d.ts +0 -0
  344. /package/templates/{static → ssr-isr}/lib/runtime/client-runtime.d.ts +0 -0
  345. /package/templates/{static → ssr-isr}/lib/runtime/hmr.d.ts +0 -0
  346. /package/templates/{static → ssr-isr}/lib/runtime/hydrate.d.ts +0 -0
  347. /package/templates/{static → ssr-isr}/lib/runtime/island-hydration-client.d.ts +0 -0
  348. /package/templates/{static → ssr-isr}/lib/runtime/islands.d.ts +0 -0
  349. /package/templates/{static → ssr-isr}/lib/runtime/render.d.ts +0 -0
  350. /package/templates/{static → ssr-isr}/lib/server/api-routes.d.ts +0 -0
  351. /package/templates/{static → ssr-isr}/lib/server/api.d.ts +0 -0
  352. /package/templates/{static → ssr-isr}/lib/server/app.d.ts +0 -0
  353. /package/templates/{static → ssr-isr}/lib/server/runtimeServe.d.ts +0 -0
  354. /package/templates/{static → ssr-isr}/lib/server/ssr.d.ts +0 -0
  355. /package/templates/{static → ssr-isr}/lib/shared/log.d.ts +0 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Middleware composition and execution engine.
3
+ * Composes multiple middleware functions into a single callable function.
4
+ * Supports functions, class constructors, and objects with handle() methods.
5
+ *
6
+ * The Pipeline implements the "cascade" or "onion" middleware pattern:
7
+ * - Middlewares are executed sequentially in order
8
+ * - Each middleware receives a next() function to pass control to the next handler
9
+ * - Execution returns through each middleware in reverse order
10
+ * - Early termination is possible by not calling next()
11
+ *
12
+ * @example
13
+ * const middlewares = [
14
+ * (ctx, next) => { console.log("1 start"); next().then(() => console.log("1 end")); },
15
+ * (ctx, next) => { console.log("2 start"); next().then(() => console.log("2 end")); },
16
+ * ];
17
+ * // Logs: "1 start", "2 start", "2 end", "1 end" (onion pattern)
18
+ */
19
+ export class Pipeline {
20
+ /**
21
+ * Composes an array of middleware into a single callable function.
22
+ * The composed function accepts (context, finalNext) and executes middlewares in sequence.
23
+ *
24
+ * Middleware resolution:
25
+ * - Functions are passed through as-is
26
+ * - Class constructors (functions with prototype.handle) are instantiated and their handle() bound
27
+ * - Objects with handle() methods have handle() bound to them
28
+ *
29
+ * @param middleware Array of middleware to compose
30
+ * @returns Composed function: async (context, next) => Promise<void>
31
+ *
32
+ * @throws {TypeError} If middleware is not an array
33
+ * @throws {TypeError} If a middleware is not a function, class, or object with handle()
34
+ *
35
+ * @example
36
+ * const composed = Pipeline.compose([authMiddleware, loggingMiddleware]);
37
+ * await composed(ctx, () => console.log("done"));
38
+ */
39
+ static compose(middleware) {
40
+ if (!Array.isArray(middleware))
41
+ throw new TypeError("Middleware stack must be an array!");
42
+ /**
43
+ * Resolve each middleware to a callable function.
44
+ * Handles functions, class constructors, and objects with handle() methods.
45
+ */
46
+ const handlers = middleware.map((mw) => this.resolveMiddleware(mw));
47
+ /**
48
+ * Returns the composed middleware function that executes the pipeline.
49
+ * Uses the dispatch() pattern to enforce single-next-call and maintain order.
50
+ *
51
+ * @param context Request context object passed to each middleware
52
+ * @param next Final handler called after all middlewares
53
+ * @returns Promise that resolves when entire pipeline completes
54
+ */
55
+ return function (context, next) {
56
+ /**
57
+ * Tracks the current dispatch index to detect "next() called multiple times".
58
+ * This prevents middleware from accidentally calling next() twice,
59
+ * which would cause handlers to execute in wrong order.
60
+ */
61
+ let index = -1;
62
+ /**
63
+ * Dispatches (executes) the middleware at index i.
64
+ * Enforces that next() can only be called once by checking index increment.
65
+ *
66
+ * @param i Index of the middleware to execute
67
+ * @returns Promise from the middleware or final next() handler
68
+ */
69
+ function dispatch(i) {
70
+ if (i <= index)
71
+ return Promise.reject(new Error("next() called multiple times"));
72
+ index = i;
73
+ let fn = handlers[i];
74
+ /**
75
+ * If we've exhausted all middlewares, call the final next() handler.
76
+ * This allows code after Pipeline.compose() to run.
77
+ */
78
+ if (i === handlers.length) {
79
+ fn = next;
80
+ }
81
+ if (!fn) return Promise.resolve();
82
+ try {
83
+ /**
84
+ * Execute the middleware function, passing:
85
+ * - context: the request context object
86
+ * - dispatch.bind(null, i + 1): the next() function for chaining
87
+ *
88
+ * Promise.resolve() wraps non-promise returns for consistency.
89
+ */
90
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
91
+ } catch (err) {
92
+ return Promise.reject(err);
93
+ }
94
+ }
95
+ /**
96
+ * Start the pipeline at the first middleware (index 0).
97
+ */
98
+ return dispatch(0);
99
+ };
100
+ }
101
+ /**
102
+ * Resolves a middleware to a callable (context, next) => Promise function.
103
+ * Supports three forms:
104
+ * 1. Function: Used directly
105
+ * 2. Class constructor with handle() method: Instantiated and bound
106
+ * 3. Object with handle() method: handle() method is bound
107
+ *
108
+ * @param mw Middleware in one of the above forms
109
+ * @returns Callable (context, next) => Promise function
110
+ *
111
+ * @throws {TypeError} If mw is not a recognized middleware type
112
+ */
113
+ static resolveMiddleware(mw) {
114
+ if (typeof mw === "function") {
115
+ /**
116
+ * Check if this is a class constructor with a handle() method.
117
+ * Constructors have a prototype property with methods defined on it.
118
+ */
119
+ if (
120
+ "prototype" in mw &&
121
+ mw.prototype &&
122
+ typeof mw.prototype.handle === "function"
123
+ ) {
124
+ try {
125
+ const instance = new mw();
126
+ return instance.handle.bind(instance);
127
+ } catch (e) {
128
+ /**
129
+ * If instantiation fails (constructor requires params),
130
+ * assume it's a simple function middleware and use it directly.
131
+ */
132
+ return mw;
133
+ }
134
+ }
135
+ return mw;
136
+ }
137
+ /**
138
+ * Check for object with handle() method.
139
+ * Useful for class instances or middleware objects.
140
+ */
141
+ if (typeof mw === "object" && mw !== null && "handle" in mw) {
142
+ return mw.handle.bind(mw);
143
+ }
144
+ throw new TypeError(
145
+ "Middleware must be a function, a class constructor, or an object with a handle() method",
146
+ );
147
+ }
148
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Global registry for named middleware and middleware groups.
3
+ * Enables reusable middleware composition patterns where middlewares are registered once
4
+ * and then referenced by name in groups or applied globally.
5
+ *
6
+ * The registry follows the singleton pattern to maintain a single shared instance
7
+ * throughout the application lifecycle.
8
+ *
9
+ * @example
10
+ * const registry = MiddlewareRegistry.get();
11
+ * registry.register('auth', authMiddleware);
12
+ * registry.register('logger', loggingMiddleware);
13
+ * registry.group('api', ['auth', 'logger']);
14
+ * // Later, get the group to apply to routes
15
+ * const apiMw = registry.getGroup('api'); // [authMiddleware, loggingMiddleware]
16
+ */
17
+ export class MiddlewareRegistry {
18
+ // Singleton instance shared across the application.
19
+ static instance;
20
+ // Map of named middleware functions.
21
+ middleware = new Map();
22
+ // Map of middleware group definitions (groups contain names of registered middleware).
23
+ groups = new Map();
24
+ constructor() {}
25
+ /**
26
+ * Gets or creates the singleton registry instance.
27
+ * All calls to this method return the same instance, ensuring a single registry.
28
+ *
29
+ * @returns The singleton MiddlewareRegistry instance.
30
+ */
31
+ static get() {
32
+ if (!this.instance) this.instance = new MiddlewareRegistry();
33
+ return this.instance;
34
+ }
35
+ /**
36
+ * Registers a middleware function with a name.
37
+ * Named middleware can be referenced in groups or applied individually.
38
+ *
39
+ * @param name Unique identifier for the middleware.
40
+ * @param mw The middleware function to register.
41
+ *
42
+ * @example
43
+ * registry.register('cors', corsMiddleware);
44
+ */
45
+ register(name, mw) {
46
+ this.middleware.set(name, mw);
47
+ }
48
+ /**
49
+ * Retrieves a registered middleware by name.
50
+ *
51
+ * @param name The name of the middleware to retrieve.
52
+ * @returns The middleware function, or undefined if not found.
53
+ */
54
+ get(name) {
55
+ return this.middleware.get(name);
56
+ }
57
+ /**
58
+ * Defines a group of middleware by names.
59
+ * Groups allow composing multiple middleware into a named set that can be applied together.
60
+ *
61
+ * @param groupName The name of the group.
62
+ * @param middlewareNames Array of registered middleware names to include in the group.
63
+ *
64
+ * @example
65
+ * registry.group('secure', ['auth', 'rateLimit', 'securityHeaders']);
66
+ */
67
+ group(groupName, middlewareNames) {
68
+ this.groups.set(groupName, middlewareNames);
69
+ }
70
+ /**
71
+ * Retrieves all middleware functions in a named group.
72
+ * Resolves group names to actual middleware functions.
73
+ * Skips missing middleware names gracefully.
74
+ *
75
+ * @param groupName The name of the group to retrieve.
76
+ * @returns Array of middleware functions in the group (in order).
77
+ *
78
+ * @example
79
+ * const middlewares = registry.getGroup('secure'); // [authFn, rateLimitFn, securityHeadersFn]
80
+ */
81
+ getGroup(groupName) {
82
+ const names = this.groups.get(groupName) || [];
83
+ return names.map((n) => this.get(n)).filter((m) => !!m);
84
+ }
85
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Fluent builder for constructing HTTP responses.
3
+ * Provides a chainable API for setting status codes, headers, body, and content type.
4
+ * Delegates actual response sending to the underlying Node.js ServerResponse.
5
+ *
6
+ * This builder is used in the Context to provide convenient response composition
7
+ * without manually managing headers and response state.
8
+ *
9
+ * @example
10
+ * ctx.response
11
+ * .status(201)
12
+ * .header('X-Custom', 'value')
13
+ * .json({ id: 123, name: 'Alice' })
14
+ * .send();
15
+ */
16
+ export class ResponseBuilder {
17
+ // HTTP status code to send (default 200 OK).
18
+ statusCode = 200;
19
+ // Header key-value pairs to include in the response.
20
+ headers = {};
21
+ // Response body content (string, Buffer, or null for empty body).
22
+ body = null;
23
+ // The underlying Node.js ServerResponse object.
24
+ res;
25
+ /**
26
+ * Initializes a ResponseBuilder with the given ServerResponse.
27
+ *
28
+ * @param res The Node.js ServerResponse object to write to.
29
+ */
30
+ constructor(res) {
31
+ this.res = res;
32
+ }
33
+ /**
34
+ * Sets the HTTP status code for the response.
35
+ *
36
+ * @param code The HTTP status code (e.g., 200, 404, 500).
37
+ * @returns This ResponseBuilder instance for method chaining.
38
+ */
39
+ status(code) {
40
+ this.statusCode = code;
41
+ return this;
42
+ }
43
+ /**
44
+ * Adds an HTTP response header.
45
+ * Multiple calls with the same key overwrite previous values.
46
+ *
47
+ * @param key The header name.
48
+ * @param value The header value.
49
+ * @returns This ResponseBuilder instance for method chaining.
50
+ */
51
+ header(key, value) {
52
+ this.headers[key] = value;
53
+ return this;
54
+ }
55
+ /**
56
+ * Sets the response body to a JSON-serialized object and sets Content-Type header.
57
+ * Automatically sets Content-Type to application/json.
58
+ *
59
+ * @param data The object to serialize as JSON.
60
+ * @returns This ResponseBuilder instance for method chaining.
61
+ */
62
+ json(data) {
63
+ this.header("Content-Type", "application/json");
64
+ this.body = JSON.stringify(data);
65
+ return this;
66
+ }
67
+ /**
68
+ * Sets the response body to HTML content and sets Content-Type header.
69
+ * Automatically sets Content-Type to text/html.
70
+ *
71
+ * @param html The HTML string to send.
72
+ * @returns This ResponseBuilder instance for method chaining.
73
+ */
74
+ html(html) {
75
+ this.header("Content-Type", "text/html");
76
+ this.body = html;
77
+ return this;
78
+ }
79
+ /**
80
+ * Sets the response body to plain text and sets Content-Type header.
81
+ * Automatically sets Content-Type to text/plain.
82
+ *
83
+ * @param text The plain text string to send.
84
+ * @returns This ResponseBuilder instance for method chaining.
85
+ */
86
+ text(text) {
87
+ this.header("Content-Type", "text/plain");
88
+ this.body = text;
89
+ return this;
90
+ }
91
+ /**
92
+ * Sends the response to the client.
93
+ * Writes the status code, headers, and body to the underlying ServerResponse.
94
+ * Does nothing if the response has already been sent (writableEnded is true).
95
+ *
96
+ * @returns Void. The underlying res.end() return value is not propagated.
97
+ */
98
+ send() {
99
+ if (this.res.writableEnded) return;
100
+ this.res.writeHead(this.statusCode, this.headers);
101
+ if (this.body !== null && this.body !== undefined) {
102
+ this.res.end(this.body);
103
+ } else {
104
+ this.res.end();
105
+ }
106
+ }
107
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ export function matchPath(pattern, path) {
2
+ if (pattern === "*") return true;
3
+ if (pattern === path) return true;
4
+ // Basic glob: * matches anything
5
+ const regexString =
6
+ "^" +
7
+ pattern
8
+ .replace(/[.+?^${}()|[\\]/g, "\\$&") // escape regex characters
9
+ .replace(/\*/g, ".*") +
10
+ "$"; // convert * to .*
11
+ const regex = new RegExp(regexString);
12
+ return regex.test(path);
13
+ }
@@ -1,20 +1,3 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
1
  // Native bundler (C++ stub)
19
2
  // High-performance bundler for assets and code
20
3
  // Currently: esbuild wrapper (use native C++ bundler in production)
@@ -1,20 +1,3 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
1
  // Native dev server (Rust stub)
19
2
  // Provides high-performance development server
20
3
  // Currently: TypeScript implementation (use Bun or esbuild-serve in production)
@@ -1,20 +1,3 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
1
  // Native modules entry point
19
2
  // Provides high-performance implementations
20
3
  // Note: These are TypeScript stubs. In production, replace with native Rust/C++ bindings.
@@ -1,20 +1,3 @@
1
- /*
2
- * This file is part of Jen.js.
3
- * Copyright (C) 2026 oopsio
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
- */
18
1
  export async function optimize(opts) {
19
2
  console.log(`[OPTIMIZER] Optimizing ${opts.files.length} files`);
20
3
  // Placeholder: simulated optimization results
@@ -0,0 +1,19 @@
1
+ export async function compileScss(opts) {
2
+ // Placeholder: returns CSS placeholder
3
+ console.log(`[STYLE COMPILER] Compiling SCSS: ${opts.input}`);
4
+ const css = `
5
+ /* SCSS compiled from: ${opts.input} */
6
+ /* Note: Full SCSS compilation requires dart-sass or native Rust implementation */
7
+ body { margin: 0; padding: 0; }
8
+ `;
9
+ return css;
10
+ }
11
+ export async function compileCSS(input, minify = false) {
12
+ console.log(`[STYLE COMPILER] Processing CSS: ${input}`);
13
+ // Placeholder: returns input CSS
14
+ return input;
15
+ }
16
+ export async function watchStyles(input, output, onChange) {
17
+ // Placeholder watcher
18
+ console.log(`[STYLE COMPILER] Watching: ${input}`);
19
+ }
@@ -0,0 +1,36 @@
1
+ // Plugin loader
2
+ // Migrated from Python src/python/plugins.py
3
+ import { readdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { pathToFileURL } from "node:url";
6
+ import { log } from "../shared/log.js";
7
+ const PLUGIN_DIR = "src/plugin/plugins";
8
+ export async function runPlugins(event = "build") {
9
+ log.info(`Running plugins (${event})...`);
10
+ try {
11
+ const files = readdirSync(PLUGIN_DIR);
12
+ for (const file of files) {
13
+ if (!file.endsWith(".ts") && !file.endsWith(".js")) continue;
14
+ const pluginPath = join(process.cwd(), PLUGIN_DIR, file);
15
+ const pluginUrl = pathToFileURL(pluginPath).href;
16
+ try {
17
+ const module = await import(pluginUrl);
18
+ const plugin = module.default;
19
+ if (!plugin) continue;
20
+ log.info(` Loading plugin: ${plugin.name}`);
21
+ if (event === "build" && plugin.onBuild) {
22
+ await plugin.onBuild();
23
+ } else if (event === "serve" && plugin.onServe) {
24
+ await plugin.onServe();
25
+ } else if (event === "deploy" && plugin.onDeploy) {
26
+ await plugin.onDeploy();
27
+ }
28
+ } catch (err) {
29
+ log.error(` Plugin error: ${file} - ${String(err)}`);
30
+ }
31
+ }
32
+ log.info("Plugins executed.");
33
+ } catch (err) {
34
+ log.warn(`Plugin directory not found: ${PLUGIN_DIR}`);
35
+ }
36
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Retrieve framework data injected by the server into the page HTML.
3
+ * The server embeds loader result data, route params, and query parameters
4
+ * into a hidden DOM element with id "__FRAMEWORK_DATA__" as JSON.
5
+ *
6
+ * This data is passed to page components during hydration as props.
7
+ * Returns null if the element does not exist or JSON is malformed,
8
+ * allowing graceful degradation without throwing errors.
9
+ *
10
+ * Usage:
11
+ * const data = getFrameworkData();
12
+ * // data = { data: {...}, params: {...}, query: {...} }
13
+ *
14
+ * @returns Framework data object { data, params, query } or null if not found.
15
+ */
16
+ export function getFrameworkData() {
17
+ const el = document.getElementById("__FRAMEWORK_DATA__");
18
+ if (!el) return null;
19
+ try {
20
+ return JSON.parse(el.textContent || "null");
21
+ } catch {
22
+ // Silently return null if JSON is invalid; page hydrates with default props
23
+ return null;
24
+ }
25
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Client-side Hot Module Replacement (HMR) / Live Reload code.
3
+ * This script is injected into the browser during development mode.
4
+ *
5
+ * Features:
6
+ * - Establishes Server-Sent Events (SSE) connection to /__hmr endpoint
7
+ * - Listens for "reload" events (full page reload on route/component changes)
8
+ * - Listens for "style-update" events (CSS updates without full reload)
9
+ * - Automatically retries connection if lost
10
+ *
11
+ * The script uses IIFE (Immediately Invoked Function Expression) to avoid
12
+ * polluting the global scope.
13
+ *
14
+ * How it works:
15
+ * 1. Server watches file system for changes
16
+ * 2. On change, server sends SSE event to clients
17
+ * 3. Client receives event and either reloads or updates CSS
18
+ * 4. CSS updates use cache-busting query params to force fresh load
19
+ *
20
+ * Only injected in development mode; production builds do not include this.
21
+ */
22
+ export const HMR_CLIENT_SCRIPT = `
23
+ (function() {
24
+ console.log("[Jen.js] Connecting to HMR...");
25
+ const evt = new EventSource("/__hmr");
26
+
27
+ evt.onopen = () => console.log("[Jen.js] HMR Connected");
28
+
29
+ // Full page reload on route or component changes
30
+ evt.addEventListener("reload", () => {
31
+ console.log("[Jen.js] Reloading...");
32
+ window.location.reload();
33
+ });
34
+
35
+ // CSS-only reload without full page reload (faster UX for style-only changes)
36
+ evt.addEventListener("style-update", (e) => {
37
+ const file = JSON.parse(e.data).file; // e.g., "styles.css"
38
+ console.log("[Jen.js] Style update:", file);
39
+
40
+ // Find matching link tags by pathname
41
+ const links = document.querySelectorAll('link[rel="stylesheet"]');
42
+ for (const link of links) {
43
+ const url = new URL(link.href);
44
+ if (url.pathname.endsWith(file)) {
45
+ // Force reload by updating cache-busting query param (timestamp)
46
+ url.searchParams.set("t", Date.now());
47
+ link.href = url.toString();
48
+ console.log("[Jen.js] Updated stylesheet:", file);
49
+ }
50
+ }
51
+ });
52
+
53
+ evt.onerror = () => {
54
+ // Connection closed; EventSource automatically retries
55
+ // (commented out: chatty in development; uncomment if needed for debugging)
56
+ // console.log("[Jen.js] HMR disconnected, retrying...");
57
+ };
58
+ })();
59
+ `;
@@ -0,0 +1,55 @@
1
+ import { hydrate } from "preact";
2
+ import { h } from "preact";
3
+ import { getFrameworkData } from "./client-runtime.js";
4
+ /**
5
+ * Hydrate a server-rendered page with client-side interactivity.
6
+ * This function is called once on page load in the browser.
7
+ * It attaches Preact event listeners and state management to existing DOM without re-rendering.
8
+ *
9
+ * Flow:
10
+ * 1. Retrieve framework data (loader result, route params, query) injected by server into page HTML
11
+ * 2. Dynamically import the route component module
12
+ * 3. Construct Preact component tree passing data as props
13
+ * 4. Attach to existing #app element (matches server-rendered HTML structure)
14
+ *
15
+ * Errors during hydration are logged but do not throw; the page remains functional
16
+ * with reduced interactivity if hydration fails.
17
+ *
18
+ * @param entryPath - Path to the route component module (e.g., "./routes/index.js")
19
+ * This path is typically injected into the HTML as a script attribute by the server.
20
+ */
21
+ export async function hydrateClient(entryPath) {
22
+ try {
23
+ // Retrieve loader data, params, and query injected into page HTML by server
24
+ const data = getFrameworkData();
25
+ // Dynamically import route component
26
+ const mod = await import(entryPath);
27
+ // Validate that route exports a default component
28
+ if (!mod.default) {
29
+ console.error(
30
+ `Failed to hydrate: route module does not export default component`,
31
+ );
32
+ return;
33
+ }
34
+ // Construct Preact VDOM tree with data as props
35
+ const Page = mod.default;
36
+ const app = h(Page, {
37
+ data: data?.data ?? null,
38
+ params: data?.params ?? {},
39
+ query: data?.query ?? {},
40
+ });
41
+ // Find root DOM element for hydration
42
+ const root = document.getElementById("app");
43
+ if (!root) {
44
+ console.error("Failed to hydrate: #app element not found in DOM");
45
+ return;
46
+ }
47
+ // Attach Preact to existing DOM tree without re-rendering
48
+ hydrate(app, root);
49
+ } catch (err) {
50
+ console.error(
51
+ "Hydration failed:",
52
+ err instanceof Error ? err.message : String(err),
53
+ );
54
+ }
55
+ }