one 1.2.57 → 1.2.58

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 (481) hide show
  1. package/dist/cjs/cli/buildPage.cjs +1 -1
  2. package/dist/cjs/cli/buildPage.js +1 -1
  3. package/dist/cjs/cli/buildPage.native.js +1 -1
  4. package/dist/cjs/cli/buildPage.native.js.map +1 -1
  5. package/dist/cjs/cli/dev.cjs +4 -4
  6. package/dist/cjs/cli/dev.js +4 -4
  7. package/dist/cjs/cli/dev.js.map +1 -1
  8. package/dist/cjs/cli/dev.native.js +4 -4
  9. package/dist/cjs/cli/dev.native.js.map +1 -1
  10. package/dist/cjs/createApp.cjs +2 -1
  11. package/dist/cjs/createApp.js +2 -2
  12. package/dist/cjs/createApp.js.map +1 -1
  13. package/dist/cjs/createHandleRequest.test.js +3 -1
  14. package/dist/cjs/createHandleRequest.test.js.map +1 -1
  15. package/dist/cjs/createHandleRequest.test.native.js.map +1 -1
  16. package/dist/cjs/devtools/registry.cjs +30 -0
  17. package/dist/cjs/devtools/registry.js +25 -0
  18. package/dist/cjs/devtools/registry.js.map +6 -0
  19. package/dist/cjs/devtools/registry.native.js +33 -0
  20. package/dist/cjs/devtools/registry.native.js.map +1 -0
  21. package/dist/cjs/fork/createMemoryHistory.cjs +20 -9
  22. package/dist/cjs/fork/createMemoryHistory.js +22 -4
  23. package/dist/cjs/fork/createMemoryHistory.js.map +1 -1
  24. package/dist/cjs/fork/createMemoryHistory.native.js +20 -9
  25. package/dist/cjs/fork/createMemoryHistory.native.js.map +1 -1
  26. package/dist/cjs/fork/useLinking.cjs +11 -5
  27. package/dist/cjs/fork/useLinking.js +6 -6
  28. package/dist/cjs/fork/useLinking.js.map +1 -1
  29. package/dist/cjs/index.cjs +17 -1
  30. package/dist/cjs/index.js +12 -2
  31. package/dist/cjs/index.js.map +1 -1
  32. package/dist/cjs/index.native.js +17 -1
  33. package/dist/cjs/index.native.js.map +1 -1
  34. package/dist/cjs/layouts/withLayoutContext.cjs +34 -15
  35. package/dist/cjs/layouts/withLayoutContext.js +29 -13
  36. package/dist/cjs/layouts/withLayoutContext.js.map +1 -1
  37. package/dist/cjs/layouts/withLayoutContext.native.js +42 -19
  38. package/dist/cjs/layouts/withLayoutContext.native.js.map +1 -1
  39. package/dist/cjs/link/Link.cjs +5 -2
  40. package/dist/cjs/link/Link.js +3 -2
  41. package/dist/cjs/link/Link.js.map +1 -1
  42. package/dist/cjs/link/Link.native.js +6 -1
  43. package/dist/cjs/link/Link.native.js.map +1 -1
  44. package/dist/cjs/link/useLinkTo.cjs +11 -3
  45. package/dist/cjs/link/useLinkTo.js +6 -3
  46. package/dist/cjs/link/useLinkTo.js.map +1 -1
  47. package/dist/cjs/link/useLinkTo.native.js +11 -3
  48. package/dist/cjs/link/useLinkTo.native.js.map +1 -1
  49. package/dist/cjs/router/Route.js.map +1 -1
  50. package/dist/cjs/router/Route.native.js.map +1 -1
  51. package/dist/cjs/router/findRouteNode.cjs +70 -0
  52. package/dist/cjs/router/findRouteNode.js +72 -0
  53. package/dist/cjs/router/findRouteNode.js.map +6 -0
  54. package/dist/cjs/router/findRouteNode.native.js +104 -0
  55. package/dist/cjs/router/findRouteNode.native.js.map +1 -0
  56. package/dist/cjs/router/router.cjs +160 -11
  57. package/dist/cjs/router/router.js +142 -7
  58. package/dist/cjs/router/router.js.map +2 -2
  59. package/dist/cjs/router/router.native.js +241 -57
  60. package/dist/cjs/router/router.native.js.map +1 -1
  61. package/dist/cjs/router/useScreens.cjs +1 -1
  62. package/dist/cjs/router/useScreens.js +1 -1
  63. package/dist/cjs/router/useScreens.js.map +1 -1
  64. package/dist/cjs/router/useScreens.native.js +5 -2
  65. package/dist/cjs/router/useScreens.native.js.map +1 -1
  66. package/dist/cjs/server/oneServe.js.map +1 -1
  67. package/dist/cjs/server/oneServe.native.js.map +1 -1
  68. package/dist/cjs/useBlocker.cjs +158 -0
  69. package/dist/cjs/useBlocker.js +145 -0
  70. package/dist/cjs/useBlocker.js.map +6 -0
  71. package/dist/cjs/useBlocker.native.js +89 -0
  72. package/dist/cjs/useBlocker.native.js.map +1 -0
  73. package/dist/cjs/useLoader.cjs +69 -3
  74. package/dist/cjs/useLoader.js +57 -4
  75. package/dist/cjs/useLoader.js.map +2 -2
  76. package/dist/cjs/useLoader.native.js +90 -6
  77. package/dist/cjs/useLoader.native.js.map +1 -1
  78. package/dist/cjs/useScrollGroup.cjs +37 -0
  79. package/dist/cjs/useScrollGroup.js +30 -0
  80. package/dist/cjs/useScrollGroup.js.map +6 -0
  81. package/dist/cjs/useScrollGroup.native.js +29 -0
  82. package/dist/cjs/useScrollGroup.native.js.map +1 -0
  83. package/dist/cjs/validateParams.cjs +80 -0
  84. package/dist/cjs/validateParams.js +84 -0
  85. package/dist/cjs/validateParams.js.map +6 -0
  86. package/dist/cjs/validateParams.native.js +180 -0
  87. package/dist/cjs/validateParams.native.js.map +1 -0
  88. package/dist/cjs/validateSearch.cjs +104 -0
  89. package/dist/cjs/validateSearch.js +99 -0
  90. package/dist/cjs/validateSearch.js.map +6 -0
  91. package/dist/cjs/validateSearch.native.js +202 -0
  92. package/dist/cjs/validateSearch.native.js.map +1 -0
  93. package/dist/cjs/views/ErrorBoundary.cjs +293 -10
  94. package/dist/cjs/views/ErrorBoundary.js +328 -8
  95. package/dist/cjs/views/ErrorBoundary.js.map +2 -2
  96. package/dist/cjs/views/ErrorBoundary.native.js +159 -4
  97. package/dist/cjs/views/ErrorBoundary.native.js.map +1 -1
  98. package/dist/cjs/views/Navigator.cjs +10 -3
  99. package/dist/cjs/views/Navigator.js +7 -3
  100. package/dist/cjs/views/Navigator.js.map +1 -1
  101. package/dist/cjs/views/Navigator.native.js +12 -3
  102. package/dist/cjs/views/Navigator.native.js.map +1 -1
  103. package/dist/cjs/views/Protected.cjs +36 -0
  104. package/dist/cjs/views/Protected.js +27 -0
  105. package/dist/cjs/views/Protected.js.map +6 -0
  106. package/dist/cjs/views/Protected.native.js +44 -0
  107. package/dist/cjs/views/Protected.native.js.map +1 -0
  108. package/dist/cjs/views/RootErrorBoundary.cjs +193 -8
  109. package/dist/cjs/views/RootErrorBoundary.js +213 -8
  110. package/dist/cjs/views/RootErrorBoundary.js.map +1 -1
  111. package/dist/cjs/views/RootErrorBoundary.native.js +192 -8
  112. package/dist/cjs/views/RootErrorBoundary.native.js.map +1 -1
  113. package/dist/cjs/views/ScrollBehavior.cjs +49 -11
  114. package/dist/cjs/views/ScrollBehavior.js +47 -11
  115. package/dist/cjs/views/ScrollBehavior.js.map +1 -1
  116. package/dist/cjs/views/ScrollBehavior.native.js +68 -10
  117. package/dist/cjs/views/ScrollBehavior.native.js.map +1 -1
  118. package/dist/cjs/views/SourceInspector.cjs +28 -0
  119. package/dist/cjs/views/SourceInspector.js +23 -0
  120. package/dist/cjs/views/SourceInspector.js.map +6 -0
  121. package/dist/cjs/views/SourceInspector.native.js +32 -0
  122. package/dist/cjs/views/SourceInspector.native.js.map +1 -0
  123. package/dist/cjs/views/Try.cjs +40 -7
  124. package/dist/cjs/views/Try.js +38 -4
  125. package/dist/cjs/views/Try.js.map +1 -1
  126. package/dist/cjs/views/Try.native.js +42 -7
  127. package/dist/cjs/views/Try.native.js.map +1 -1
  128. package/dist/cjs/vite/DevHead.cjs +797 -43
  129. package/dist/cjs/vite/DevHead.js +802 -51
  130. package/dist/cjs/vite/DevHead.js.map +1 -1
  131. package/dist/cjs/vite/DevHead.native.js +783 -1
  132. package/dist/cjs/vite/DevHead.native.js.map +1 -1
  133. package/dist/cjs/vite/one.cjs +7 -1
  134. package/dist/cjs/vite/one.js +7 -2
  135. package/dist/cjs/vite/one.js.map +1 -1
  136. package/dist/cjs/vite/one.native.js +11 -1
  137. package/dist/cjs/vite/one.native.js.map +1 -1
  138. package/dist/cjs/vite/plugins/SSRCSSPlugin.cjs +44 -4
  139. package/dist/cjs/vite/plugins/SSRCSSPlugin.js +48 -4
  140. package/dist/cjs/vite/plugins/SSRCSSPlugin.js.map +1 -1
  141. package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js +62 -5
  142. package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
  143. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.js +6 -3
  144. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.js.map +1 -1
  145. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
  146. package/dist/cjs/vite/plugins/generateFileSystemRouteTypesPlugin.cjs +5 -1
  147. package/dist/cjs/vite/plugins/generateFileSystemRouteTypesPlugin.js +11 -6
  148. package/dist/cjs/vite/plugins/generateFileSystemRouteTypesPlugin.js.map +1 -1
  149. package/dist/cjs/vite/plugins/generateFileSystemRouteTypesPlugin.native.js +1 -0
  150. package/dist/cjs/vite/plugins/generateFileSystemRouteTypesPlugin.native.js.map +1 -1
  151. package/dist/cjs/vite/plugins/sourceInspectorPlugin.cjs +155 -0
  152. package/dist/cjs/vite/plugins/sourceInspectorPlugin.js +148 -0
  153. package/dist/cjs/vite/plugins/sourceInspectorPlugin.js.map +6 -0
  154. package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js +231 -0
  155. package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js.map +1 -0
  156. package/dist/cjs/vite/plugins/virtualEntryPlugin.cjs +25 -6
  157. package/dist/cjs/vite/plugins/virtualEntryPlugin.js +16 -6
  158. package/dist/cjs/vite/plugins/virtualEntryPlugin.js.map +1 -1
  159. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js +26 -7
  160. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  161. package/dist/esm/cli/buildPage.js +1 -1
  162. package/dist/esm/cli/buildPage.mjs +1 -1
  163. package/dist/esm/cli/buildPage.mjs.map +1 -1
  164. package/dist/esm/cli/buildPage.native.js +1 -1
  165. package/dist/esm/cli/buildPage.native.js.map +1 -1
  166. package/dist/esm/cli/dev.js +4 -4
  167. package/dist/esm/cli/dev.js.map +1 -1
  168. package/dist/esm/cli/dev.mjs +4 -4
  169. package/dist/esm/cli/dev.mjs.map +1 -1
  170. package/dist/esm/cli/dev.native.js +4 -4
  171. package/dist/esm/cli/dev.native.js.map +1 -1
  172. package/dist/esm/createApp.js +2 -2
  173. package/dist/esm/createApp.js.map +1 -1
  174. package/dist/esm/createApp.mjs +2 -1
  175. package/dist/esm/createApp.mjs.map +1 -1
  176. package/dist/esm/createHandleRequest.test.js +3 -1
  177. package/dist/esm/createHandleRequest.test.js.map +1 -1
  178. package/dist/esm/createHandleRequest.test.mjs.map +1 -1
  179. package/dist/esm/createHandleRequest.test.native.js.map +1 -1
  180. package/dist/esm/devtools/registry.js +9 -0
  181. package/dist/esm/devtools/registry.js.map +6 -0
  182. package/dist/esm/devtools/registry.mjs +6 -0
  183. package/dist/esm/devtools/registry.mjs.map +1 -0
  184. package/dist/esm/devtools/registry.native.js +6 -0
  185. package/dist/esm/devtools/registry.native.js.map +1 -0
  186. package/dist/esm/fork/createMemoryHistory.js +22 -4
  187. package/dist/esm/fork/createMemoryHistory.js.map +1 -1
  188. package/dist/esm/fork/createMemoryHistory.mjs +20 -9
  189. package/dist/esm/fork/createMemoryHistory.mjs.map +1 -1
  190. package/dist/esm/fork/createMemoryHistory.native.js +20 -9
  191. package/dist/esm/fork/createMemoryHistory.native.js.map +1 -1
  192. package/dist/esm/fork/useLinking.js +6 -5
  193. package/dist/esm/fork/useLinking.js.map +1 -1
  194. package/dist/esm/fork/useLinking.mjs +11 -5
  195. package/dist/esm/fork/useLinking.mjs.map +1 -1
  196. package/dist/esm/index.js +30 -2
  197. package/dist/esm/index.js.map +1 -1
  198. package/dist/esm/index.mjs +8 -2
  199. package/dist/esm/index.mjs.map +1 -1
  200. package/dist/esm/index.native.js +8 -2
  201. package/dist/esm/index.native.js.map +1 -1
  202. package/dist/esm/layouts/withLayoutContext.js +30 -12
  203. package/dist/esm/layouts/withLayoutContext.js.map +1 -1
  204. package/dist/esm/layouts/withLayoutContext.mjs +34 -15
  205. package/dist/esm/layouts/withLayoutContext.mjs.map +1 -1
  206. package/dist/esm/layouts/withLayoutContext.native.js +42 -19
  207. package/dist/esm/layouts/withLayoutContext.native.js.map +1 -1
  208. package/dist/esm/link/Link.js +3 -2
  209. package/dist/esm/link/Link.js.map +1 -1
  210. package/dist/esm/link/Link.mjs +5 -2
  211. package/dist/esm/link/Link.mjs.map +1 -1
  212. package/dist/esm/link/Link.native.js +6 -1
  213. package/dist/esm/link/Link.native.js.map +1 -1
  214. package/dist/esm/link/useLinkTo.js +6 -3
  215. package/dist/esm/link/useLinkTo.js.map +1 -1
  216. package/dist/esm/link/useLinkTo.mjs +11 -3
  217. package/dist/esm/link/useLinkTo.mjs.map +1 -1
  218. package/dist/esm/link/useLinkTo.native.js +11 -3
  219. package/dist/esm/link/useLinkTo.native.js.map +1 -1
  220. package/dist/esm/router/Route.js.map +1 -1
  221. package/dist/esm/router/Route.mjs.map +1 -1
  222. package/dist/esm/router/Route.native.js.map +1 -1
  223. package/dist/esm/router/findRouteNode.js +56 -0
  224. package/dist/esm/router/findRouteNode.js.map +6 -0
  225. package/dist/esm/router/findRouteNode.mjs +44 -0
  226. package/dist/esm/router/findRouteNode.mjs.map +1 -0
  227. package/dist/esm/router/findRouteNode.native.js +75 -0
  228. package/dist/esm/router/findRouteNode.native.js.map +1 -0
  229. package/dist/esm/router/router.js +154 -6
  230. package/dist/esm/router/router.js.map +1 -1
  231. package/dist/esm/router/router.mjs +151 -10
  232. package/dist/esm/router/router.mjs.map +1 -1
  233. package/dist/esm/router/router.native.js +232 -56
  234. package/dist/esm/router/router.native.js.map +1 -1
  235. package/dist/esm/router/useScreens.js +1 -1
  236. package/dist/esm/router/useScreens.js.map +1 -1
  237. package/dist/esm/router/useScreens.mjs +1 -1
  238. package/dist/esm/router/useScreens.mjs.map +1 -1
  239. package/dist/esm/router/useScreens.native.js +5 -2
  240. package/dist/esm/router/useScreens.native.js.map +1 -1
  241. package/dist/esm/server/oneServe.js.map +1 -1
  242. package/dist/esm/server/oneServe.mjs.map +1 -1
  243. package/dist/esm/server/oneServe.native.js.map +1 -1
  244. package/dist/esm/useBlocker.js +122 -0
  245. package/dist/esm/useBlocker.js.map +6 -0
  246. package/dist/esm/useBlocker.mjs +123 -0
  247. package/dist/esm/useBlocker.mjs.map +1 -0
  248. package/dist/esm/useBlocker.native.js +51 -0
  249. package/dist/esm/useBlocker.native.js.map +1 -0
  250. package/dist/esm/useLoader.js +57 -3
  251. package/dist/esm/useLoader.js.map +2 -2
  252. package/dist/esm/useLoader.mjs +69 -4
  253. package/dist/esm/useLoader.mjs.map +1 -1
  254. package/dist/esm/useLoader.native.js +90 -7
  255. package/dist/esm/useLoader.native.js.map +1 -1
  256. package/dist/esm/useScrollGroup.js +16 -0
  257. package/dist/esm/useScrollGroup.js.map +6 -0
  258. package/dist/esm/useScrollGroup.mjs +14 -0
  259. package/dist/esm/useScrollGroup.mjs.map +1 -0
  260. package/dist/esm/useScrollGroup.native.js +3 -0
  261. package/dist/esm/useScrollGroup.native.js.map +1 -0
  262. package/dist/esm/validateParams.js +68 -0
  263. package/dist/esm/validateParams.js.map +6 -0
  264. package/dist/esm/validateParams.mjs +54 -0
  265. package/dist/esm/validateParams.mjs.map +1 -0
  266. package/dist/esm/validateParams.native.js +151 -0
  267. package/dist/esm/validateParams.native.js.map +1 -0
  268. package/dist/esm/validateSearch.js +83 -0
  269. package/dist/esm/validateSearch.js.map +6 -0
  270. package/dist/esm/validateSearch.mjs +77 -0
  271. package/dist/esm/validateSearch.mjs.map +1 -0
  272. package/dist/esm/validateSearch.native.js +172 -0
  273. package/dist/esm/validateSearch.native.js.map +1 -0
  274. package/dist/esm/views/ErrorBoundary.js +325 -7
  275. package/dist/esm/views/ErrorBoundary.js.map +2 -2
  276. package/dist/esm/views/ErrorBoundary.mjs +289 -6
  277. package/dist/esm/views/ErrorBoundary.mjs.map +1 -1
  278. package/dist/esm/views/ErrorBoundary.native.js +159 -4
  279. package/dist/esm/views/ErrorBoundary.native.js.map +1 -1
  280. package/dist/esm/views/Navigator.js +7 -2
  281. package/dist/esm/views/Navigator.js.map +1 -1
  282. package/dist/esm/views/Navigator.mjs +10 -3
  283. package/dist/esm/views/Navigator.mjs.map +1 -1
  284. package/dist/esm/views/Navigator.native.js +12 -3
  285. package/dist/esm/views/Navigator.native.js.map +1 -1
  286. package/dist/esm/views/Protected.js +14 -0
  287. package/dist/esm/views/Protected.js.map +6 -0
  288. package/dist/esm/views/Protected.mjs +11 -0
  289. package/dist/esm/views/Protected.mjs.map +1 -0
  290. package/dist/esm/views/Protected.native.js +16 -0
  291. package/dist/esm/views/Protected.native.js.map +1 -0
  292. package/dist/esm/views/RootErrorBoundary.js +214 -7
  293. package/dist/esm/views/RootErrorBoundary.js.map +1 -1
  294. package/dist/esm/views/RootErrorBoundary.mjs +192 -7
  295. package/dist/esm/views/RootErrorBoundary.mjs.map +1 -1
  296. package/dist/esm/views/RootErrorBoundary.native.js +191 -7
  297. package/dist/esm/views/RootErrorBoundary.native.js.map +1 -1
  298. package/dist/esm/views/ScrollBehavior.js +47 -11
  299. package/dist/esm/views/ScrollBehavior.js.map +1 -1
  300. package/dist/esm/views/ScrollBehavior.mjs +48 -11
  301. package/dist/esm/views/ScrollBehavior.mjs.map +1 -1
  302. package/dist/esm/views/ScrollBehavior.native.js +67 -10
  303. package/dist/esm/views/ScrollBehavior.native.js.map +1 -1
  304. package/dist/esm/views/SourceInspector.js +7 -0
  305. package/dist/esm/views/SourceInspector.js.map +6 -0
  306. package/dist/esm/views/SourceInspector.mjs +5 -0
  307. package/dist/esm/views/SourceInspector.mjs.map +1 -0
  308. package/dist/esm/views/SourceInspector.native.js +6 -0
  309. package/dist/esm/views/SourceInspector.native.js.map +1 -0
  310. package/dist/esm/views/Try.js +38 -4
  311. package/dist/esm/views/Try.js.map +1 -1
  312. package/dist/esm/views/Try.mjs +40 -7
  313. package/dist/esm/views/Try.mjs.map +1 -1
  314. package/dist/esm/views/Try.native.js +42 -7
  315. package/dist/esm/views/Try.native.js.map +1 -1
  316. package/dist/esm/vite/DevHead.js +802 -51
  317. package/dist/esm/vite/DevHead.js.map +1 -1
  318. package/dist/esm/vite/DevHead.mjs +797 -43
  319. package/dist/esm/vite/DevHead.mjs.map +1 -1
  320. package/dist/esm/vite/DevHead.native.js +782 -0
  321. package/dist/esm/vite/DevHead.native.js.map +1 -1
  322. package/dist/esm/vite/one.js +7 -1
  323. package/dist/esm/vite/one.js.map +1 -1
  324. package/dist/esm/vite/one.mjs +7 -1
  325. package/dist/esm/vite/one.mjs.map +1 -1
  326. package/dist/esm/vite/one.native.js +11 -1
  327. package/dist/esm/vite/one.native.js.map +1 -1
  328. package/dist/esm/vite/plugins/SSRCSSPlugin.js +48 -4
  329. package/dist/esm/vite/plugins/SSRCSSPlugin.js.map +1 -1
  330. package/dist/esm/vite/plugins/SSRCSSPlugin.mjs +44 -4
  331. package/dist/esm/vite/plugins/SSRCSSPlugin.mjs.map +1 -1
  332. package/dist/esm/vite/plugins/SSRCSSPlugin.native.js +61 -4
  333. package/dist/esm/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
  334. package/dist/esm/vite/plugins/fileSystemRouterPlugin.js +6 -3
  335. package/dist/esm/vite/plugins/fileSystemRouterPlugin.js.map +1 -1
  336. package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
  337. package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
  338. package/dist/esm/vite/plugins/generateFileSystemRouteTypesPlugin.js +11 -6
  339. package/dist/esm/vite/plugins/generateFileSystemRouteTypesPlugin.js.map +1 -1
  340. package/dist/esm/vite/plugins/generateFileSystemRouteTypesPlugin.mjs +5 -1
  341. package/dist/esm/vite/plugins/generateFileSystemRouteTypesPlugin.mjs.map +1 -1
  342. package/dist/esm/vite/plugins/generateFileSystemRouteTypesPlugin.native.js +1 -0
  343. package/dist/esm/vite/plugins/generateFileSystemRouteTypesPlugin.native.js.map +1 -1
  344. package/dist/esm/vite/plugins/sourceInspectorPlugin.js +126 -0
  345. package/dist/esm/vite/plugins/sourceInspectorPlugin.js.map +6 -0
  346. package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs +121 -0
  347. package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs.map +1 -0
  348. package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js +194 -0
  349. package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js.map +1 -0
  350. package/dist/esm/vite/plugins/virtualEntryPlugin.js +16 -6
  351. package/dist/esm/vite/plugins/virtualEntryPlugin.js.map +1 -1
  352. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs +25 -6
  353. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs.map +1 -1
  354. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js +26 -7
  355. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  356. package/package.json +11 -9
  357. package/src/cli/buildPage.ts +1 -1
  358. package/src/cli/dev.ts +4 -4
  359. package/src/createApp.tsx +11 -1
  360. package/src/createHandleRequest.test.ts +3 -1
  361. package/src/devtools/registry.ts +21 -0
  362. package/src/fork/createMemoryHistory.tsx +43 -11
  363. package/src/fork/useLinking.ts +14 -4
  364. package/src/index.ts +34 -1
  365. package/src/interfaces/router.ts +48 -0
  366. package/src/layouts/withLayoutContext.tsx +48 -8
  367. package/src/link/Link.tsx +7 -2
  368. package/src/link/useLinkTo.tsx +7 -3
  369. package/src/router/Route.tsx +32 -3
  370. package/src/router/findRouteNode.ts +127 -0
  371. package/src/router/router.ts +286 -2
  372. package/src/router/useScreens.tsx +9 -3
  373. package/src/useBlocker.native.ts +153 -0
  374. package/src/useBlocker.ts +340 -0
  375. package/src/useLoader.ts +139 -1
  376. package/src/useScrollGroup.native.ts +7 -0
  377. package/src/useScrollGroup.ts +44 -0
  378. package/src/validateParams.ts +196 -0
  379. package/src/validateSearch.ts +241 -0
  380. package/src/views/ErrorBoundary.tsx +154 -156
  381. package/src/views/ErrorBoundary.web.tsx +321 -0
  382. package/src/views/Navigator.tsx +14 -2
  383. package/src/views/Protected.tsx +62 -0
  384. package/src/views/RootErrorBoundary.tsx +214 -17
  385. package/src/views/ScrollBehavior.tsx +82 -3
  386. package/src/views/SourceInspector.tsx +39 -0
  387. package/src/views/Try.tsx +81 -12
  388. package/src/vite/DevHead.tsx +819 -54
  389. package/src/vite/one.ts +13 -0
  390. package/src/vite/plugins/SSRCSSPlugin.ts +104 -0
  391. package/src/vite/plugins/fileSystemRouterPlugin.tsx +11 -8
  392. package/src/vite/plugins/generateFileSystemRouteTypesPlugin.tsx +4 -0
  393. package/src/vite/plugins/sourceInspectorPlugin.ts +246 -0
  394. package/src/vite/plugins/virtualEntryPlugin.ts +35 -10
  395. package/src/vite/types.ts +28 -0
  396. package/types/Route.d.ts.map +1 -0
  397. package/types/cleanUrl.d.ts.map +1 -0
  398. package/types/cli/run.d.ts.map +1 -0
  399. package/types/createApp.d.ts +5 -0
  400. package/types/createApp.d.ts.map +1 -1
  401. package/types/createRoute.d.ts.map +1 -0
  402. package/types/devtools/registry.d.ts +15 -0
  403. package/types/devtools/registry.d.ts.map +1 -0
  404. package/types/fork/NavigationContainer.native.d.ts.map +1 -0
  405. package/types/fork/createMemoryHistory.d.ts +8 -3
  406. package/types/fork/createMemoryHistory.d.ts.map +1 -1
  407. package/types/fork/useLinking.d.ts.map +1 -1
  408. package/types/getLinkingConfig.d.ts.map +1 -0
  409. package/types/getRoutes.d.ts.map +1 -0
  410. package/types/imperative-api.d.ts.map +1 -0
  411. package/types/index.d.ts +8 -1
  412. package/types/index.d.ts.map +1 -1
  413. package/types/interfaces/router.d.ts +47 -0
  414. package/types/interfaces/router.d.ts.map +1 -1
  415. package/types/layouts/withLayoutContext.d.ts +2 -1
  416. package/types/layouts/withLayoutContext.d.ts.map +1 -1
  417. package/types/link/Link.d.ts.map +1 -1
  418. package/types/link/useLinkTo.d.ts +1 -0
  419. package/types/link/useLinkTo.d.ts.map +1 -1
  420. package/types/matchers.d.ts.map +1 -0
  421. package/types/platform.d.ts.map +1 -0
  422. package/types/router/Route.d.ts +32 -3
  423. package/types/router/Route.d.ts.map +1 -1
  424. package/types/router/findRouteNode.d.ts +31 -0
  425. package/types/router/findRouteNode.d.ts.map +1 -0
  426. package/types/router/router.d.ts +35 -0
  427. package/types/router/router.d.ts.map +1 -1
  428. package/types/router/useScreens.d.ts +2 -0
  429. package/types/router/useScreens.d.ts.map +1 -1
  430. package/types/server/oneServe.d.ts.map +1 -1
  431. package/types/sortRoutes.d.ts.map +1 -0
  432. package/types/useBlocker.d.ts +72 -0
  433. package/types/useBlocker.d.ts.map +1 -0
  434. package/types/useBlocker.native.d.ts +60 -0
  435. package/types/useBlocker.native.d.ts.map +1 -0
  436. package/types/useLoader.d.ts +10 -0
  437. package/types/useLoader.d.ts.map +1 -1
  438. package/types/useNavigation.d.ts.map +1 -0
  439. package/types/useScreens.d.ts.map +1 -0
  440. package/types/useScrollGroup.d.ts +27 -0
  441. package/types/useScrollGroup.d.ts.map +1 -0
  442. package/types/useScrollGroup.native.d.ts +6 -0
  443. package/types/useScrollGroup.native.d.ts.map +1 -0
  444. package/types/useSearch.d.ts.map +1 -0
  445. package/types/useViteRoutes.d.ts.map +1 -0
  446. package/types/validateParams.d.ts +85 -0
  447. package/types/validateParams.d.ts.map +1 -0
  448. package/types/validateSearch.d.ts +107 -0
  449. package/types/validateSearch.d.ts.map +1 -0
  450. package/types/views/ErrorBoundary.d.ts +11 -1
  451. package/types/views/ErrorBoundary.d.ts.map +1 -1
  452. package/types/views/ErrorBoundary.web.d.ts +13 -0
  453. package/types/views/ErrorBoundary.web.d.ts.map +1 -0
  454. package/types/views/Navigator.d.ts.map +1 -1
  455. package/types/views/Protected.d.ts +39 -0
  456. package/types/views/Protected.d.ts.map +1 -0
  457. package/types/views/RootErrorBoundary.d.ts +14 -8
  458. package/types/views/RootErrorBoundary.d.ts.map +1 -1
  459. package/types/views/ScrollBehavior.d.ts +8 -0
  460. package/types/views/ScrollBehavior.d.ts.map +1 -1
  461. package/types/views/ScrollRestoration.d.ts.map +1 -0
  462. package/types/views/SourceInspector.d.ts +35 -0
  463. package/types/views/SourceInspector.d.ts.map +1 -0
  464. package/types/views/Try.d.ts +29 -6
  465. package/types/views/Try.d.ts.map +1 -1
  466. package/types/vite/DevHead.d.ts.map +1 -1
  467. package/types/vite/build.d.ts.map +1 -0
  468. package/types/vite/headers.d.ts.map +1 -0
  469. package/types/vite/headers.native.d.ts.map +1 -0
  470. package/types/vite/one.d.ts.map +1 -1
  471. package/types/vite/plugins/SSRCSSPlugin.d.ts.map +1 -1
  472. package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
  473. package/types/vite/plugins/generateFileSystemRouteTypesPlugin.d.ts.map +1 -1
  474. package/types/vite/plugins/seoPreviewPlugin.d.ts.map +1 -0
  475. package/types/vite/plugins/sourceInspectorPlugin.d.ts +3 -0
  476. package/types/vite/plugins/sourceInspectorPlugin.d.ts.map +1 -0
  477. package/types/vite/plugins/virtualEntryPlugin.d.ts.map +1 -1
  478. package/types/vite/resolveAPIRequest.d.ts.map +1 -0
  479. package/types/vite/server.d.ts.map +1 -0
  480. package/types/vite/types.d.ts +24 -0
  481. package/types/vite/types.d.ts.map +1 -1
