one 1.25.12 → 1.25.15

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 (308) hide show
  1. package/dist/cjs/cli/build.cjs +37 -186
  2. package/dist/cjs/cli/build.native.js +270 -423
  3. package/dist/cjs/cli/build.native.js.map +1 -1
  4. package/dist/cjs/cli/buildPage.cjs +7 -7
  5. package/dist/cjs/cli/buildPage.native.js +7 -7
  6. package/dist/cjs/cli/buildPage.native.js.map +1 -1
  7. package/dist/cjs/cli/buildPageWorker.cjs +1 -1
  8. package/dist/cjs/cli/buildPageWorker.native.js +1 -1
  9. package/dist/cjs/cli/buildPageWorker.native.js.map +1 -1
  10. package/dist/cjs/cli/serverRouteModules.cjs +47 -0
  11. package/dist/cjs/cli/serverRouteModules.native.js +52 -0
  12. package/dist/cjs/cli/serverRouteModules.native.js.map +1 -0
  13. package/dist/cjs/cli/workerPool.native.js.map +1 -1
  14. package/dist/cjs/createApp.cjs +3 -0
  15. package/dist/cjs/createDevHandleRequest.cjs +151 -0
  16. package/dist/cjs/createDevHandleRequest.native.js +194 -0
  17. package/dist/cjs/createDevHandleRequest.native.js.map +1 -0
  18. package/dist/cjs/createHandleRequest.cjs +1 -123
  19. package/dist/cjs/createHandleRequest.native.js +1 -163
  20. package/dist/cjs/createHandleRequest.native.js.map +1 -1
  21. package/dist/cjs/createHandleRequest.test.cjs +25 -25
  22. package/dist/cjs/createHandleRequest.test.native.js +25 -25
  23. package/dist/cjs/createHandleRequest.test.native.js.map +1 -1
  24. package/dist/cjs/headless-server.native.js.map +1 -1
  25. package/dist/cjs/headless.cjs +4 -0
  26. package/dist/cjs/headless.native.js +4 -0
  27. package/dist/cjs/headless.native.js.map +1 -1
  28. package/dist/cjs/layouts/Drawer.cjs +0 -2
  29. package/dist/cjs/layouts/Drawer.native.js.map +1 -1
  30. package/dist/cjs/layouts/Tabs.cjs +0 -2
  31. package/dist/cjs/layouts/Tabs.native.js.map +1 -1
  32. package/dist/cjs/router/diagnoseRouteLoadFailure.native.js.map +1 -1
  33. package/dist/cjs/router/useViteRoutes.cjs +9 -1
  34. package/dist/cjs/router/useViteRoutes.native.js +9 -1
  35. package/dist/cjs/router/useViteRoutes.native.js.map +1 -1
  36. package/dist/cjs/router/web/WebStackView.cjs +0 -2
  37. package/dist/cjs/router/web/WebStackView.native.js +0 -2
  38. package/dist/cjs/router/web/WebStackView.native.js.map +1 -1
  39. package/dist/cjs/serve-worker.cjs +3 -2
  40. package/dist/cjs/serve-worker.native.js +3 -2
  41. package/dist/cjs/serve-worker.native.js.map +1 -1
  42. package/dist/cjs/server/oneServe.cjs +23 -4
  43. package/dist/cjs/server/oneServe.native.js +25 -6
  44. package/dist/cjs/server/oneServe.native.js.map +1 -1
  45. package/dist/cjs/server/routeExportsFromEntry.cjs +47 -0
  46. package/dist/cjs/server/routeExportsFromEntry.native.js +52 -0
  47. package/dist/cjs/server/routeExportsFromEntry.native.js.map +1 -0
  48. package/dist/cjs/server/workerHandler.cjs +30 -12
  49. package/dist/cjs/server/workerHandler.native.js +32 -13
  50. package/dist/cjs/server/workerHandler.native.js.map +1 -1
  51. package/dist/cjs/server/workerHandler.test.cjs +43 -10
  52. package/dist/cjs/server/workerHandler.test.native.js +46 -10
  53. package/dist/cjs/server/workerHandler.test.native.js.map +1 -1
  54. package/dist/cjs/views/ScrollBehavior.native.js.map +1 -1
  55. package/dist/cjs/vite/cloudflareWranglerConfig.cjs +247 -0
  56. package/dist/cjs/vite/cloudflareWranglerConfig.native.js +392 -0
  57. package/dist/cjs/vite/cloudflareWranglerConfig.native.js.map +1 -0
  58. package/dist/cjs/vite/cloudflareWranglerConfig.test.cjs +116 -0
  59. package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js +120 -0
  60. package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
  61. package/dist/cjs/vite/one.cjs +4 -2
  62. package/dist/cjs/vite/one.native.js +8 -6
  63. package/dist/cjs/vite/one.native.js.map +1 -1
  64. package/dist/cjs/vite/plugins/SSRCSSPlugin.cjs +10 -1
  65. package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js +52 -3
  66. package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
  67. package/dist/cjs/vite/plugins/environmentGuardPlugin.cjs +1 -1
  68. package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js +1 -1
  69. package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
  70. package/dist/cjs/vite/plugins/environmentGuardPlugin.test.cjs +4 -0
  71. package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
  72. package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
  73. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.cjs +14 -5
  74. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js +15 -5
  75. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
  76. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.cjs +47 -0
  77. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
  78. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
  79. package/dist/cjs/vite/plugins/virtualEntryPlugin.cjs +9 -7
  80. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js +11 -7
  81. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  82. package/dist/cjs/vite/plugins/virtualEntryPlugin.test.cjs +12 -0
  83. package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
  84. package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
  85. package/dist/cjs/vite/plugins/workerdDevPlugin.cjs +364 -0
  86. package/dist/cjs/vite/plugins/workerdDevPlugin.native.js +461 -0
  87. package/dist/cjs/vite/plugins/workerdDevPlugin.native.js.map +1 -0
  88. package/dist/cjs/vite/plugins/workerdDevPlugin.test.cjs +42 -0
  89. package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js +45 -0
  90. package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
  91. package/dist/cjs/vite/replaceLoader.cjs +6 -3
  92. package/dist/cjs/vite/replaceLoader.native.js +8 -3
  93. package/dist/cjs/vite/replaceLoader.native.js.map +1 -1
  94. package/dist/esm/cli/build.mjs +31 -180
  95. package/dist/esm/cli/build.mjs.map +1 -1
  96. package/dist/esm/cli/build.native.js +264 -417
  97. package/dist/esm/cli/build.native.js.map +1 -1
  98. package/dist/esm/cli/buildPage.mjs +7 -7
  99. package/dist/esm/cli/buildPage.mjs.map +1 -1
  100. package/dist/esm/cli/buildPage.native.js +7 -7
  101. package/dist/esm/cli/buildPage.native.js.map +1 -1
  102. package/dist/esm/cli/buildPageWorker.mjs +1 -1
  103. package/dist/esm/cli/buildPageWorker.mjs.map +1 -1
  104. package/dist/esm/cli/buildPageWorker.native.js +1 -1
  105. package/dist/esm/cli/buildPageWorker.native.js.map +1 -1
  106. package/dist/esm/cli/serverRouteModules.mjs +22 -0
  107. package/dist/esm/cli/serverRouteModules.mjs.map +1 -0
  108. package/dist/esm/cli/serverRouteModules.native.js +24 -0
  109. package/dist/esm/cli/serverRouteModules.native.js.map +1 -0
  110. package/dist/esm/cli/workerPool.mjs.map +1 -1
  111. package/dist/esm/cli/workerPool.native.js.map +1 -1
  112. package/dist/esm/createApp.mjs +4 -1
  113. package/dist/esm/createApp.mjs.map +1 -1
  114. package/dist/esm/createDevHandleRequest.mjs +126 -0
  115. package/dist/esm/createDevHandleRequest.mjs.map +1 -0
  116. package/dist/esm/createDevHandleRequest.native.js +166 -0
  117. package/dist/esm/createDevHandleRequest.native.js.map +1 -0
  118. package/dist/esm/createHandleRequest.mjs +1 -123
  119. package/dist/esm/createHandleRequest.mjs.map +1 -1
  120. package/dist/esm/createHandleRequest.native.js +1 -163
  121. package/dist/esm/createHandleRequest.native.js.map +1 -1
  122. package/dist/esm/createHandleRequest.test.mjs +1 -1
  123. package/dist/esm/createHandleRequest.test.native.js +1 -1
  124. package/dist/esm/headless-server.mjs.map +1 -1
  125. package/dist/esm/headless-server.native.js.map +1 -1
  126. package/dist/esm/headless.mjs +4 -0
  127. package/dist/esm/headless.mjs.map +1 -1
  128. package/dist/esm/headless.native.js +4 -0
  129. package/dist/esm/headless.native.js.map +1 -1
  130. package/dist/esm/layouts/Drawer.mjs +0 -2
  131. package/dist/esm/layouts/Drawer.mjs.map +1 -1
  132. package/dist/esm/layouts/Drawer.native.js.map +1 -1
  133. package/dist/esm/layouts/Tabs.mjs +0 -2
  134. package/dist/esm/layouts/Tabs.mjs.map +1 -1
  135. package/dist/esm/layouts/Tabs.native.js.map +1 -1
  136. package/dist/esm/router/diagnoseRouteLoadFailure.mjs.map +1 -1
  137. package/dist/esm/router/diagnoseRouteLoadFailure.native.js.map +1 -1
  138. package/dist/esm/router/useViteRoutes.mjs +9 -1
  139. package/dist/esm/router/useViteRoutes.mjs.map +1 -1
  140. package/dist/esm/router/useViteRoutes.native.js +9 -1
  141. package/dist/esm/router/useViteRoutes.native.js.map +1 -1
  142. package/dist/esm/router/web/WebStackView.mjs +0 -2
  143. package/dist/esm/router/web/WebStackView.mjs.map +1 -1
  144. package/dist/esm/router/web/WebStackView.native.js +0 -2
  145. package/dist/esm/router/web/WebStackView.native.js.map +1 -1
  146. package/dist/esm/serve-worker.mjs +3 -2
  147. package/dist/esm/serve-worker.mjs.map +1 -1
  148. package/dist/esm/serve-worker.native.js +3 -2
  149. package/dist/esm/serve-worker.native.js.map +1 -1
  150. package/dist/esm/server/oneServe.mjs +23 -4
  151. package/dist/esm/server/oneServe.mjs.map +1 -1
  152. package/dist/esm/server/oneServe.native.js +25 -6
  153. package/dist/esm/server/oneServe.native.js.map +1 -1
  154. package/dist/esm/server/routeExportsFromEntry.mjs +21 -0
  155. package/dist/esm/server/routeExportsFromEntry.mjs.map +1 -0
  156. package/dist/esm/server/routeExportsFromEntry.native.js +23 -0
  157. package/dist/esm/server/routeExportsFromEntry.native.js.map +1 -0
  158. package/dist/esm/server/workerHandler.mjs +30 -12
  159. package/dist/esm/server/workerHandler.mjs.map +1 -1
  160. package/dist/esm/server/workerHandler.native.js +32 -13
  161. package/dist/esm/server/workerHandler.native.js.map +1 -1
  162. package/dist/esm/server/workerHandler.test.mjs +43 -10
  163. package/dist/esm/server/workerHandler.test.mjs.map +1 -1
  164. package/dist/esm/server/workerHandler.test.native.js +46 -10
  165. package/dist/esm/server/workerHandler.test.native.js.map +1 -1
  166. package/dist/esm/views/ScrollBehavior.mjs.map +1 -1
  167. package/dist/esm/views/ScrollBehavior.native.js.map +1 -1
  168. package/dist/esm/vite/cloudflareWranglerConfig.mjs +202 -0
  169. package/dist/esm/vite/cloudflareWranglerConfig.mjs.map +1 -0
  170. package/dist/esm/vite/cloudflareWranglerConfig.native.js +344 -0
  171. package/dist/esm/vite/cloudflareWranglerConfig.native.js.map +1 -0
  172. package/dist/esm/vite/cloudflareWranglerConfig.test.mjs +117 -0
  173. package/dist/esm/vite/cloudflareWranglerConfig.test.mjs.map +1 -0
  174. package/dist/esm/vite/cloudflareWranglerConfig.test.native.js +118 -0
  175. package/dist/esm/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
  176. package/dist/esm/vite/one.mjs +4 -2
  177. package/dist/esm/vite/one.mjs.map +1 -1
  178. package/dist/esm/vite/one.native.js +8 -6
  179. package/dist/esm/vite/one.native.js.map +1 -1
  180. package/dist/esm/vite/plugins/SSRCSSPlugin.mjs +10 -1
  181. package/dist/esm/vite/plugins/SSRCSSPlugin.mjs.map +1 -1
  182. package/dist/esm/vite/plugins/SSRCSSPlugin.native.js +52 -3
  183. package/dist/esm/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
  184. package/dist/esm/vite/plugins/environmentGuardPlugin.mjs +1 -1
  185. package/dist/esm/vite/plugins/environmentGuardPlugin.mjs.map +1 -1
  186. package/dist/esm/vite/plugins/environmentGuardPlugin.native.js +1 -1
  187. package/dist/esm/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
  188. package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs +4 -0
  189. package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs.map +1 -1
  190. package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
  191. package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
  192. package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs +13 -4
  193. package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
  194. package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js +14 -4
  195. package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
  196. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs +47 -0
  197. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs.map +1 -1
  198. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
  199. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
  200. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs +9 -7
  201. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs.map +1 -1
  202. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js +11 -7
  203. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  204. package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs +12 -0
  205. package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs.map +1 -1
  206. package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
  207. package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
  208. package/dist/esm/vite/plugins/workerdDevPlugin.mjs +336 -0
  209. package/dist/esm/vite/plugins/workerdDevPlugin.mjs.map +1 -0
  210. package/dist/esm/vite/plugins/workerdDevPlugin.native.js +430 -0
  211. package/dist/esm/vite/plugins/workerdDevPlugin.native.js.map +1 -0
  212. package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs +43 -0
  213. package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs.map +1 -0
  214. package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js +43 -0
  215. package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
  216. package/dist/esm/vite/replaceLoader.mjs +6 -3
  217. package/dist/esm/vite/replaceLoader.mjs.map +1 -1
  218. package/dist/esm/vite/replaceLoader.native.js +8 -3
  219. package/dist/esm/vite/replaceLoader.native.js.map +1 -1
  220. package/package.json +9 -9
  221. package/src/cli/build.ts +48 -224
  222. package/src/cli/buildPage.ts +9 -7
  223. package/src/cli/buildPageWorker.ts +1 -0
  224. package/src/cli/serverRouteModules.ts +33 -0
  225. package/src/cli/workerPool.ts +1 -0
  226. package/src/createApp.tsx +5 -1
  227. package/src/createDevHandleRequest.ts +186 -0
  228. package/src/createHandleRequest.test.ts +1 -1
  229. package/src/createHandleRequest.ts +2 -172
  230. package/src/headless-server.ts +0 -1
  231. package/src/headless.tsx +5 -0
  232. package/src/layouts/Drawer.web.tsx +0 -3
  233. package/src/layouts/Tabs.web.tsx +0 -2
  234. package/src/router/diagnoseRouteLoadFailure.ts +3 -1
  235. package/src/router/useViteRoutes.tsx +9 -1
  236. package/src/router/web/WebStackView.tsx +0 -3
  237. package/src/serve-worker.ts +6 -1
  238. package/src/server/oneServe.ts +40 -16
  239. package/src/server/routeExportsFromEntry.ts +59 -0
  240. package/src/server/workerHandler.test.ts +37 -9
  241. package/src/server/workerHandler.ts +39 -13
  242. package/src/views/ScrollBehavior.tsx +5 -1
  243. package/src/vite/cloudflareWranglerConfig.test.ts +101 -0
  244. package/src/vite/cloudflareWranglerConfig.ts +252 -0
  245. package/src/vite/one.ts +14 -1
  246. package/src/vite/plugins/SSRCSSPlugin.ts +17 -2
  247. package/src/vite/plugins/environmentGuardPlugin.test.ts +5 -0
  248. package/src/vite/plugins/environmentGuardPlugin.ts +2 -2
  249. package/src/vite/plugins/fileSystemRouterPlugin.test.ts +44 -0
  250. package/src/vite/plugins/fileSystemRouterPlugin.tsx +20 -8
  251. package/src/vite/plugins/virtualEntryPlugin.test.ts +13 -0
  252. package/src/vite/plugins/virtualEntryPlugin.ts +13 -9
  253. package/src/vite/plugins/workerdDevPlugin.test.ts +44 -0
  254. package/src/vite/plugins/workerdDevPlugin.ts +398 -0
  255. package/src/vite/replaceLoader.ts +10 -2
  256. package/types/cli/build.d.ts.map +1 -1
  257. package/types/cli/buildPage.d.ts +1 -1
  258. package/types/cli/buildPage.d.ts.map +1 -1
  259. package/types/cli/serverRouteModules.d.ts +2 -0
  260. package/types/cli/serverRouteModules.d.ts.map +1 -0
  261. package/types/cli/workerPool.d.ts +1 -0
  262. package/types/cli/workerPool.d.ts.map +1 -1
  263. package/types/createApp.d.ts.map +1 -1
  264. package/types/createDevHandleRequest.d.ts +10 -0
  265. package/types/createDevHandleRequest.d.ts.map +1 -0
  266. package/types/createHandleRequest.d.ts +2 -9
  267. package/types/createHandleRequest.d.ts.map +1 -1
  268. package/types/headless-server.d.ts +0 -1
  269. package/types/headless-server.d.ts.map +1 -1
  270. package/types/headless.d.ts.map +1 -1
  271. package/types/layouts/Drawer.web.d.ts.map +1 -1
  272. package/types/layouts/Tabs.web.d.ts.map +1 -1
  273. package/types/router/diagnoseRouteLoadFailure.d.ts.map +1 -1
  274. package/types/router/useViteRoutes.d.ts.map +1 -1
  275. package/types/router/web/WebStackView.d.ts.map +1 -1
  276. package/types/serve-worker.d.ts +3 -1
  277. package/types/serve-worker.d.ts.map +1 -1
  278. package/types/server/oneServe.d.ts +1 -1
  279. package/types/server/oneServe.d.ts.map +1 -1
  280. package/types/server/routeExportsFromEntry.d.ts +29 -0
  281. package/types/server/routeExportsFromEntry.d.ts.map +1 -0
  282. package/types/server/workerHandler.d.ts +2 -1
  283. package/types/server/workerHandler.d.ts.map +1 -1
  284. package/types/views/ScrollBehavior.d.ts.map +1 -1
  285. package/types/vite/cloudflareWranglerConfig.d.ts +21 -0
  286. package/types/vite/cloudflareWranglerConfig.d.ts.map +1 -0
  287. package/types/vite/cloudflareWranglerConfig.test.d.ts +2 -0
  288. package/types/vite/cloudflareWranglerConfig.test.d.ts.map +1 -0
  289. package/types/vite/one.d.ts.map +1 -1
  290. package/types/vite/plugins/SSRCSSPlugin.d.ts.map +1 -1
  291. package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
  292. package/types/vite/plugins/virtualEntryPlugin.d.ts.map +1 -1
  293. package/types/vite/plugins/workerdDevPlugin.d.ts +15 -0
  294. package/types/vite/plugins/workerdDevPlugin.d.ts.map +1 -0
  295. package/types/vite/plugins/workerdDevPlugin.test.d.ts +2 -0
  296. package/types/vite/plugins/workerdDevPlugin.test.d.ts.map +1 -0
  297. package/types/vite/replaceLoader.d.ts +2 -1
  298. package/types/vite/replaceLoader.d.ts.map +1 -1
  299. package/dist/cjs/headless/devHeadlessNote.cjs +0 -34
  300. package/dist/cjs/headless/devHeadlessNote.native.js +0 -37
  301. package/dist/cjs/headless/devHeadlessNote.native.js.map +0 -1
  302. package/dist/esm/headless/devHeadlessNote.mjs +0 -9
  303. package/dist/esm/headless/devHeadlessNote.mjs.map +0 -1
  304. package/dist/esm/headless/devHeadlessNote.native.js +0 -9
  305. package/dist/esm/headless/devHeadlessNote.native.js.map +0 -1
  306. package/src/headless/devHeadlessNote.ts +0 -13
  307. package/types/headless/devHeadlessNote.d.ts +0 -2
  308. package/types/headless/devHeadlessNote.d.ts.map +0 -1
