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
@@ -5,7 +5,9 @@
5
5
  * Please refrain from making changes to this file, as it will make merging updates from the upstream harder.
6
6
  * All modifications except formatting should be marked with `// @modified` comment.
7
7
  *
8
- * No modifications currently, copied only in order to use a custom `useLinking` function.
8
+ * Modifications:
9
+ * - Added displayPath field to HistoryRecord for route masking support
10
+ * - Modified push() and replace() to accept displayPath parameter for showing masked URLs in browser
9
11
  */
10
12
 
11
13
  import type { NavigationState } from '@react-navigation/core'
@@ -16,8 +18,10 @@ type HistoryRecord = {
16
18
  id: string
17
19
  // Navigation state object for the history entry
18
20
  state: NavigationState
19
- // Path of the history entry
21
+ // Path of the history entry (actual navigation path)
20
22
  path: string
23
+ // @modified - Display path for route masking (URL shown in browser)
24
+ displayPath?: string
21
25
  }
22
26
 
23
27
  export function createMemoryHistory() {
@@ -70,7 +74,16 @@ export function createMemoryHistory() {
70
74
  return -1
71
75
  },
72
76
 
73
- push({ path, state }: { path: string; state: NavigationState }) {
77
+ // @modified - added displayPath parameter for route masking
78
+ push({
79
+ path,
80
+ state,
81
+ displayPath,
82
+ }: {
83
+ path: string
84
+ state: NavigationState
85
+ displayPath?: string
86
+ }) {
74
87
  interrupt()
75
88
 
76
89
  const id = nanoid()
@@ -79,21 +92,35 @@ export function createMemoryHistory() {
79
92
  // So we remove any existing entries after the current index to clean them up
80
93
  items = items.slice(0, index + 1)
81
94
 
82
- items.push({ path, state, id })
95
+ items.push({ path, state, id, displayPath })
83
96
  index = items.length - 1
84
97
 
98
+ // @modified - use displayPath for browser URL if provided (route masking)
99
+ const urlPath = displayPath ?? path
100
+
85
101
  if (process.env.ONE_DEBUG_ROUTER) {
86
- console.info(`[one] 📜 history.push path=${path}`)
102
+ console.info(
103
+ `[one] 📜 history.push path=${path}${displayPath ? ` displayPath=${displayPath}` : ''}`
104
+ )
87
105
  }
88
106
 
89
107
  // We pass empty string for title because it's ignored in all browsers except safari
90
108
  // We don't store state object in history.state because:
91
109
  // - browsers have limits on how big it can be, and we don't control the size
92
110
  // - while not recommended, there could be non-serializable data in state
93
- window.history.pushState({ id }, '', path)
111
+ window.history.pushState({ id }, '', urlPath)
94
112
  },
95
113
 
96
- replace({ path, state }: { path: string; state: NavigationState }) {
114
+ // @modified - added displayPath parameter for route masking
115
+ replace({
116
+ path,
117
+ state,
118
+ displayPath,
119
+ }: {
120
+ path: string
121
+ state: NavigationState
122
+ displayPath?: string
123
+ }) {
97
124
  interrupt()
98
125
 
99
126
  const id = window.history.state?.id ?? nanoid()
@@ -112,20 +139,25 @@ export function createMemoryHistory() {
112
139
  // So we need to push the entry as there's nothing to replace
113
140
 
114
141
  pathWithHash = pathWithHash + hash
115
- items = [{ path: pathWithHash, state, id }]
142
+ items = [{ path: pathWithHash, state, id, displayPath }]
116
143
  index = 0
117
144
  } else {
118
145
  if (items[index].path === path) {
119
146
  pathWithHash = pathWithHash + hash
120
147
  }
121
- items[index] = { path, state, id }
148
+ items[index] = { path, state, id, displayPath }
122
149
  }
123
150
 
151
+ // @modified - use displayPath for browser URL if provided (route masking)
152
+ const urlPath = displayPath ? displayPath + hash : pathWithHash
153
+
124
154
  if (process.env.ONE_DEBUG_ROUTER) {
125
- console.info(`[one] 📜 history.replace path=${pathWithHash}`)
155
+ console.info(
156
+ `[one] 📜 history.replace path=${pathWithHash}${displayPath ? ` displayPath=${displayPath}` : ''}`
157
+ )
126
158
  }
127
159
 
128
- window.history.replaceState({ id }, '', pathWithHash)
160
+ window.history.replaceState({ id }, '', urlPath)
129
161
  },
130
162
 
131
163
  // `history.go(n)` is asynchronous, there are couple of things to keep in mind:
@@ -23,6 +23,7 @@ import * as React from 'react'
23
23
  // @modified - start
24
24
  // import { ServerContext } from '@react-navigation/web';
25
25
  import { rootState as routerRootState } from '../router/router'
26
+ import { stripGroupSegmentsFromPath } from '../router/matchers'
26
27
  import { ServerLocationContext } from '../router/serverLocationContext'
27
28
  import { createMemoryHistory } from './createMemoryHistory'
28
29
  import { appendBaseUrl } from './getPathFromState-mods'
@@ -254,7 +255,9 @@ export function useLinking(
254
255
  // Otherwise, we'll handle it like a regular deep link
255
256
  const record = history.get(index)
256
257
 
257
- if (record?.path === path && record?.state) {
258
+ // @modified - check both actual path and display path for route masking support
259
+ const pathMatches = record?.path === path || record?.displayPath === path
260
+ if (pathMatches && record?.state) {
258
261
  if (process.env.ONE_DEBUG_ROUTER) {
259
262
  console.info(`[one] 📜 history record found, resetRoot to:`, record.state)
260
263
  }
@@ -461,6 +464,12 @@ export function useLinking(
461
464
  const route = findFocusedRoute(state)
462
465
  const path = getPathForRoute(route, state)
463
466
 
467
+ // @modified - extract mask from linkOptions for route masking
468
+ const maskHref = (state as any).linkOptions?.mask?.href
469
+ const displayPath = maskHref
470
+ ? appendBaseUrl(stripGroupSegmentsFromPath(maskHref) || '/')
471
+ : undefined
472
+
464
473
  previousStateRef.current = refState
465
474
  pendingPopStatePathRef.current = undefined
466
475
 
@@ -488,7 +497,7 @@ export function useLinking(
488
497
  if (historyDelta > 0) {
489
498
  // If history length is increased, we should pushState
490
499
  // Note that path might not actually change here, for example, drawer open should pushState
491
- history.push({ path, state })
500
+ history.push({ path, state, displayPath })
492
501
  } else if (historyDelta < 0) {
493
502
  // If history length is decreased, i.e. entries were removed, we want to go back
494
503
 
@@ -512,18 +521,19 @@ export function useLinking(
512
521
  }
513
522
 
514
523
  // Store the updated state as well as fix the path if incorrect
524
+ // Don't apply mask when going back - use the actual path
515
525
  history.replace({ path, state })
516
526
  } catch (e) {
517
527
  // The navigation was interrupted
518
528
  }
519
529
  } else {
520
530
  // If history length is unchanged, we want to replaceState
521
- history.replace({ path, state })
531
+ history.replace({ path, state, displayPath })
522
532
  }
523
533
  } else {
524
534
  // If no common navigation state was found, assume it's a replace
525
535
  // This would happen if the user did a reset/conditionally changed navigators
526
- history.replace({ path, state })
536
+ history.replace({ path, state, displayPath })
527
537
  }
528
538
  }
529
539
 
package/src/index.ts CHANGED
@@ -71,6 +71,7 @@ export { href } from './href'
71
71
  // components
72
72
  export { Stack } from './layouts/Stack'
73
73
  export { Tabs } from './layouts/Tabs'
74
+ export { Protected, type ProtectedProps } from './views/Protected'
74
75
  // utilities
75
76
  export { withLayoutContext } from './layouts/withLayoutContext'
76
77
  export { Link } from './link/Link'
@@ -86,9 +87,37 @@ export * as routerStore from './router/router'
86
87
  export { useNavigation } from './router/useNavigation'
87
88
  export { registerPreloadedRoute } from './router/useViteRoutes'
88
89
  export type { Endpoint, LoaderProps } from './types'
90
+ // navigation blocking
91
+ export {
92
+ useBlocker,
93
+ type Blocker,
94
+ type BlockerFunction,
95
+ type BlockerState,
96
+ } from './useBlocker'
97
+ // route param validation
98
+ export {
99
+ validateParams,
100
+ zodParamValidator,
101
+ ParamValidationError,
102
+ RouteValidationError,
103
+ type ParamValidator,
104
+ type InferParamInput,
105
+ type InferParamOutput,
106
+ type ValidateRouteProps,
107
+ type ValidationResult,
108
+ type RouteValidationFn,
109
+ } from './validateParams'
110
+ // validation state hook
111
+ export { useValidationState, type ValidationState } from './router/router'
89
112
  // React Navigation
90
113
  export { useFocusEffect } from './useFocusEffect'
91
- export { refetchLoader, useLoader, useLoaderState } from './useLoader'
114
+ export {
115
+ getLoaderTimingHistory,
116
+ refetchLoader,
117
+ useLoader,
118
+ useLoaderState,
119
+ type LoaderTimingEntry,
120
+ } from './useLoader'
92
121
  export {
93
122
  type ServerHeadInsertionCallback,
94
123
  useServerHeadInsertion,
@@ -97,8 +126,12 @@ export { isResponse } from './utils/isResponse'
97
126
  export { redirect } from './utils/redirect'
98
127
  export { watchFile } from './utils/watchFile'
99
128
  export { ErrorBoundary } from './views/ErrorBoundary'
129
+ export type { ErrorBoundaryProps, ErrorRouteInfo } from './views/Try'
100
130
  export { LoadProgressBar } from './views/LoadProgressBar'
101
131
  export { Navigator, Slot } from './views/Navigator'
102
132
  export { ScrollBehavior } from './views/ScrollBehavior'
133
+ export { SourceInspector, type SourceInspectorProps } from './views/SourceInspector'
134
+ // scroll position groups
135
+ export { useScrollGroup } from './useScrollGroup'
103
136
  // server
104
137
  export { getServerData, setResponseHeaders, setServerData } from './vite/one-server-only'
@@ -65,6 +65,41 @@ export namespace OneRouter {
65
65
 
66
66
  export type LinkToOptions = {
67
67
  scroll?: boolean
68
+ /**
69
+ * Display a different URL in the browser than the actual route.
70
+ * Useful for modals and overlays that should show a clean URL.
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * // Navigate to /photos/5/modal but show /photos/5 in browser
75
+ * router.navigate('/photos/5/modal', {
76
+ * mask: { href: '/photos/5' }
77
+ * })
78
+ * ```
79
+ */
80
+ mask?: {
81
+ /** The URL to display in the browser address bar */
82
+ href: Href
83
+ /**
84
+ * If true, unmask on page reload (show the masked URL in browser).
85
+ * If false (default), keep masking (navigate to actual route on reload).
86
+ */
87
+ unmaskOnReload?: boolean
88
+ }
89
+ /**
90
+ * Specify a scroll group for this navigation.
91
+ * Routes within the same scroll group will preserve scroll position
92
+ * when navigating between them.
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * // Use scroll group to preserve scroll when switching tabs
97
+ * router.navigate('/dashboard/settings', {
98
+ * scrollGroup: '/dashboard'
99
+ * })
100
+ * ```
101
+ */
102
+ scrollGroup?: string
68
103
  }
69
104
 
70
105
  type SearchOrHash = `?${string}` | `#${string}`
@@ -359,6 +394,19 @@ export namespace OneRouter {
359
394
  /** On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind. */
360
395
  className?: string
361
396
 
397
+ /**
398
+ * Display a different URL in the browser than the actual route.
399
+ * Useful for modals and overlays that should show a clean URL.
400
+ *
401
+ * @example
402
+ * ```tsx
403
+ * <Link href="/photos/5/modal" mask="/photos/5">
404
+ * View Photo
405
+ * </Link>
406
+ * ```
407
+ */
408
+ mask?: Href<T>
409
+
362
410
  onPress?: (
363
411
  e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
364
412
  ) => void
@@ -1,9 +1,11 @@
1
1
  import type { EventMapBase, NavigationState } from '@react-navigation/native'
2
2
  import React from 'react'
3
3
  import { useContextKey } from '../router/Route'
4
+ import { registerProtectedRoutes, unregisterProtectedRoutes } from '../router/router'
4
5
  import { type ScreenProps, useSortedScreens } from '../router/useScreens'
5
6
  import type { PickPartial } from '../types'
6
7
  import { withStaticProperties } from '../utils/withStaticProperties'
8
+ import { isProtectedElement } from '../views/Protected'
7
9
  import { Screen } from '../views/Screen'
8
10
 
9
11
  export function useFilterScreenChildren(
@@ -19,9 +21,16 @@ export function useFilterScreenChildren(
19
21
  ) {
20
22
  return React.useMemo(() => {
21
23
  const customChildren: any[] = []
24
+ const screens: any[] = []
25
+ const protectedScreens = new Set<string>()
22
26
 
23
- const screens = React.Children.map(children, (child) => {
24
- if (React.isValidElement(child) && child && child.type === Screen) {
27
+ /**
28
+ * Recursively process children, handling Protected elements.
29
+ * When exclude is true, all Screen children are added to protectedScreens instead of screens.
30
+ */
31
+ function flattenChild(child: React.ReactNode, exclude = false) {
32
+ // Handle Screen elements
33
+ if (React.isValidElement(child) && child.type === Screen) {
25
34
  if (
26
35
  typeof child.props === 'object' &&
27
36
  child.props &&
@@ -44,24 +53,42 @@ export function useFilterScreenChildren(
44
53
  )
45
54
  }
46
55
  }
47
- return child.props as ScreenProps
56
+
57
+ const screenProps = child.props as ScreenProps
58
+ if (exclude && screenProps.name) {
59
+ protectedScreens.add(screenProps.name)
60
+ } else {
61
+ screens.push(screenProps)
62
+ }
63
+ return
64
+ }
65
+
66
+ // Handle Protected elements - recursively process children with guard logic
67
+ if (isProtectedElement(child)) {
68
+ // Key logic: exclude if parent excluded OR guard is false
69
+ const excludeChildren = exclude || !child.props.guard
70
+ React.Children.forEach(child.props.children, (nested) => {
71
+ flattenChild(nested, excludeChildren)
72
+ })
73
+ return
48
74
  }
49
75
 
76
+ // Handle other children (custom components in custom Navigator)
50
77
  if (isCustomNavigator) {
51
78
  customChildren.push(child)
52
- } else {
79
+ } else if (child != null) {
53
80
  console.warn(
54
81
  `Layout children must be of type Screen, all other children are ignored. To use custom children, create a custom <Layout />. Update Layout Route at: "app${contextKey}/_layout"`
55
82
  )
56
83
  }
84
+ }
57
85
 
58
- return null
59
- })?.filter(Boolean)
86
+ React.Children.forEach(children, (child) => flattenChild(child))
60
87
 
61
88
  // Add an assertion for development
62
89
  if (process.env.NODE_ENV !== 'production') {
63
90
  // Assert if names are not unique
64
- const names = screens?.map((screen) => screen.name)
91
+ const names = screens.map((screen) => screen.name)
65
92
  if (names && new Set(names).size !== names.length) {
66
93
  throw new Error('Screen names must be unique: ' + names)
67
94
  }
@@ -70,6 +97,7 @@ export function useFilterScreenChildren(
70
97
  return {
71
98
  screens,
72
99
  children: customChildren,
100
+ protectedScreens,
73
101
  }
74
102
  }, [children, contextKey, isCustomNavigator])
75
103
  }
@@ -92,13 +120,25 @@ export function withLayoutContext<
92
120
  (propsIn, ref) => {
93
121
  const { children, ...props } = propsIn as React.ComponentProps<T>
94
122
  const contextKey = useContextKey()
95
- const { screens } = useFilterScreenChildren(children, {
123
+ const { screens, protectedScreens } = useFilterScreenChildren(children, {
96
124
  contextKey,
97
125
  })
98
126
 
127
+ // Register protected routes globally so linkTo can block navigation to them
128
+ // Register immediately (not just in effect) to catch navigation attempts during first render
129
+ registerProtectedRoutes(contextKey, protectedScreens)
130
+
131
+ React.useEffect(() => {
132
+ registerProtectedRoutes(contextKey, protectedScreens)
133
+ return () => {
134
+ unregisterProtectedRoutes(contextKey)
135
+ }
136
+ }, [contextKey, protectedScreens])
137
+
99
138
  const processed = processor ? processor(screens ?? ([] as any)) : screens
100
139
  const sorted = useSortedScreens((processed ?? []) as any, {
101
140
  onlyMatching: true,
141
+ protectedScreens,
102
142
  })
103
143
 
104
144
  // Prevent throwing an error when there are no screens.
package/src/link/Link.tsx CHANGED
@@ -25,6 +25,7 @@ export const Link = React.forwardRef(function Link(
25
25
  replace,
26
26
  push,
27
27
  id,
28
+ mask,
28
29
  // TODO: This does not prevent default on the anchor tag.
29
30
  asChild,
30
31
  rel,
@@ -47,7 +48,11 @@ export const Link = React.forwardRef(function Link(
47
48
  return resolveHref(href)
48
49
  }, [href])
49
50
 
50
- const props = useLinkTo({ href: resolvedHref, replace })
51
+ const resolvedMask = React.useMemo(() => {
52
+ return mask ? resolveHref(mask) : undefined
53
+ }, [mask])
54
+
55
+ const props = useLinkTo({ href: resolvedHref, replace, mask: resolvedMask })
51
56
 
52
57
  const onPress = (
53
58
  e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
@@ -67,7 +72,7 @@ export const Link = React.forwardRef(function Link(
67
72
  {...props}
68
73
  {...hrefAttrs}
69
74
  {...rest}
70
- nativeID={id}
75
+ {...(process.env.TAMAGUI_TARGET === 'web' ? { id } : { nativeID: id })}
71
76
  style={asChild ? null : style}
72
77
  {...Platform.select({
73
78
  web: {
@@ -29,7 +29,7 @@ function eventShouldPreventDefault(
29
29
  return false
30
30
  }
31
31
 
32
- export function useLinkTo(props: { href: string; replace?: boolean }) {
32
+ export function useLinkTo(props: { href: string; replace?: boolean; mask?: string }) {
33
33
  const { linkTo } = useOneRouter()
34
34
 
35
35
  const onPress = (
@@ -46,13 +46,17 @@ export function useLinkTo(props: { href: string; replace?: boolean }) {
46
46
  }
47
47
 
48
48
  if (shouldHandle) {
49
- linkTo(props.href, event)
49
+ const options = props.mask ? { mask: { href: props.mask } } : undefined
50
+ linkTo(props.href, event, options)
50
51
  }
51
52
  }
52
53
 
54
+ // For the displayed href, use the mask if provided (shows clean URL in status bar on hover)
55
+ const displayHref = props.mask || props.href
56
+
53
57
  return {
54
58
  // Ensure there's always a value for href. Manually append the baseUrl to the href prop that shows in the static HTML.
55
- href: appendBaseUrl(stripGroupSegmentsFromPath(props.href) || '/'),
59
+ href: appendBaseUrl(stripGroupSegmentsFromPath(displayHref) || '/'),
56
60
  role: 'link' as const,
57
61
  onPress,
58
62
  }
@@ -1,6 +1,8 @@
1
1
  import React, { createContext, type ReactNode, useContext } from 'react'
2
2
  import type { ErrorBoundaryProps } from '../views/Try'
3
+ import type { LoaderProps } from '../types'
3
4
  import type { One } from '../vite/types'
5
+ import type { ParamValidator, RouteValidationFn } from '../validateParams'
4
6
  import { getContextKey } from './matchers'
5
7
  import { RouteInfoContextProvider } from './RouteInfoContext'
6
8
 
@@ -18,9 +20,36 @@ export type LoadedRoute = {
18
20
  generateStaticParams?: (props: {
19
21
  params?: Record<string, string | string[]>
20
22
  }) => Record<string, string | string[]>[]
21
- loader?: (props: {
22
- params?: Record<string, string | string[]>
23
- }) => Record<string, string | string[]>[]
23
+ loader?: (props: LoaderProps) => Record<string, string | string[]>[]
24
+ /**
25
+ * Validate route params before navigation.
26
+ * Use with Zod, Valibot, or a custom function.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { z } from 'zod'
31
+ * export const validateParams = z.object({
32
+ * id: z.string().uuid()
33
+ * })
34
+ * ```
35
+ */
36
+ validateParams?: ParamValidator
37
+ /**
38
+ * Async route validation function.
39
+ * Runs before navigation to validate the route is accessible.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * export async function validateRoute({ params }) {
44
+ * const exists = await checkResourceExists(params.id)
45
+ * if (!exists) {
46
+ * return { valid: false, error: 'Resource not found' }
47
+ * }
48
+ * return { valid: true }
49
+ * }
50
+ * ```
51
+ */
52
+ validateRoute?: RouteValidationFn
24
53
  }
25
54
 
26
55
  export type RouteNode = {
@@ -0,0 +1,127 @@
1
+ import type { RouteNode } from './Route'
2
+
3
+ /**
4
+ * Find a RouteNode from the route tree based on the navigation state.
5
+ * Walks through the state's routes recursively to find the deepest matching route.
6
+ */
7
+ export function findRouteNodeFromState(
8
+ state: { routes: Array<{ name: string; state?: any }> } | undefined,
9
+ rootNode: RouteNode | null
10
+ ): RouteNode | null {
11
+ if (!state || !rootNode) {
12
+ return null
13
+ }
14
+
15
+ // Get the current route from state (the active one based on index)
16
+ const currentRoute = state.routes[state.routes.length - 1]
17
+ if (!currentRoute) {
18
+ return null
19
+ }
20
+
21
+ // Find the matching child node
22
+ const matchingNode = findNodeByRouteName(rootNode, currentRoute.name)
23
+ if (!matchingNode) {
24
+ return null
25
+ }
26
+
27
+ // If there's a nested state, continue recursively
28
+ if (currentRoute.state && currentRoute.state.routes) {
29
+ const nestedResult = findRouteNodeFromState(currentRoute.state, matchingNode)
30
+ if (nestedResult) {
31
+ return nestedResult
32
+ }
33
+ }
34
+
35
+ return matchingNode
36
+ }
37
+
38
+ /**
39
+ * Find a node by its route name in the tree.
40
+ * Searches children recursively.
41
+ */
42
+ function findNodeByRouteName(node: RouteNode, routeName: string): RouteNode | null {
43
+ // Check if this node matches
44
+ if (node.route === routeName) {
45
+ return node
46
+ }
47
+
48
+ // Search children
49
+ for (const child of node.children) {
50
+ const found = findNodeByRouteName(child, routeName)
51
+ if (found) {
52
+ return found
53
+ }
54
+ }
55
+
56
+ return null
57
+ }
58
+
59
+ /**
60
+ * Extract params from navigation state.
61
+ * Collects params from all routes in the state hierarchy.
62
+ */
63
+ export function extractParamsFromState(
64
+ state:
65
+ | { routes: Array<{ name: string; params?: Record<string, any>; state?: any }> }
66
+ | undefined
67
+ ): Record<string, string | string[]> {
68
+ if (!state) {
69
+ return {}
70
+ }
71
+
72
+ const params: Record<string, string | string[]> = {}
73
+
74
+ // Collect params from all routes in the state
75
+ for (const route of state.routes) {
76
+ if (route.params) {
77
+ Object.assign(params, route.params)
78
+ }
79
+ // Recurse into nested state
80
+ if (route.state) {
81
+ Object.assign(params, extractParamsFromState(route.state))
82
+ }
83
+ }
84
+
85
+ return params
86
+ }
87
+
88
+ /**
89
+ * Extract search params from href string.
90
+ */
91
+ export function extractSearchFromHref(href: string): Record<string, string | string[]> {
92
+ const searchIndex = href.indexOf('?')
93
+ if (searchIndex === -1) {
94
+ return {}
95
+ }
96
+
97
+ const searchString = href.slice(searchIndex + 1)
98
+ const params: Record<string, string | string[]> = {}
99
+ const searchParams = new URLSearchParams(searchString)
100
+
101
+ searchParams.forEach((value, key) => {
102
+ const existing = params[key]
103
+ if (existing === undefined) {
104
+ params[key] = value
105
+ } else if (Array.isArray(existing)) {
106
+ existing.push(value)
107
+ } else {
108
+ params[key] = [existing, value]
109
+ }
110
+ })
111
+
112
+ return params
113
+ }
114
+
115
+ /**
116
+ * Extract pathname from href string.
117
+ */
118
+ export function extractPathnameFromHref(href: string): string {
119
+ const searchIndex = href.indexOf('?')
120
+ const hashIndex = href.indexOf('#')
121
+
122
+ let endIndex = href.length
123
+ if (searchIndex !== -1) endIndex = Math.min(endIndex, searchIndex)
124
+ if (hashIndex !== -1) endIndex = Math.min(endIndex, hashIndex)
125
+
126
+ return href.slice(0, endIndex)
127
+ }