@@ -0,0 +1,340 @@
1
+ import * as React from 'react'
2
+ import { Platform } from 'react-native'
3
+
4
+ export type BlockerState = 'unblocked' | 'blocked' | 'proceeding'
5
+
6
+ export type BlockerFunction = (args: {
7
+ currentLocation: string
8
+ nextLocation: string
9
+ historyAction: 'push' | 'pop' | 'replace'
10
+ }) => boolean
11
+
12
+ export type Blocker =
13
+ | {
14
+ state: 'unblocked'
15
+ reset?: undefined
16
+ proceed?: undefined
17
+ location?: undefined
18
+ }
19
+ | {
20
+ state: 'blocked'
21
+ reset: () => void
22
+ proceed: () => void
23
+ location: string
24
+ }
25
+ | {
26
+ state: 'proceeding'
27
+ reset?: undefined
28
+ proceed?: undefined
29
+ location: string
30
+ }
31
+
32
+ /**
33
+ * Stored pending navigation that was blocked.
34
+ * We need to restore it when the user confirms.
35
+ */
36
+ type PendingNavigation = {
37
+ previousLocation: string
38
+ nextLocation: string
39
+ historyAction: 'push' | 'pop' | 'replace'
40
+ }
41
+
42
+ // Global state for blocking
43
+ let currentLocation =
44
+ typeof window !== 'undefined' ? window.location.pathname + window.location.search : ''
45
+ let isBlocking = false
46
+ let isProceeding = false
47
+ let pendingNavigation: PendingNavigation | null = null
48
+
49
+ // Active blocker callbacks
50
+ const blockerCallbacks = new Map<
51
+ symbol,
52
+ {
53
+ shouldBlock: () => boolean
54
+ onBlock: (pending: PendingNavigation) => void
55
+ onProceed: () => void
56
+ onReset: () => void
57
+ }
58
+ >()
59
+
60
+ // Track if global listeners are set up
61
+ let listenersSetup = false
62
+
63
+ function setupListeners() {
64
+ if (listenersSetup || typeof window === 'undefined') return
65
+ listenersSetup = true
66
+
67
+ // Track current location on page load
68
+ currentLocation = window.location.pathname + window.location.search
69
+
70
+ // Listen for popstate (browser back/forward)
71
+ window.addEventListener('popstate', () => {
72
+ if (isProceeding) return
73
+
74
+ const nextLocation = window.location.pathname + window.location.search
75
+
76
+ // Check if any blocker wants to block
77
+ for (const [, callbacks] of blockerCallbacks) {
78
+ if (callbacks.shouldBlock()) {
79
+ // Block the navigation
80
+ isBlocking = true
81
+ pendingNavigation = {
82
+ previousLocation: currentLocation,
83
+ nextLocation,
84
+ historyAction: 'pop',
85
+ }
86
+
87
+ // Restore the previous URL immediately using history.forward() or history.back()
88
+ // We pushed a state when we got here, so we need to go back
89
+ window.history.go(1) // Go forward to restore
90
+
91
+ // Notify the blocker
92
+ callbacks.onBlock(pendingNavigation)
93
+ return
94
+ }
95
+ }
96
+
97
+ // No blocking, update current location
98
+ currentLocation = nextLocation
99
+ })
100
+
101
+ // Intercept pushState and replaceState
102
+ const originalPushState = window.history.pushState.bind(window.history)
103
+ const originalReplaceState = window.history.replaceState.bind(window.history)
104
+
105
+ window.history.pushState = function (state, title, url) {
106
+ if (isProceeding || !url) {
107
+ return originalPushState(state, title, url)
108
+ }
109
+
110
+ const nextLocation = typeof url === 'string' ? url : url.toString()
111
+
112
+ for (const [, callbacks] of blockerCallbacks) {
113
+ if (callbacks.shouldBlock()) {
114
+ isBlocking = true
115
+ pendingNavigation = {
116
+ previousLocation: currentLocation,
117
+ nextLocation,
118
+ historyAction: 'push',
119
+ }
120
+ callbacks.onBlock(pendingNavigation)
121
+ return // Don't call original
122
+ }
123
+ }
124
+
125
+ currentLocation = nextLocation
126
+ return originalPushState(state, title, url)
127
+ }
128
+
129
+ window.history.replaceState = function (state, title, url) {
130
+ if (isProceeding || !url) {
131
+ return originalReplaceState(state, title, url)
132
+ }
133
+
134
+ const nextLocation = typeof url === 'string' ? url : url.toString()
135
+
136
+ for (const [, callbacks] of blockerCallbacks) {
137
+ if (callbacks.shouldBlock()) {
138
+ isBlocking = true
139
+ pendingNavigation = {
140
+ previousLocation: currentLocation,
141
+ nextLocation,
142
+ historyAction: 'replace',
143
+ }
144
+ callbacks.onBlock(pendingNavigation)
145
+ return // Don't call original
146
+ }
147
+ }
148
+
149
+ currentLocation = nextLocation
150
+ return originalReplaceState(state, title, url)
151
+ }
152
+
153
+ // Handle beforeunload (page close/refresh)
154
+ window.addEventListener('beforeunload', (event) => {
155
+ for (const [, callbacks] of blockerCallbacks) {
156
+ if (callbacks.shouldBlock()) {
157
+ event.preventDefault()
158
+ event.returnValue = ''
159
+ return
160
+ }
161
+ }
162
+ })
163
+ }
164
+
165
+ /**
166
+ * Block navigation when a condition is met.
167
+ *
168
+ * This is useful for preventing users from accidentally leaving a page with unsaved changes.
169
+ * Works with both browser navigation (back/forward, URL changes) and programmatic navigation.
170
+ *
171
+ * @param shouldBlock - Either a boolean or a function that returns whether to block.
172
+ * When using a function, you receive the current and next locations and can make dynamic decisions.
173
+ *
174
+ * @example
175
+ * ```tsx
176
+ * function EditForm() {
177
+ * const [isDirty, setIsDirty] = useState(false)
178
+ * const blocker = useBlocker(isDirty)
179
+ *
180
+ * return (
181
+ * <>
182
+ * <form onChange={() => setIsDirty(true)}>
183
+ * {// form fields}
184
+ * </form>
185
+ *
186
+ * {blocker.state === 'blocked' && (
187
+ * <Dialog>
188
+ * <p>You have unsaved changes. Leave anyway?</p>
189
+ * <button onClick={blocker.reset}>Stay</button>
190
+ * <button onClick={blocker.proceed}>Leave</button>
191
+ * </Dialog>
192
+ * )}
193
+ * </>
194
+ * )
195
+ * }
196
+ * ```
197
+ *
198
+ * @example
199
+ * ```tsx
200
+ * // Function-based blocking with location info
201
+ * const blocker = useBlocker(({ currentLocation, nextLocation }) => {
202
+ * // Only block when leaving this specific section
203
+ * return currentLocation.startsWith('/edit') && !nextLocation.startsWith('/edit')
204
+ * })
205
+ * ```
206
+ */
207
+ export function useBlocker(shouldBlock: BlockerFunction | boolean): Blocker {
208
+ const [state, setState] = React.useState<BlockerState>('unblocked')
209
+ const [blockedLocation, setBlockedLocation] = React.useState<string | null>(null)
210
+ const idRef = React.useRef<symbol | null>(null)
211
+
212
+ const shouldBlockRef = React.useRef(shouldBlock)
213
+ shouldBlockRef.current = shouldBlock
214
+
215
+ React.useEffect(() => {
216
+ // Only run on web
217
+ if (Platform.OS !== 'web' || typeof window === 'undefined') return
218
+
219
+ setupListeners()
220
+
221
+ const id = Symbol('blocker')
222
+ idRef.current = id
223
+
224
+ blockerCallbacks.set(id, {
225
+ shouldBlock: () => {
226
+ const block = shouldBlockRef.current
227
+ if (typeof block === 'function') {
228
+ return block({
229
+ currentLocation,
230
+ nextLocation: pendingNavigation?.nextLocation || '',
231
+ historyAction: pendingNavigation?.historyAction || 'push',
232
+ })
233
+ }
234
+ return block
235
+ },
236
+ onBlock: (pending) => {
237
+ setBlockedLocation(pending.nextLocation)
238
+ setState('blocked')
239
+ },
240
+ onProceed: () => {
241
+ setState('proceeding')
242
+ },
243
+ onReset: () => {
244
+ setState('unblocked')
245
+ setBlockedLocation(null)
246
+ },
247
+ })
248
+
249
+ return () => {
250
+ blockerCallbacks.delete(id)
251
+ }
252
+ }, [])
253
+
254
+ const reset = React.useCallback(() => {
255
+ isBlocking = false
256
+ pendingNavigation = null
257
+ setBlockedLocation(null)
258
+ setState('unblocked')
259
+ }, [])
260
+
261
+ const proceed = React.useCallback(() => {
262
+ if (!pendingNavigation) return
263
+
264
+ setState('proceeding')
265
+ isProceeding = true
266
+
267
+ const pending = pendingNavigation
268
+ pendingNavigation = null
269
+ isBlocking = false
270
+
271
+ // Execute the blocked navigation
272
+ requestAnimationFrame(() => {
273
+ if (pending.historyAction === 'pop') {
274
+ // Go back to where the user wanted to go
275
+ window.history.back()
276
+ } else if (pending.historyAction === 'push') {
277
+ window.history.pushState(null, '', pending.nextLocation)
278
+ } else {
279
+ window.history.replaceState(null, '', pending.nextLocation)
280
+ }
281
+
282
+ currentLocation = pending.nextLocation
283
+
284
+ // Reset state after navigation
285
+ requestAnimationFrame(() => {
286
+ isProceeding = false
287
+ setBlockedLocation(null)
288
+ setState('unblocked')
289
+ })
290
+ })
291
+ }, [])
292
+
293
+ if (state === 'unblocked') {
294
+ return { state: 'unblocked' }
295
+ }
296
+
297
+ if (state === 'proceeding') {
298
+ return { state: 'proceeding', location: blockedLocation! }
299
+ }
300
+
301
+ return {
302
+ state: 'blocked',
303
+ reset,
304
+ proceed,
305
+ location: blockedLocation!,
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Check if any active blocker wants to block navigation.
311
+ * Called by the router before navigating via Link.
312
+ * Returns true if navigation was blocked.
313
+ */
314
+ export function checkBlocker(
315
+ nextLocation: string,
316
+ historyAction: 'push' | 'pop' | 'replace' = 'push'
317
+ ): boolean {
318
+ if (Platform.OS !== 'web' || typeof window === 'undefined') {
319
+ return false
320
+ }
321
+
322
+ if (isProceeding) {
323
+ return false
324
+ }
325
+
326
+ for (const [, callbacks] of blockerCallbacks) {
327
+ if (callbacks.shouldBlock()) {
328
+ isBlocking = true
329
+ pendingNavigation = {
330
+ previousLocation: currentLocation,
331
+ nextLocation,
332
+ historyAction,
333
+ }
334
+ callbacks.onBlock(pendingNavigation)
335
+ return true
336
+ }
337
+ }
338
+
339
+ return false
340
+ }
package/src/useLoader.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useDeferredValue, useSyncExternalStore } from 'react'
2
+ import { registerDevtoolsFunction } from './devtools/registry'
2
3
  import { useParams, usePathname } from './hooks'
3
4
  import { preloadedLoaderData, preloadingLoader } from './router/router'
4
5
  import { getLoaderPath } from './utils/cleanUrl'
@@ -15,6 +16,60 @@ type LoaderStateEntry = {
15
16
  hasLoadedOnce?: boolean
16
17
  }
17
18
 
19
+ // Timing data for loader waterfall devtool (dev only)
20
+ export type LoaderTimingEntry = {
21
+ path: string
22
+ startTime: number
23
+ moduleLoadTime?: number
24
+ executionTime?: number
25
+ totalTime?: number
26
+ error?: string
27
+ source: 'preload' | 'initial' | 'refetch'
28
+ }
29
+
30
+ // Store timing history for devtools - only populated in development
31
+ const loaderTimingHistory: LoaderTimingEntry[] = []
32
+ const MAX_TIMING_HISTORY = 50
33
+
34
+ function recordLoaderTiming(entry: LoaderTimingEntry) {
35
+ if (process.env.NODE_ENV !== 'development') return
36
+
37
+ loaderTimingHistory.unshift(entry)
38
+ if (loaderTimingHistory.length > MAX_TIMING_HISTORY) {
39
+ loaderTimingHistory.pop()
40
+ }
41
+ // Dispatch event for devtools
42
+ if (typeof window !== 'undefined') {
43
+ window.dispatchEvent(new CustomEvent('one-loader-timing', { detail: entry }))
44
+
45
+ // Also dispatch error event if there was an error
46
+ if (entry.error) {
47
+ window.dispatchEvent(
48
+ new CustomEvent('one-error', {
49
+ detail: {
50
+ error: {
51
+ message: entry.error,
52
+ name: 'LoaderError',
53
+ },
54
+ route: {
55
+ pathname: entry.path,
56
+ },
57
+ timestamp: Date.now(),
58
+ type: 'loader',
59
+ },
60
+ })
61
+ )
62
+ }
63
+ }
64
+ }
65
+
66
+ export function getLoaderTimingHistory(): LoaderTimingEntry[] {
67
+ return loaderTimingHistory
68
+ }
69
+
70
+ // Register with devtools registry so router.ts doesn't need to dynamically import us
71
+ registerDevtoolsFunction('getLoaderTimingHistory', getLoaderTimingHistory)
72
+
18
73
  const loaderState: Record<string, LoaderStateEntry> = {}
19
74
  const subscribers = new Set<() => void>()
20
75
 
@@ -44,6 +99,8 @@ function getLoaderState(path: string, preloadedData?: any): LoaderStateEntry {
44
99
  }
45
100
 
46
101
  export async function refetchLoader(pathname: string): Promise<void> {
102
+ const startTime = performance.now()
103
+
47
104
  updateState(pathname, {
48
105
  state: 'loading',
49
106
  error: null,
@@ -53,8 +110,15 @@ export async function refetchLoader(pathname: string): Promise<void> {
53
110
  const cacheBust = `${Date.now()}`
54
111
  const loaderJSUrl = getLoaderPath(pathname, true, cacheBust)
55
112
 
113
+ const moduleLoadStart = performance.now()
56
114
  const module = await dynamicImport(loaderJSUrl)
115
+ const moduleLoadTime = performance.now() - moduleLoadStart
116
+
117
+ const executionStart = performance.now()
57
118
  const result = await module.loader()
119
+ const executionTime = performance.now() - executionStart
120
+
121
+ const totalTime = performance.now() - startTime
58
122
 
59
123
  updateState(pathname, {
60
124
  data: result,
@@ -62,16 +126,37 @@ export async function refetchLoader(pathname: string): Promise<void> {
62
126
  timestamp: Date.now(),
63
127
  hasLoadedOnce: true,
64
128
  })
129
+
130
+ recordLoaderTiming({
131
+ path: pathname,
132
+ startTime,
133
+ moduleLoadTime,
134
+ executionTime,
135
+ totalTime,
136
+ source: 'refetch',
137
+ })
65
138
  } catch (err) {
139
+ const totalTime = performance.now() - startTime
140
+
66
141
  updateState(pathname, {
67
142
  error: err,
68
143
  state: 'idle',
69
144
  })
145
+
146
+ recordLoaderTiming({
147
+ path: pathname,
148
+ startTime,
149
+ totalTime,
150
+ error: err instanceof Error ? err.message : String(err),
151
+ source: 'refetch',
152
+ })
153
+
70
154
  throw err
71
155
  }
72
156
  }
73
157
 
74
- if (typeof window !== 'undefined') {
158
+ // Expose refetchLoader globally for HMR in development
159
+ if (process.env.NODE_ENV === 'development' && typeof window !== 'undefined') {
75
160
  ;(window as any).__oneRefetchLoader = refetchLoader
76
161
  }
77
162
 
@@ -172,12 +257,15 @@ export function useLoaderState<
172
257
  } else {
173
258
  // initial load
174
259
  const loadData = async () => {
260
+ const startTime = performance.now()
261
+
175
262
  try {
176
263
  if (process.env.TAMAGUI_TARGET === 'native') {
177
264
  const loaderJSUrl = getLoaderPath(currentPath, true)
178
265
  const nativeLoaderJSUrl = `${loaderJSUrl}?platform=ios`
179
266
 
180
267
  try {
268
+ const moduleLoadStart = performance.now()
181
269
  const loaderJsCodeResp = await fetch(nativeLoaderJSUrl)
182
270
  if (!loaderJsCodeResp.ok) {
183
271
  throw new Error(`Response not ok: ${loaderJsCodeResp.status}`)
@@ -187,41 +275,91 @@ export function useLoaderState<
187
275
  const result = eval(
188
276
  `() => { var exports = {}; ${loaderJsCode}; return exports; }`
189
277
  )()
278
+ const moduleLoadTime = performance.now() - moduleLoadStart
190
279
 
191
280
  if (typeof result.loader !== 'function') {
192
281
  throw new Error("Loader code isn't exporting a `loader` function")
193
282
  }
194
283
 
284
+ const executionStart = performance.now()
195
285
  const data = await result.loader()
286
+ const executionTime = performance.now() - executionStart
287
+ const totalTime = performance.now() - startTime
288
+
196
289
  updateState(currentPath, {
197
290
  data,
198
291
  hasLoadedOnce: true,
199
292
  promise: undefined,
200
293
  })
294
+
295
+ recordLoaderTiming({
296
+ path: currentPath,
297
+ startTime,
298
+ moduleLoadTime,
299
+ executionTime,
300
+ totalTime,
301
+ source: 'initial',
302
+ })
201
303
  return
202
304
  } catch (e) {
305
+ const totalTime = performance.now() - startTime
203
306
  updateState(currentPath, {
204
307
  data: {},
205
308
  promise: undefined,
206
309
  })
310
+ recordLoaderTiming({
311
+ path: currentPath,
312
+ startTime,
313
+ totalTime,
314
+ error: e instanceof Error ? e.message : String(e),
315
+ source: 'initial',
316
+ })
207
317
  return
208
318
  }
209
319
  }
210
320
 
211
321
  // web platform
212
322
  const loaderJSUrl = getLoaderPath(currentPath, true)
323
+
324
+ const moduleLoadStart = performance.now()
213
325
  const module = await dynamicImport(loaderJSUrl)
326
+ const moduleLoadTime = performance.now() - moduleLoadStart
327
+
328
+ const executionStart = performance.now()
214
329
  const result = await module.loader()
330
+ const executionTime = performance.now() - executionStart
331
+
332
+ const totalTime = performance.now() - startTime
333
+
215
334
  updateState(currentPath, {
216
335
  data: result,
217
336
  hasLoadedOnce: true,
218
337
  promise: undefined,
219
338
  })
339
+
340
+ recordLoaderTiming({
341
+ path: currentPath,
342
+ startTime,
343
+ moduleLoadTime,
344
+ executionTime,
345
+ totalTime,
346
+ source: 'initial',
347
+ })
220
348
  } catch (err) {
349
+ const totalTime = performance.now() - startTime
350
+
221
351
  updateState(currentPath, {
222
352
  error: err,
223
353
  promise: undefined,
224
354
  })
355
+
356
+ recordLoaderTiming({
357
+ path: currentPath,
358
+ startTime,
359
+ totalTime,
360
+ error: err instanceof Error ? err.message : String(err),
361
+ source: 'initial',
362
+ })
225
363
  }
226
364
  }
227
365
 
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Native no-op for useScrollGroup.
3
+ * Scroll position groups are a web-only feature.
4
+ */
5
+ export function useScrollGroup(_groupPath?: string) {
6
+ // No-op on native - scroll position is handled differently
7
+ }
@@ -0,0 +1,44 @@
1
+ import { useEffect } from 'react'
2
+ import { usePathname } from './hooks'
3
+ import { registerScrollGroup } from './views/ScrollBehavior'
4
+
5
+ /**
6
+ * Register the current route as a scroll group.
7
+ * Child routes will preserve scroll position when navigating between them.
8
+ *
9
+ * Use this in a layout component to create a scroll group for all its children.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * // app/dashboard/_layout.tsx
14
+ * import { useScrollGroup } from 'one'
15
+ *
16
+ * export default function DashboardLayout() {
17
+ * // All routes under /dashboard will share scroll position
18
+ * useScrollGroup()
19
+ *
20
+ * return <Slot />
21
+ * }
22
+ * ```
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * // Custom group path
27
+ * useScrollGroup('/products')
28
+ * ```
29
+ */
30
+ export function useScrollGroup(groupPath?: string) {
31
+ const pathname = usePathname()
32
+
33
+ useEffect(() => {
34
+ // Use provided groupPath or derive from current pathname
35
+ const group = groupPath || pathname
36
+
37
+ if (!group) return
38
+
39
+ // Normalize the group path
40
+ const normalizedGroup = group.endsWith('/') ? group.slice(0, -1) : group
41
+
42
+ return registerScrollGroup(normalizedGroup)
43
+ }, [groupPath, pathname])
44
+ }