@@ -3,9 +3,7 @@ import type { Middleware, MiddlewareContext } from './createMiddleware'
3
3
  import type { RouteNode } from './router/Route'
4
4
  import type { RouteInfoCompiled } from './server/createRoutesManifest'
5
5
  import type { LoaderProps } from './types'
6
- import { getPathFromLoaderPath } from './utils/cleanUrl'
7
6
  import { isResponse } from './utils/isResponse'
8
- import { getManifest } from './vite/getManifest'
9
7
  import { resolveAPIEndpoint, resolveResponse } from './vite/resolveResponse'
10
8
  import type { RouteInfo } from './vite/types'
11
9
 
@@ -24,12 +22,12 @@ type RequestHandlerProps<RouteExtraProps extends object = {}> = {
24
22
  loaderProps?: LoaderProps
25
23
  }
26
24
 
27
- type RequestHandlerResponse = null | string | Response
25
+ export type RequestHandlerResponse = null | string | Response
28
26
 
29
27
  const debugRouter = process.env.ONE_DEBUG_ROUTER
30
28
  const staticAssetPathRe = /\.(?:[a-z0-9]{2,4}|webmanifest|wasm|woff2)$/i
31
29
 
32
- function isStaticAssetRequestPath(pathname: string): boolean {
30
+ export function isStaticAssetRequestPath(pathname: string): boolean {
33
31
  return (
34
32
  !pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED) && staticAssetPathRe.test(pathname)
35
33
  )
@@ -382,174 +380,6 @@ export function compileManifest(manifest: {
382
380
  }
383
381
  }
384
382
 
385
- // in dev mode we do it more simply:
386
- export function createHandleRequest(
387
- handlers: RequestHandlers,
388
- {
389
- routerRoot,
390
- ignoredRouteFiles,
391
- routePaths,
392
- }: { routerRoot: string; ignoredRouteFiles?: string[]; routePaths?: string[] }
393
- ) {
394
- const manifest = getManifest({ routerRoot, ignoredRouteFiles, routePaths })
395
- if (!manifest) {
396
- throw new Error(`No routes manifest`)
397
- }
398
- const compiledManifest = compileManifest(manifest)
399
-
400
- return {
401
- manifest,
402
- handler: async function handleRequest(
403
- request: Request
404
- ): Promise<RequestHandlerResponse> {
405
- const url = getURLfromRequestURL(request)
406
- const { pathname, search } = url
407
-
408
- // skip paths handled by vite internals or react native dev middleware
409
- if (
410
- pathname === '/__vxrnhmr' ||
411
- pathname.startsWith('/@vite/') ||
412
- pathname.startsWith('/@fs/') ||
413
- pathname.startsWith('/@id/') ||
414
- pathname.startsWith('/node_modules/') ||
415
- pathname.startsWith('/debugger-frontend') ||
416
- pathname.startsWith('/inspector')
417
- ) {
418
- return null
419
- }
420
-
421
- const looksLikeStaticFile = isStaticAssetRequestPath(pathname)
422
-
423
- if (handlers.handleAPI) {
424
- const apiRoute = compiledManifest.apiRoutes.find((route) => {
425
- return route.compiledRegex.test(pathname)
426
- })
427
- if (apiRoute) {
428
- if (debugRouter) {
429
- console.info(`[one] ⚡ ${pathname} → matched API route: ${apiRoute.page}`)
430
- }
431
- return await resolveAPIRoute(handlers, request, url, apiRoute)
432
- }
433
- }
434
-
435
- if (!isPageRequestMethod(request.method)) {
436
- return null
437
- }
438
-
439
- if (handlers.handleLoader) {
440
- const isClientRequestingNewRoute = pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED)
441
-
442
- if (isClientRequestingNewRoute) {
443
- const platformParam = url.searchParams.get('platform')
444
- const isNativePlatform =
445
- platformParam === 'ios' ||
446
- platformParam === 'android' ||
447
- platformParam === 'native'
448
-
449
- // for native requests, try serving the pre-built .native.js static file first
450
- // (SSG/SPA routes generate standalone CJS loaders at build time)
451
- if (isNativePlatform && handlers.handleStaticFile) {
452
- const nativeLoaderPath = pathname.replace(/\.js$/, '.native.js')
453
- const staticResponse = await handlers.handleStaticFile(nativeLoaderPath)
454
- if (staticResponse) {
455
- return staticResponse
456
- }
457
- }
458
-
459
- const originalUrl = getPathFromLoaderPath(pathname)
460
-
461
- for (const route of compiledManifest.pageRoutes) {
462
- if (route.file === '') {
463
- // ignore not found route
464
- continue
465
- }
466
-
467
- const finalUrl = new URL(originalUrl, url.origin)
468
- finalUrl.search = url.search
469
-
470
- if (!route.compiledRegex.test(finalUrl.pathname)) {
471
- continue
472
- }
473
-
474
- // route is known to export no loader → return empty module without
475
- // importing the page bundle. on workerd/cloudflare, evaluating a
476
- // no-loader SSG page's server bundle can crash when it pulls in
477
- // RN/Tamagui modules that aren't compatible with the workers runtime.
478
- if (route.hasLoader === false) {
479
- const emptyBody = isNativePlatform
480
- ? 'exports.loader=function(){return undefined}'
481
- : 'export function loader() { return undefined }'
482
- return new Response(emptyBody, {
483
- headers: { 'Content-Type': 'text/javascript' },
484
- })
485
- }
486
-
487
- const cleanedRequest = new Request(finalUrl, request)
488
- return resolveLoaderRoute(handlers, cleanedRequest, finalUrl, route)
489
- }
490
-
491
- // no matching route - return empty module so client handles gracefully
492
- const emptyBody = isNativePlatform
493
- ? 'exports.loader=function(){return{}}'
494
- : 'export {}'
495
- return new Response(emptyBody, {
496
- headers: { 'Content-Type': 'text/javascript' },
497
- })
498
- }
499
- }
500
-
501
- if (handlers.handlePage) {
502
- for (const route of compiledManifest.pageRoutes) {
503
- if (!route.compiledRegex.test(pathname)) {
504
- continue
505
- }
506
-
507
- // static asset requests (sourcemaps, favicons, fonts, …) should not
508
- // SSR the user's +not-found page or hijack a dynamic route. for
509
- // +not-found we still run middleware so it can intercept, then
510
- // short-circuit to a bare 404 instead of rendering the page tree.
511
- const isDynamicRoute = Object.keys(route.routeKeys).length > 0
512
- const isNotFoundRoute = route.page.endsWith('/+not-found')
513
- if (looksLikeStaticFile && isNotFoundRoute) {
514
- if (debugRouter) {
515
- console.info(
516
- `[one] ⚡ ${pathname} → bare 404 for static probe on ${route.page}`
517
- )
518
- }
519
- if (!route.middlewares?.length) {
520
- return null
521
- }
522
- return await runMiddlewares(handlers, request, route, async () => {
523
- return new Response(null, {
524
- status: 404,
525
- headers: { 'Content-Type': 'text/plain' },
526
- })
527
- })
528
- }
529
- if (looksLikeStaticFile && isDynamicRoute) {
530
- if (debugRouter) {
531
- console.info(
532
- `[one] ⚡ ${pathname} → skipping dynamic route ${route.page} for static asset`
533
- )
534
- }
535
- continue
536
- }
537
-
538
- if (debugRouter) {
539
- console.info(
540
- `[one] ⚡ ${pathname} → matched page route: ${route.page} (${route.type})`
541
- )
542
- }
543
-
544
- return resolvePageRoute(handlers, request, url, route)
545
- }
546
- }
547
-
548
- return null
549
- },
550
- }
551
- }
552
-
553
383
  export function getLoaderParams(
554
384
  url: URL,
555
385
  config: { compiledRegex: RegExp; routeKeys: Record<string, string> }
@@ -20,7 +20,6 @@
20
20
  * oneOptions: { web: { defaultRenderMode: 'spa' } },
21
21
  * routes: {
22
22
  * api: { '/api/hello': () => import('./api/hello') },
23
- * pages: { '/index': () => import('./index') },
24
23
  * middlewares: {},
25
24
  * serverEntry: () => import('./entry-server'),
26
25
  * },
package/src/headless.tsx CHANGED
@@ -4,6 +4,7 @@ import type { OneLinkingConfig } from './link/getLinking'
4
4
  import { Root } from './Root'
5
5
  import { resolveClientLoader } from './clientLoaderResolver'
6
6
  import { render } from './render'
7
+ import { handleSkewError, isChunkLoadError } from './utils/dynamicImport'
7
8
  import { findRootLayout } from './utils/findRootLayout'
8
9
  import type { One } from './vite/types'
9
10
 
@@ -51,5 +52,9 @@ export function createApp(options: CreateHeadlessAppProps) {
51
52
  })
52
53
  .catch((err) => {
53
54
  console.error(`[one/headless] Error during initialization:`, err)
55
+ if (isChunkLoadError(err)) {
56
+ handleSkewError()
57
+ }
54
58
  })
55
59
  }
60
+
@@ -15,7 +15,6 @@ import {
15
15
  import { Children, type ComponentProps, forwardRef, type ReactNode } from 'react'
16
16
 
17
17
  import { getCustomNavigatorChildren, isNavigatorConfigChild } from '../headless/children'
18
- import { devHeadlessNote } from '../headless/devHeadlessNote'
19
18
  import { renderKeptMountedScreens, useVisitedScreens } from '../headless/keepMounted'
20
19
  import {
21
20
  DrawerStateProvider,
@@ -75,8 +74,6 @@ function HeadlessDrawerView({ customChildren }: { customChildren?: ReactNode[] }
75
74
  const { screens, focused } = useDrawer()
76
75
  const visited = useVisitedScreens(focused.key)
77
76
 
78
- devHeadlessNote('Drawer')
79
-
80
77
  if (customChildren?.length) {
81
78
  return <>{customChildren}</>
82
79
  }
@@ -11,7 +11,6 @@ import {
11
11
  import { Children, Fragment, forwardRef, type ReactNode, useMemo, useRef } from 'react'
12
12
  import { getPathFromState } from '../fork/getPathFromState'
13
13
  import { getCustomNavigatorChildren, isNavigatorConfigChild } from '../headless/children'
14
- import { devHeadlessNote } from '../headless/devHeadlessNote'
15
14
  import { renderKeptMountedScreens, useVisitedScreens } from '../headless/keepMounted'
16
15
  import { useTabs } from '../headless/useTabs'
17
16
  import { getResolvedLinking } from '../router/linkingConfig'
@@ -118,7 +117,6 @@ function WebTabsNavigator({
118
117
  function HeadlessTabsView({ customChildren }: { customChildren?: ReactNode[] }) {
119
118
  const { screens, focused } = useTabs()
120
119
  const visited = useVisitedScreens(focused.key)
121
- devHeadlessNote('Tabs')
122
120
 
123
121
  if (customChildren?.length) {
124
122
  return <Fragment>{customChildren}</Fragment>
@@ -28,7 +28,9 @@ function collectImports(source: string, base: string): string[] {
28
28
  out.push(new URL(spec, base).href)
29
29
  } catch {}
30
30
  }
31
- for (const m of source.matchAll(/(?:^|[\s;}])(?:import|export)[^'"]{0,300}?from\s*["']([^"']+)["']/g))
31
+ for (const m of source.matchAll(
32
+ /(?:^|[\s;}])(?:import|export)[^'"]{0,300}?from\s*["']([^"']+)["']/g
33
+ ))
32
34
  add(m[1])
33
35
  for (const m of source.matchAll(/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g)) add(m[1])
34
36
  for (const m of source.matchAll(/(?:^|[\s;}])import\s*["']([^"']+)["']/g)) add(m[1])
@@ -1,5 +1,6 @@
1
1
  import type { GlobbedRouteImports } from '../types'
2
2
  import type { One } from '../vite/types'
3
+ import { handleSkewError, isChunkLoadError } from '../utils/dynamicImport'
3
4
  import { diagnoseRouteLoadFailure } from './diagnoseRouteLoadFailure'
4
5
  import { hmrImport } from './hmrImport'
5
6
 
@@ -146,7 +147,11 @@ export async function preloadRouteModules(href: string): Promise<void> {
146
147
  .then((mod: any) => {
147
148
  preloadedModules[key] = mod
148
149
  })
149
- .catch(() => {})
150
+ .catch((err: any) => {
151
+ if (isChunkLoadError(err)) {
152
+ handleSkewError()
153
+ }
154
+ })
150
155
  )
151
156
  }
152
157
  }
@@ -284,6 +289,9 @@ export function globbedRoutesToRouteContext(
284
289
  })
285
290
  .catch((err) => {
286
291
  console.error(`Error loading route`, id, err, new Error().stack)
292
+ if (isChunkLoadError(err)) {
293
+ handleSkewError()
294
+ }
287
295
  // rendering an empty component keeps one bad route from taking down the
288
296
  // app, but it also makes the failure invisible: nothing inside the route
289
297
  // mounts and the only trace is the line above. in dev, hand it to the
@@ -21,7 +21,6 @@ import {
21
21
  } from 'react'
22
22
  import useLatestCallback from 'use-latest-callback'
23
23
 
24
- import { devHeadlessNote } from '../../headless/devHeadlessNote'
25
24
  import { useWebPresentations } from '../../headless/Presentations'
26
25
  import type {
27
26
  ModalPresentationOptions,
@@ -95,8 +94,6 @@ function HeadlessStackView({
95
94
  return <Fragment>{customChildren}</Fragment>
96
95
  }
97
96
 
98
- devHeadlessNote('Stack')
99
-
100
97
  const lastBaseIndex = findLastNonOverlayIndex(
101
98
  state,
102
99
  descriptors,
@@ -19,7 +19,11 @@ export type { LazyRoutes }
19
19
  * API route handler contexts as `{ env, executionCtx }`).
20
20
  * Call `updateRoutes(newBuildInfo, newLazyRoutes?)` to hot-swap the route table.
21
21
  */
22
- export async function serve(buildInfo: One.BuildInfo, lazyRoutes?: LazyRoutes) {
22
+ export async function serve(
23
+ buildInfo: One.BuildInfo,
24
+ lazyRoutes?: LazyRoutes,
25
+ serveOptions?: { disableModuleCache?: boolean }
26
+ ) {
23
27
  setupBuildInfo(buildInfo)
24
28
  ensureExists(buildInfo.oneOptions)
25
29
  setServerGlobals()
@@ -28,6 +32,7 @@ export async function serve(buildInfo: One.BuildInfo, lazyRoutes?: LazyRoutes) {
28
32
  oneOptions: buildInfo.oneOptions!,
29
33
  buildInfo,
30
34
  lazyRoutes: lazyRoutes!,
35
+ disableModuleCache: serveOptions?.disableModuleCache,
31
36
  })
32
37
 
33
38
  return {
@@ -16,10 +16,12 @@ import {
16
16
  } from '../createHandleRequest'
17
17
  import type { RenderAppProps } from '../types'
18
18
  import { getPathFromLoaderPath } from '../utils/cleanUrl'
19
+ import { getRouterRootFromOneOptions } from '../utils/getRouterRootFromOneOptions'
19
20
  import { toAbsoluteUrl } from '../utils/toAbsolute'
20
21
  import { toServerOutputPath } from '../utils/toServerOutputPath'
21
22
  import type { One } from '../vite/types'
22
23
  import type { RouteInfoCompiled } from './createRoutesManifest'
24
+ import { getRouteExportsFromEntry } from './routeExportsFromEntry'
23
25
  import { setSSRLoaderData } from './ssrLoaderData'
24
26
  import { getFetchStaticHtml } from './staticHtmlFetcher'
25
27
 
@@ -74,8 +76,8 @@ async function readStaticHtml(htmlPath: string, outDir = 'dist'): Promise<string
74
76
  * Modules are loaded on-demand when a route is matched, not all upfront.
75
77
  */
76
78
  type LazyRoutes = {
79
+ pages?: Record<string, () => Promise<any>>
77
80
  serverEntry: () => Promise<{ default: { render: (props: any) => any } }>
78
- pages: Record<string, () => Promise<any>>
79
81
  api: Record<string, () => Promise<any>>
80
82
  middlewares: Record<string, () => Promise<any>>
81
83
  }
@@ -150,6 +152,7 @@ export async function oneServe(
150
152
  }
151
153
 
152
154
  const apiCJS = oneOptions.build?.api?.outputFormat === 'cjs'
155
+ const routerRoot = getRouterRootFromOneOptions(oneOptions)
153
156
 
154
157
  // pre-computed constants to avoid per-request overhead
155
158
  const useStreaming = !process.env.ONE_BUFFERED_SSR
@@ -169,6 +172,26 @@ export async function oneServe(
169
172
  { promise: Promise<any>; expires: number }
170
173
  >()
171
174
 
175
+ // route modules are resolved through the built server entry, see
176
+ // routeExportsFromEntry
177
+ async function importRouteModule(
178
+ lazyKey: string | undefined,
179
+ serverPath: string | undefined
180
+ ): Promise<any> {
181
+ if (lazyKey && options?.lazyRoutes?.pages?.[lazyKey]) {
182
+ return await options.lazyRoutes.pages[lazyKey]()
183
+ }
184
+ if (lazyKey) {
185
+ const entry = await loadServerEntry()
186
+ const exported = await getRouteExportsFromEntry(entry, routerRoot, lazyKey)
187
+ if (exported) return exported
188
+ }
189
+ // layouts and middlewares outside the router root still resolve by path
190
+ return await import(
191
+ toAbsoluteUrl(toServerOutputPath(serverPath || lazyKey || '', outDir))
192
+ )
193
+ }
194
+
172
195
  // resolve a route module's loader - sync on cache hit, async on cold start
173
196
  function resolveLoaderSync(
174
197
  serverPath: string | undefined,
@@ -180,18 +203,11 @@ export async function oneServe(
180
203
 
181
204
  // cold path - async import
182
205
  return (async () => {
183
- const pathToResolve = serverPath || lazyKey || ''
184
- const resolvedPath = toServerOutputPath(pathToResolve, outDir)
185
-
186
206
  let routeExported: any
187
207
  if (moduleImportCache.has(cacheKey)) {
188
208
  routeExported = moduleImportCache.get(cacheKey)
189
209
  } else {
190
- routeExported = lazyKey
191
- ? options?.lazyRoutes?.pages?.[lazyKey]
192
- ? await options.lazyRoutes.pages[lazyKey]()
193
- : await import(toAbsoluteUrl(resolvedPath))
194
- : await import(toAbsoluteUrl(serverPath!))
210
+ routeExported = await importRouteModule(lazyKey, serverPath)
195
211
  setBounded(moduleImportCache, cacheKey, routeExported, MODULE_CACHE_MAX)
196
212
  }
197
213
 
@@ -286,18 +302,26 @@ export async function oneServe(
286
302
  let render: ((props: RenderAppProps) => any) | null = null
287
303
  let renderStream: ((props: RenderAppProps) => Promise<ReadableStream>) | null = null
288
304
  let renderLoading: Promise<void> | null = null
305
+ let entryLoading: Promise<any> | null = null
289
306
 
290
- function ensureRenderLoaded(): void | Promise<void> {
291
- if (render) return // sync!
292
- if (renderLoading) return renderLoading
293
- renderLoading = (async () => {
294
- const entry = options?.lazyRoutes?.serverEntry
295
- ? await options.lazyRoutes.serverEntry()
296
- : await import(
307
+ function loadServerEntry(): Promise<any> {
308
+ if (!entryLoading) {
309
+ entryLoading = options?.lazyRoutes?.serverEntry
310
+ ? options.lazyRoutes.serverEntry()
311
+ : import(
297
312
  toAbsoluteUrl(
298
313
  `${serverOptions.root}/${outDir}/server/_virtual_one-entry.${typeof oneOptions.build?.server === 'object' && oneOptions.build.server.outputFormat === 'cjs' ? 'c' : ''}js`
299
314
  )
300
315
  )
316
+ }
317
+ return entryLoading
318
+ }
319
+
320
+ function ensureRenderLoaded(): void | Promise<void> {
321
+ if (render) return // sync!
322
+ if (renderLoading) return renderLoading
323
+ renderLoading = (async () => {
324
+ const entry = await loadServerEntry()
301
325
  render = entry.default.render as (props: RenderAppProps) => any
302
326
  renderStream = entry.default.renderStream as
303
327
  | ((props: RenderAppProps) => Promise<ReadableStream>)
@@ -0,0 +1,59 @@
1
+ /**
2
+ * route modules have to be read through the built server entry's own route map,
3
+ * never by importing whichever output chunk happens to contain them.
4
+ *
5
+ * a bundler makes no promise that a chunk re-exports a module's bindings under
6
+ * their source names. when a route is both dynamically imported by the entry and
7
+ * statically imported by another route (docs pages mirrored under a second url,
8
+ * say), or when the app sets `output.strictExecutionOrder`, rolldown emits the
9
+ * chunk as
10
+ *
11
+ * export { loader as a, init__slug_ as i, _slug__exports as n, generateStaticParams as r }
12
+ *
13
+ * so every read by source name comes back undefined: the build then reports a
14
+ * route that exports generateStaticParams as missing it, and any loader on that
15
+ * route silently stops running.
16
+ *
17
+ * the entry's `import.meta.glob` map is written by the bundler itself, which
18
+ * rewrites each entry to whatever preserves the real namespace
19
+ * (`import(chunk).then((n) => (n.i(), n.n))` for the wrapped case above). so it
20
+ * resolves correctly no matter how the chunking lands.
21
+ */
22
+
23
+ /** the key the entry's globs use: `./posts/[slug]+ssg.tsx` -> `/app/posts/[slug]+ssg.tsx` */
24
+ export function routeEntryKey(routerRoot: string, routeFile: string) {
25
+ return `/${routerRoot}/${routeFile.replace(/^\.?\//, '')}`
26
+ }
27
+
28
+ /**
29
+ * resolve one route's exports out of an already-loaded server entry namespace.
30
+ * returns null when the entry has no such route.
31
+ */
32
+ export async function getRouteExportsFromEntry(
33
+ entry: any,
34
+ routerRoot: string,
35
+ routeFile: string
36
+ ): Promise<Record<string, any> | null> {
37
+ const key = routeEntryKey(routerRoot, routeFile)
38
+
39
+ // a route that declares spa by filename or parent directory is stubbed out of
40
+ // the route map, so the server never holds its page component. every stubbed
41
+ // route has an entry in this parallel per-export map whether or not it
42
+ // actually exports a loader, which is what tells a stub from a real route. a
43
+ // route that is spa only because of `web.defaultRenderMode` is never stubbed.
44
+ const spaExports = entry?.oneServerSpaRouteExports
45
+ if (spaExports?.loader && key in spaExports.loader) {
46
+ const [loader, loaderCache, generateStaticParams, sitemap] = await Promise.all([
47
+ spaExports.loader[key](),
48
+ spaExports.loaderCache?.[key]?.(),
49
+ spaExports.generateStaticParams?.[key]?.(),
50
+ spaExports.sitemap?.[key]?.(),
51
+ ])
52
+ return { loader, loaderCache, generateStaticParams, sitemap }
53
+ }
54
+
55
+ // some output formats nest the entry default one level deeper
56
+ const app = entry?.default?.options ? entry.default : entry?.default?.default
57
+ const importRoute = app?.options?.routes?.[key]
58
+ return importRoute ? await importRoute() : null
59
+ }
@@ -2,8 +2,9 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
2
2
  import type { One } from '../vite/types'
3
3
  import { createWorkerHandler, type LazyRoutes } from './workerHandler'
4
4
 
5
+ // route files are router-root relative, the way createRoutesManifest emits them
5
6
  const pageRoute = {
6
- file: 'app/some-page.tsx',
7
+ file: './some-page.tsx',
7
8
  page: '/some-page',
8
9
  namedRegex: '^/some-page(?:/)?$',
9
10
  urlPath: '/some-page',
@@ -14,7 +15,7 @@ const pageRoute = {
14
15
  } satisfies One.BuildInfo['manifest']['pageRoutes'][number]
15
16
 
16
17
  const apiRoute = {
17
- file: 'app/api/status+api.ts',
18
+ file: './api/status+api.ts',
18
19
  page: '/api/status',
19
20
  namedRegex: '^/api/status(?:/)?$',
20
21
  urlPath: '/api/status',
@@ -57,15 +58,21 @@ const buildInfo = {
57
58
  loaders: {},
58
59
  } satisfies One.BuildInfo
59
60
 
60
- const lazyRoutes = {
61
- serverEntry: async () => ({
61
+ // route modules are reached through the server entry's own route map, keyed by
62
+ // the router-root prefixed path its `import.meta.glob` produces
63
+ const routeKey = `/app/${pageRoute.file.slice(2)}`
64
+
65
+ const makeServerEntry =
66
+ (importPage: () => Promise<any> = async () => ({})) =>
67
+ async () => ({
62
68
  default: {
63
69
  render: () => '<html></html>',
70
+ options: { routes: { [routeKey]: importPage } },
64
71
  },
65
- }),
66
- pages: {
67
- [pageRoute.file]: async () => ({}),
68
- },
72
+ })
73
+
74
+ const lazyRoutes = {
75
+ serverEntry: makeServerEntry(),
69
76
  api: {
70
77
  [apiRoute.page]: async () => ({
71
78
  HEAD: () => new Response(null, { status: 204 }),
@@ -77,7 +84,7 @@ const lazyRoutes = {
77
84
  function createHandler() {
78
85
  vi.stubEnv('ONE_BUFFERED_SSR', '1')
79
86
  return createWorkerHandler({
80
- oneOptions: { web: { defaultRenderMode: 'ssr' } },
87
+ oneOptions: { router: { root: 'app' }, web: { defaultRenderMode: 'ssr' } },
81
88
  buildInfo,
82
89
  lazyRoutes,
83
90
  }).handleRequest
@@ -122,4 +129,25 @@ describe('createWorkerHandler', () => {
122
129
  expect(response).toBeInstanceOf(Response)
123
130
  expect(response?.status).toBe(204)
124
131
  })
132
+
133
+ it('disableModuleCache re-imports the page module on each request', async () => {
134
+ vi.stubEnv('ONE_BUFFERED_SSR', '1')
135
+ let imports = 0
136
+ const handleRequest = createWorkerHandler({
137
+ oneOptions: { router: { root: 'app' }, web: { defaultRenderMode: 'ssr' } },
138
+ buildInfo,
139
+ disableModuleCache: true,
140
+ lazyRoutes: {
141
+ ...lazyRoutes,
142
+ serverEntry: makeServerEntry(async () => {
143
+ imports += 1
144
+ return {}
145
+ }),
146
+ },
147
+ }).handleRequest
148
+
149
+ await handleRequest(new Request('https://example.com/some-page'))
150
+ await handleRequest(new Request('https://example.com/some-page'))
151
+ expect(imports).toBeGreaterThan(1)
152
+ })
125
153
  })