one 1.26.0 → 1.26.1

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 (114) hide show
  1. package/dist/cjs/router/getNormalizedStatePath.cjs +2 -1
  2. package/dist/cjs/router/getNormalizedStatePath.native.js +2 -1
  3. package/dist/cjs/router/getNormalizedStatePath.native.js.map +1 -1
  4. package/dist/cjs/router/getRouteInfo.cjs +6 -2
  5. package/dist/cjs/router/getRouteInfo.native.js +6 -2
  6. package/dist/cjs/router/getRouteInfo.native.js.map +1 -1
  7. package/dist/cjs/router/getRouteInfo.test.cjs +35 -0
  8. package/dist/cjs/router/getRouteInfo.test.native.js +42 -0
  9. package/dist/cjs/router/getRouteInfo.test.native.js.map +1 -0
  10. package/dist/cjs/router/path.cjs +1 -0
  11. package/dist/cjs/router/path.native.js +1 -0
  12. package/dist/cjs/router/path.native.js.map +1 -1
  13. package/dist/cjs/router/routeHmr.native.js +2 -5
  14. package/dist/cjs/router/routeHmr.native.js.map +1 -1
  15. package/dist/cjs/router/routeHmr.native.test.cjs +23 -9
  16. package/dist/cjs/router/routeHmr.native.test.native.js +27 -9
  17. package/dist/cjs/router/routeHmr.native.test.native.js.map +1 -1
  18. package/dist/cjs/router/useScreens.cjs +15 -19
  19. package/dist/cjs/router/useScreens.native.js +15 -19
  20. package/dist/cjs/router/useScreens.native.js.map +1 -1
  21. package/dist/cjs/router/useScreens.test.cjs +78 -0
  22. package/dist/cjs/router/useScreens.test.native.js +88 -1
  23. package/dist/cjs/router/useScreens.test.native.js.map +1 -1
  24. package/dist/cjs/router/useViteRoutes.cjs +3 -2
  25. package/dist/cjs/router/useViteRoutes.native.js +3 -2
  26. package/dist/cjs/router/useViteRoutes.native.js.map +1 -1
  27. package/dist/cjs/useFocusEffect.cjs +7 -1
  28. package/dist/cjs/useFocusEffect.native.js +9 -4
  29. package/dist/cjs/useFocusEffect.native.js.map +1 -1
  30. package/dist/cjs/vite/one.native.js.map +1 -1
  31. package/dist/cjs/vite/plugins/sourceInspectorPlugin.cjs +7 -1
  32. package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js +7 -1
  33. package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
  34. package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.cjs +15 -0
  35. package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js +16 -0
  36. package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -1
  37. package/dist/esm/router/getNormalizedStatePath.mjs +2 -1
  38. package/dist/esm/router/getNormalizedStatePath.mjs.map +1 -1
  39. package/dist/esm/router/getNormalizedStatePath.native.js +2 -1
  40. package/dist/esm/router/getNormalizedStatePath.native.js.map +1 -1
  41. package/dist/esm/router/getRouteInfo.mjs +5 -2
  42. package/dist/esm/router/getRouteInfo.mjs.map +1 -1
  43. package/dist/esm/router/getRouteInfo.native.js +5 -2
  44. package/dist/esm/router/getRouteInfo.native.js.map +1 -1
  45. package/dist/esm/router/getRouteInfo.test.mjs +36 -0
  46. package/dist/esm/router/getRouteInfo.test.mjs.map +1 -0
  47. package/dist/esm/router/getRouteInfo.test.native.js +40 -0
  48. package/dist/esm/router/getRouteInfo.test.native.js.map +1 -0
  49. package/dist/esm/router/path.mjs +1 -1
  50. package/dist/esm/router/path.mjs.map +1 -1
  51. package/dist/esm/router/path.native.js +1 -1
  52. package/dist/esm/router/path.native.js.map +1 -1
  53. package/dist/esm/router/routeHmr.native.js +2 -5
  54. package/dist/esm/router/routeHmr.native.js.map +1 -1
  55. package/dist/esm/router/routeHmr.native.test.js +21 -11
  56. package/dist/esm/router/routeHmr.native.test.js.map +1 -1
  57. package/dist/esm/router/routeHmr.native.test.mjs +23 -9
  58. package/dist/esm/router/routeHmr.native.test.mjs.map +1 -1
  59. package/dist/esm/router/routeHmr.native.test.native.js +27 -9
  60. package/dist/esm/router/routeHmr.native.test.native.js.map +1 -1
  61. package/dist/esm/router/useScreens.mjs +15 -18
  62. package/dist/esm/router/useScreens.mjs.map +1 -1
  63. package/dist/esm/router/useScreens.native.js +15 -18
  64. package/dist/esm/router/useScreens.native.js.map +1 -1
  65. package/dist/esm/router/useScreens.test.mjs +76 -0
  66. package/dist/esm/router/useScreens.test.mjs.map +1 -1
  67. package/dist/esm/router/useScreens.test.native.js +86 -0
  68. package/dist/esm/router/useScreens.test.native.js.map +1 -1
  69. package/dist/esm/router/useViteRoutes.mjs +3 -2
  70. package/dist/esm/router/useViteRoutes.mjs.map +1 -1
  71. package/dist/esm/router/useViteRoutes.native.js +3 -2
  72. package/dist/esm/router/useViteRoutes.native.js.map +1 -1
  73. package/dist/esm/useFocusEffect.mjs +8 -2
  74. package/dist/esm/useFocusEffect.mjs.map +1 -1
  75. package/dist/esm/useFocusEffect.native.js +10 -5
  76. package/dist/esm/useFocusEffect.native.js.map +1 -1
  77. package/dist/esm/vite/one.mjs.map +1 -1
  78. package/dist/esm/vite/one.native.js.map +1 -1
  79. package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs +7 -2
  80. package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs.map +1 -1
  81. package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js +7 -2
  82. package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
  83. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.mjs +16 -1
  84. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.mjs.map +1 -1
  85. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.native.js +17 -1
  86. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -1
  87. package/package.json +11 -11
  88. package/src/router/getNormalizedStatePath.tsx +2 -1
  89. package/src/router/getRouteInfo.test.ts +33 -0
  90. package/src/router/getRouteInfo.ts +5 -2
  91. package/src/router/path.ts +1 -1
  92. package/src/router/routeHmr.native.test.ts +23 -11
  93. package/src/router/routeHmr.native.ts +6 -4
  94. package/src/router/useScreens.test.tsx +72 -0
  95. package/src/router/useScreens.tsx +11 -19
  96. package/src/router/useViteRoutes.tsx +3 -2
  97. package/src/useFocusEffect.ts +14 -4
  98. package/src/vite/one.ts +3 -1
  99. package/src/vite/plugins/sourceInspectorPlugin.test.ts +37 -1
  100. package/src/vite/plugins/sourceInspectorPlugin.ts +24 -3
  101. package/types/router/getNormalizedStatePath.d.ts.map +1 -1
  102. package/types/router/getRouteInfo.d.ts +5 -0
  103. package/types/router/getRouteInfo.d.ts.map +1 -1
  104. package/types/router/getRouteInfo.test.d.ts +2 -0
  105. package/types/router/getRouteInfo.test.d.ts.map +1 -0
  106. package/types/router/path.d.ts +1 -0
  107. package/types/router/path.d.ts.map +1 -1
  108. package/types/router/routeHmr.native.d.ts.map +1 -1
  109. package/types/router/useScreens.d.ts.map +1 -1
  110. package/types/router/useViteRoutes.d.ts.map +1 -1
  111. package/types/useFocusEffect.d.ts.map +1 -1
  112. package/types/vite/one.d.ts.map +1 -1
  113. package/types/vite/plugins/sourceInspectorPlugin.d.ts +9 -0
  114. package/types/vite/plugins/sourceInspectorPlugin.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":["describe","expect","it","getSourceInspectorPath","resolveEditorFilePath","toBe","fileExists","filePath"],"sources":["../../../../src/vite/plugins/sourceInspectorPlugin.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,MAAA,EAAQC,EAAA,QAAU;AAErC,SAASC,sBAAA,EAAwBC,qBAAA,QAA6B;AAE9DJ,QAAA,CAAS,iCAAiC,MAAM;EAC9CA,QAAA,CAAS,0BAA0B,MAAM;IACvCE,EAAA,CAAG,mDAAmD,MAAM;MAC1DD,MAAA,CAAOE,sBAAA,CAAuB,kCAAkC,OAAO,CAAC,EAAEE,IAAA,CACxE,2BACF;IACF,CAAC;IAEDH,EAAA,CAAG,gEAAgE,MAAM;MACvED,MAAA,CACEE,sBAAA,CAAuB,wCAAwC,OAAO,CACxE,EAAEE,IAAA,CAAK,sCAAsC;IAC/C,CAAC;EACH,CAAC;EAEDL,QAAA,CAAS,yBAAyB,MAAM;IACtCE,EAAA,CAAG,sDAAsD,MAAM;MAC7D,MAAMI,UAAA,GAAcC,QAAA,IAClBA,QAAA,KAAa;MAEfN,MAAA,CACEG,qBAAA,CAAsB,6BAA6B,SAASE,UAAU,CACxE,EAAED,IAAA,CAAK,gCAAgC;IACzC,CAAC;IAEDH,EAAA,CAAG,yDAAyD,MAAM;MAChED,MAAA,CACEG,qBAAA,CACE,kCACA,mBACA,MAAM,KACR,CACF,EAAEC,IAAA,CAAK,gCAAgC;IACzC,CAAC;EACH,CAAC;AACH,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["describe","expect","it","getSourceInspectorPath","injectSourceToJsx","resolveEditorFilePath","toBe","fileExists","filePath","out","join","process","cwd","code","toContain","not","toMatch"],"sources":["../../../../src/vite/plugins/sourceInspectorPlugin.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,MAAA,EAAQC,EAAA,QAAU;AAErC,SACEC,sBAAA,EACAC,iBAAA,EACAC,qBAAA,QACK;AAEPL,QAAA,CAAS,iCAAiC,MAAM;EAC9CA,QAAA,CAAS,0BAA0B,MAAM;IACvCE,EAAA,CAAG,mDAAmD,MAAM;MAC1DD,MAAA,CAAOE,sBAAA,CAAuB,kCAAkC,OAAO,CAAC,EAAEG,IAAA,CACxE,2BACF;IACF,CAAC;IAEDJ,EAAA,CAAG,gEAAgE,MAAM;MACvED,MAAA,CACEE,sBAAA,CAAuB,wCAAwC,OAAO,CACxE,EAAEG,IAAA,CAAK,sCAAsC;IAC/C,CAAC;EACH,CAAC;EAEDN,QAAA,CAAS,yBAAyB,MAAM;IACtCE,EAAA,CAAG,sDAAsD,MAAM;MAC7D,MAAMK,UAAA,GAAcC,QAAA,IAClBA,QAAA,KAAa;MAEfP,MAAA,CACEI,qBAAA,CAAsB,6BAA6B,SAASE,UAAU,CACxE,EAAED,IAAA,CAAK,gCAAgC;IACzC,CAAC;IAEDJ,EAAA,CAAG,yDAAyD,MAAM;MAChED,MAAA,CACEI,qBAAA,CACE,kCACA,mBACA,MAAM,KACR,CACF,EAAEC,IAAA,CAAK,gCAAgC;IACzC,CAAC;EACH,CAAC;EAEDN,QAAA,CAAS,qBAAqB,MAAM;IAClCE,EAAA,CAAG,4EAA4E,YAAY;MACzF,MAAMO,GAAA,GAAM,MAAML,iBAAA,CAChB,CACE,gCACA,WACA,gBACA,qCACA,2BACA,gDACA,iBACA,0DACA,iBACA,4CACA,YACA,IACF,CAAEM,IAAA,CAAK,IAAI,GACX,GAAGC,OAAA,CAAQC,GAAA,CAAI,CAAC,gBAClB;MACA,MAAMC,IAAA,GAAOJ,GAAA,EAAKI,IAAA,IAAQ;MAC1BZ,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,uBAAuB;MAC9Cb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,0BAA0B;MACjDb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,uBAAuB;MAC9Cb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,kCAAkC;MACzDb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,iBAAiB;MACxCb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,iBAAiB;MACxCb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,8BAA8B;MACrDb,MAAA,CAAOY,IAAI,EAAEC,SAAA,CAAU,sBAAsB;MAC7Cb,MAAA,CAAOY,IAAI,EAAEE,GAAA,CAAIC,OAAA,CAAQ,wEAAwE;IACnG,CAAC;EACH,CAAC;AACH,CAAC","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { getSourceInspectorPath, resolveEditorFilePath } from "./sourceInspectorPlugin.native.js";
2
+ import { getSourceInspectorPath, injectSourceToJsx, resolveEditorFilePath } from "./sourceInspectorPlugin.native.js";
3
3
  describe("sourceInspectorPlugin helpers", function () {
4
4
  describe("getSourceInspectorPath", function () {
5
5
  it("keeps project files relative to the current cwd", function () {
@@ -22,5 +22,21 @@ describe("sourceInspectorPlugin helpers", function () {
22
22
  })).toBe("/Users/n8/shared/ui/Button.tsx");
23
23
  });
24
24
  });
25
+ describe("injectSourceToJsx", function () {
26
+ it("tags dom elements and components but leaves custom reconciler tags alone", async function () {
27
+ var _ref;
28
+ var out = await injectSourceToJsx(["export const Scene = () => (", " <div>", " <Canvas>", " <mesh position={[0, 1, 0]}>", " <boxGeometry />", ' <meshStandardMaterial color="red" />', " </mesh>", " <instancedMesh args={[geometry, material, 4]} />", " </Canvas>", ' <svg><linearGradient id="g" /></svg>', " </div>", ")"].join("\n"), `${process.cwd()}/src/Scene.tsx`);
29
+ var code = (_ref = out === null || out === void 0 ? void 0 : out.code) !== null && _ref !== void 0 ? _ref : "";
30
+ expect(code).toContain("<div data-one-source=");
31
+ expect(code).toContain("<Canvas data-one-source=");
32
+ expect(code).toContain("<svg data-one-source=");
33
+ expect(code).toContain("<linearGradient data-one-source=");
34
+ expect(code).toContain("<mesh position=");
35
+ expect(code).toContain("<boxGeometry />");
36
+ expect(code).toContain("<meshStandardMaterial color=");
37
+ expect(code).toContain("<instancedMesh args=");
38
+ expect(code).not.toMatch(/<(mesh|boxGeometry|meshStandardMaterial|instancedMesh) data-one-source/);
39
+ });
40
+ });
25
41
  });
26
42
  //# sourceMappingURL=sourceInspectorPlugin.test.native.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["describe","expect","it","getSourceInspectorPath","resolveEditorFilePath","toBe","fileExists","filePath"],"sources":["../../../../src/vite/plugins/sourceInspectorPlugin.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,MAAA,EAAQC,EAAA,QAAU;AAErC,SAASC,sBAAA,EAAwBC,qBAAA,QAA6B;AAE9DJ,QAAA,CAAS,iCAAiC,YAAM;EAC9CA,QAAA,CAAS,0BAA0B,YAAM;IACvCE,EAAA,CAAG,mDAAmD,YAAM;MAC1DD,MAAA,CAAOE,sBAAA,CAAuB,kCAAkC,OAAO,CAAC,EAAEE,IAAA;IAAA;IACxEH,EACF;MACDD,MAAA,CAAAE,sBAAA,mDAAAE,IAAA;IAED;EACE;EAAAL,QACE,wBAAuB;IAA+CE,EACxE,qDAA6C;MAC9C,IAAAI,UAAA,YAAAA,CAAAC,QAAA;QACF,OAAAA,QAAA;MAED;MACEN,MAAG,CAAAG,qBAAA,4BAAsD,SAAM,EAAAE,UAAA,GAAAD,IAAA;IAC7D;IAGAH,EAAA;MAAAD,MACE,CAAAG,qBAAsB,iCAA6B,EAAS,iBAAU;QACtE,OAAK;MACR,IAAAC,IAAA;IAED;EACE;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["describe","expect","it","getSourceInspectorPath","injectSourceToJsx","resolveEditorFilePath","toBe","fileExists","filePath","_ref","out","join","process","cwd","code","toContain","not","toMatch"],"sources":["../../../../src/vite/plugins/sourceInspectorPlugin.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,MAAA,EAAQC,EAAA,QAAU;AAErC,SAAAC,sBAAA,EAAAC,iBAAA,EAAAC,qBAAA;AAAAL,QACE;EACAA,QAAA;IACAE,EAAA;MAAAD,MACK,CAAAE,sBAAA,6CAAAG,IAAA;IAEP;IACEJ,EAAA,+DAAyC;MACvCD,MAAG,CAAAE,sBAAA,uCAAyD,YAAAG,IAAA;IAC1D;EAA0E;EACxEN,QACF;IACFE,EAAC;MAED,IAAGK,UAAA,YAAAA,CAAAC,QAAA;QACD,OAAAA,QAAA;MAAA;MAEAP,MAAE,CAAKI,qBAAA,4BAAsC,WAAAE,UAAA,GAAAD,IAAA;IAC/C,CAAC;IACFJ,EAAA;MAEDD,MAAS,CAAAI,qBAAA,iCAA+B;QACnC;MACD,IAAAC,IAAM,iCACJ;IAEF;EAAA;EACwEN,QACtE,oBAAK;IACTE,EAAC;MAED,IAAGO,IAAA;MACD,IAAAC,GAAA,SAAAN,iBAAA,EACE,yCACE,gBACA,qCACM,EACR,2BACA,8CAAqC,EACxC,iBACF,0DAED,eAAS,EACJ,4CACD,UAAY,EACV,KAAAO,IACE,WAAAC,OAAA,CAAAC,GAAA;MAAA,IACAC,IAAA,IAAAL,IAAA,GAAAC,GAAA,aAAAA,GAAA,uBAAAA,GAAA,CAAAI,IAAA,cAAAL,IAAA,cAAAA,IAAA;MAAAR,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAC,SAAA;MAAAd,MACA,CAAAa,IAAA,EAAAE,GAAA,CAAAC,OAAA;IAAA;EACA;AACS","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one",
3
- "version": "1.26.0",
3
+ "version": "1.26.1",
4
4
  "license": "BSD-3-Clause",
5
5
  "sideEffects": [
6
6
  "setup.mjs",
@@ -197,18 +197,18 @@
197
197
  "@react-navigation/routers": "~7.6.4",
198
198
  "@cloudflare/vite-plugin": "^1.33.1",
199
199
  "@ungap/structured-clone": "^1.2.0",
200
- "@vxrn/color-scheme": "1.26.0",
201
- "@vxrn/compiler": "1.26.0",
202
- "@vxrn/resolve": "1.26.0",
203
- "@vxrn/tslib-lite": "1.26.0",
204
- "@vxrn/use-isomorphic-layout-effect": "1.26.0",
205
- "@vxrn/vite-plugin-metro": "1.26.0",
200
+ "@vxrn/color-scheme": "1.26.1",
201
+ "@vxrn/compiler": "1.26.1",
202
+ "@vxrn/resolve": "1.26.1",
203
+ "@vxrn/tslib-lite": "1.26.1",
204
+ "@vxrn/use-isomorphic-layout-effect": "1.26.1",
205
+ "@vxrn/vite-plugin-metro": "1.26.1",
206
206
  "babel-dead-code-elimination": "1.0.10",
207
207
  "babel-plugin-module-resolver": "^5.0.2",
208
208
  "babel-preset-expo": "~57.0.5",
209
209
  "citty": "^0.1.6",
210
210
  "core-js": "^3.38.1",
211
- "create-vxrn": "1.26.0",
211
+ "create-vxrn": "1.26.1",
212
212
  "escape-string-regexp": "^5.0.0",
213
213
  "expo-linking": "~57.0.5",
214
214
  "expo-modules-core": "~57.0.10",
@@ -229,7 +229,7 @@
229
229
  "tsconfig-paths": "^4",
230
230
  "use-latest-callback": "^0.2.3",
231
231
  "vite": "^8.2.2",
232
- "vxrn": "1.26.0",
232
+ "vxrn": "1.26.1",
233
233
  "web-streams-polyfill": "^4.3.0",
234
234
  "ws": "^8.21.0",
235
235
  "xxhashjs": "^0.2.2"
@@ -247,7 +247,7 @@
247
247
  "react-native-safe-area-context": ">=5.0.0",
248
248
  "react-native-screens": ">=4.0.0",
249
249
  "react-native-worklets": ">=0.7.0",
250
- "sharp": "^0.35.3"
250
+ "sharp": "^0.35.4"
251
251
  },
252
252
  "peerDependenciesMeta": {
253
253
  "@bottom-tabs/react-navigation": {
@@ -295,7 +295,7 @@
295
295
  "react-native": "0.86.2",
296
296
  "react-test-renderer": "^19.2.0",
297
297
  "rolldown": "^1.2.4",
298
- "sharp": "^0.35.3",
298
+ "sharp": "^0.35.4",
299
299
  "typescript": "^5.7.3",
300
300
  "vitest": "^4.1.0"
301
301
  },
@@ -1,4 +1,5 @@
1
1
  import { stripBaseUrl } from '../fork/getStateFromPath-mods'
2
+ import { stripPathSuffix } from './path'
2
3
 
3
4
  type SearchParams = Record<string, string | string[]>
4
5
 
@@ -21,7 +22,7 @@ export function getNormalizedStatePath(
21
22
  },
22
23
  baseUrl?: string
23
24
  ): Pick<UrlObject, 'segments' | 'params'> {
24
- const [pathname] = statePath.split('?')
25
+ const pathname = stripPathSuffix(statePath)
25
26
  return {
26
27
  // Strip empty path at the start
27
28
  segments: stripBaseUrl(pathname, baseUrl)
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { getRouteInfoFromState } from './getRouteInfo'
3
+
4
+ // a hash link (/dev#stack) keeps its hash in the serialized path; route info
5
+ // must still report the bare pathname or the router never sees the pending
6
+ // navigation land and serializes the stale state to history
7
+ describe('getRouteInfoFromState', () => {
8
+ const state = {
9
+ routes: [{ name: 'dev', path: '/dev#stack', params: { '#': 'stack' } }],
10
+ } as any
11
+
12
+ it('drops the hash from pathname and segments', () => {
13
+ const info = getRouteInfoFromState(
14
+ (_state, asPath) => ({
15
+ path: asPath ? '/(site)/dev#stack' : '/dev#stack',
16
+ params: { '#': 'stack' },
17
+ }),
18
+ state
19
+ )
20
+ expect(info.pathname).toBe('/dev')
21
+ expect(info.segments).toEqual(['(site)', 'dev'])
22
+ expect(info.unstable_globalHref).toBe('/dev#stack')
23
+ })
24
+
25
+ it('drops the query and the hash together', () => {
26
+ const info = getRouteInfoFromState(
27
+ () => ({ path: '/dev?x=1#stack', params: { x: '1', '#': 'stack' } }),
28
+ state
29
+ )
30
+ expect(info.pathname).toBe('/dev')
31
+ expect(info.segments).toEqual(['dev'])
32
+ })
33
+ })
@@ -5,6 +5,7 @@ import type { OneRouter } from '../interfaces/router'
5
5
  import { getNormalizedStatePath, type UrlObject } from './getNormalizedStatePath'
6
6
  import { isIndexPath } from './isIndexPath'
7
7
  import { getResolvedLinking } from './linkingConfig'
8
+ import { stripPathSuffix } from './path'
8
9
 
9
10
  export function getRouteInfo(state: OneRouter.ResultState) {
10
11
  return getRouteInfoFromState(
@@ -20,7 +21,7 @@ export function getRouteInfo(state: OneRouter.ResultState) {
20
21
  )
21
22
  }
22
23
 
23
- function getRouteInfoFromState(
24
+ export function getRouteInfoFromState(
24
25
  getPathFromState: (state: State, asPath: boolean) => { path: string; params: any },
25
26
  state: State,
26
27
  baseUrl?: string
@@ -30,7 +31,9 @@ function getRouteInfoFromState(
30
31
 
31
32
  return {
32
33
  unstable_globalHref: path,
33
- pathname: stripBaseUrl(path, baseUrl).split('?')[0],
34
+ // a hash href serializes as /page#section; the pathname the router compares
35
+ // against pending navigation and the URL must drop the hash as well as the query
36
+ pathname: stripPathSuffix(stripBaseUrl(path, baseUrl)),
34
37
  isIndex: isIndexPath(state),
35
38
  ...getNormalizedStatePath(qualified, baseUrl),
36
39
  }
@@ -1,6 +1,6 @@
1
1
  import { stripBaseUrl } from '../fork/getStateFromPath-mods'
2
2
 
3
- function stripPathSuffix(path: string): string {
3
+ export function stripPathSuffix(path: string): string {
4
4
  const queryIndex = path.indexOf('?')
5
5
  const hashIndex = path.indexOf('#')
6
6
  let end = path.length
@@ -25,35 +25,48 @@ describe('routeHmr.native', () => {
25
25
  expect(typeof globalThis.__VXRN_ON_MODULE_UPDATED__).toBe('function')
26
26
  })
27
27
 
28
- it('bumps the epoch and notifies subscribers, and stops after unsubscribe', () => {
28
+ it('does not bump the epoch, so Fast Refresh can keep the mounted route', () => {
29
29
  const before = routeHmr.getRouteHmrEpoch()
30
30
  const listener = vi.fn()
31
31
  const unsubscribe = routeHmr.subscribeRouteHmr(listener)
32
32
 
33
33
  globalThis.__VXRN_ON_MODULE_UPDATED__!('app/index.tsx')
34
- expect(routeHmr.getRouteHmrEpoch()).toBe(before + 1)
35
- expect(listener).toHaveBeenCalledTimes(1)
34
+ expect(routeHmr.getRouteHmrEpoch()).toBe(before)
35
+ expect(listener).not.toHaveBeenCalled()
36
36
 
37
37
  unsubscribe()
38
- globalThis.__VXRN_ON_MODULE_UPDATED__!('app/index.tsx')
39
- expect(listener).toHaveBeenCalledTimes(1)
40
38
  })
41
39
 
42
40
  it('evicts the route cache for the updated file when window.__oneRouteCache is present', () => {
43
- const clearFile = vi.fn()
41
+ const clearFile = vi.fn(() => true)
44
42
  ;(globalThis as any).window = { __oneRouteCache: { clearFile } }
45
43
  globalThis.__VXRN_ON_MODULE_UPDATED__!('app/_layout.tsx')
46
44
  expect(clearFile).toHaveBeenCalledWith('app/_layout.tsx')
47
45
  })
48
46
 
47
+ it('does not bump the epoch for a non-route module either', () => {
48
+ const before = routeHmr.getRouteHmrEpoch()
49
+ const listener = vi.fn()
50
+ const unsubscribe = routeHmr.subscribeRouteHmr(listener)
51
+ ;(globalThis as any).window = {
52
+ __oneRouteCache: { clearFile: () => false },
53
+ }
54
+
55
+ globalThis.__VXRN_ON_MODULE_UPDATED__!('features/onboarding/HmrProbeChild.tsx')
56
+ expect(routeHmr.getRouteHmrEpoch()).toBe(before)
57
+ expect(listener).not.toHaveBeenCalled()
58
+ unsubscribe()
59
+ })
60
+
49
61
  it('does not throw when window / route cache is absent', () => {
50
62
  ;(globalThis as any).window = undefined
51
63
  expect(() => globalThis.__VXRN_ON_MODULE_UPDATED__!('x.tsx')).not.toThrow()
52
64
  })
53
65
 
54
- it('still notifies subscribers when route-cache eviction throws', () => {
66
+ it('does not throw or bump the epoch when route-cache eviction throws', () => {
55
67
  const listener = vi.fn()
56
68
  const unsubscribe = routeHmr.subscribeRouteHmr(listener)
69
+ const before = routeHmr.getRouteHmrEpoch()
57
70
  ;(globalThis as any).window = {
58
71
  __oneRouteCache: {
59
72
  clearFile() {
@@ -62,10 +75,9 @@ describe('routeHmr.native', () => {
62
75
  },
63
76
  }
64
77
 
65
- expect(() => globalThis.__VXRN_ON_MODULE_UPDATED__!('app/index.tsx')).toThrow(
66
- 'cache eviction failed'
67
- )
68
- expect(listener).toHaveBeenCalledOnce()
78
+ expect(() => globalThis.__VXRN_ON_MODULE_UPDATED__!('app/index.tsx')).not.toThrow()
79
+ expect(routeHmr.getRouteHmrEpoch()).toBe(before)
80
+ expect(listener).not.toHaveBeenCalled()
69
81
  unsubscribe()
70
82
  })
71
83
  })
@@ -1,7 +1,10 @@
1
1
  // native Fast Refresh for One routes
2
2
  //
3
3
  // vxrn calls the global hook after committing an updated module. One evicts that
4
- // route and bumps this external-store epoch so mounted screens load fresh exports.
4
+ // route from the loader cache so the next loadRoute() sees fresh exports. it
5
+ // does not bump the epoch: ScreenComponent re-running loadRoute() would render a
6
+ // new function identity and remount the route, which is what made
7
+ // `generation:1` jump to `generation:2` when a route file was Fast Refreshed.
5
8
 
6
9
  declare global {
7
10
  // vxrn's native HMR runtime invokes this (when defined) with each committed
@@ -29,9 +32,8 @@ if (process.env.NODE_ENV === 'development') {
29
32
  if (typeof routeCache?.clearFile === 'function') {
30
33
  routeCache.clearFile(id)
31
34
  }
32
- } finally {
33
- routeHmrEpoch++
34
- routeHmrListeners.forEach((listener) => listener())
35
+ } catch (error) {
36
+ console.error('[one] route cache eviction failed', error)
35
37
  }
36
38
  }
37
39
  }
@@ -137,3 +137,75 @@ describe('route SuspenseFallback', () => {
137
137
  expect(renderer!.toJSON()).toBeNull()
138
138
  })
139
139
  })
140
+
141
+ describe('ErrorBoundary route identity', () => {
142
+ it('preserves page state across a re-render when the route exports ErrorBoundary', async () => {
143
+ let mounts = 0
144
+ function Page() {
145
+ const [count, setCount] = React.useState(0)
146
+ React.useEffect(() => {
147
+ mounts += 1
148
+ }, [])
149
+ return (
150
+ <button data-count={count} onClick={() => setCount((value) => value + 1)}>
151
+ {count}
152
+ </button>
153
+ )
154
+ }
155
+ function ErrorBoundary() {
156
+ return <div data-error="1" />
157
+ }
158
+
159
+ const node = createRouteNode('spa', 'onboarding', './auth/onboarding.tsx', () => ({
160
+ default: Page,
161
+ ErrorBoundary,
162
+ }))
163
+ const Route = getQualifiedRouteComponent(node)
164
+
165
+ function Harness({ tick }: { tick: number }) {
166
+ return <Route tick={tick} />
167
+ }
168
+
169
+ let renderer: TestRenderer.ReactTestRenderer
170
+ await act(async () => {
171
+ renderer = TestRenderer.create(<Harness tick={0} />)
172
+ })
173
+
174
+ const button = renderer!.root.findByType('button')
175
+ expect(button.props['data-count']).toBe(0)
176
+ await act(async () => {
177
+ button.props.onClick()
178
+ })
179
+ expect(renderer!.root.findByType('button').props['data-count']).toBe(1)
180
+ expect(mounts).toBe(1)
181
+
182
+ await act(async () => {
183
+ renderer.update(<Harness tick={1} />)
184
+ })
185
+
186
+ expect(renderer!.root.findByType('button').props['data-count']).toBe(1)
187
+ expect(mounts).toBe(1)
188
+ })
189
+
190
+ it('still renders the exported ErrorBoundary when the page throws', async () => {
191
+ function Page(): React.ReactNode {
192
+ throw new Error('boom')
193
+ }
194
+ function ErrorBoundary({ error }: { error: Error; retry: () => Promise<void> }) {
195
+ return <div data-caught={error.message} />
196
+ }
197
+
198
+ const node = createRouteNode('spa', 'broken', './broken.tsx', () => ({
199
+ default: Page,
200
+ ErrorBoundary,
201
+ }))
202
+ const Route = getQualifiedRouteComponent(node)
203
+
204
+ let renderer: TestRenderer.ReactTestRenderer
205
+ await act(async () => {
206
+ renderer = TestRenderer.create(<Route />)
207
+ })
208
+
209
+ expect(renderer!.root.findByProps({ 'data-caught': 'boom' })).toBeTruthy()
210
+ })
211
+ })
@@ -350,26 +350,16 @@ export function useSortedScreens(
350
350
  }
351
351
 
352
352
  function fromImport({ ErrorBoundary, SuspenseFallback, ...component }: LoadedRoute) {
353
- if (ErrorBoundary) {
354
- return {
355
- default: React.forwardRef((props: any, ref: any) => {
356
- const children = React.createElement(getPageExport(component) || EmptyRoute, {
357
- ...props,
358
- ref,
359
- })
360
- return <Try catch={ErrorBoundary}>{children}</Try>
361
- }),
362
- SuspenseFallback,
363
- }
364
- }
353
+ // keep ErrorBoundary on the returned module and wrap it in JSX below.
354
+ // a new forwardRef here remounts the route on every ScreenComponent render.
365
355
  if (process.env.NODE_ENV !== 'production') {
366
356
  const exported = getPageExport(component)
367
357
  if (exported && typeof exported === 'object' && Object.keys(exported).length === 0) {
368
- return { default: EmptyRoute, SuspenseFallback }
358
+ return { default: EmptyRoute, ErrorBoundary, SuspenseFallback }
369
359
  }
370
360
  }
371
361
 
372
- return { default: getPageExport(component), SuspenseFallback }
362
+ return { default: getPageExport(component), ErrorBoundary, SuspenseFallback }
373
363
  }
374
364
 
375
365
  function RouteSuspenseFallback({
@@ -422,9 +412,9 @@ export function getQualifiedRouteComponent(value: RouteNode) {
422
412
  }, [])
423
413
  }
424
414
 
425
- // native Fast Refresh: subscribe to the route-hot epoch (the routeHmr.native
426
- // store bumps it when vxrn reports a route module update) so this component
427
- // re-renders and re-runs loadRoute() to pick up the edited module's exports
415
+ // native Fast Refresh: subscribe to the route-hot epoch. route file patches
416
+ // are applied in place and do not bump it; a bump re-runs loadRoute() and
417
+ // remounts the screen.
428
418
  if (
429
419
  process.env.NODE_ENV === 'development' &&
430
420
  process.env.TAMAGUI_TARGET === 'native'
@@ -451,7 +441,8 @@ export function getQualifiedRouteComponent(value: RouteNode) {
451
441
  }
452
442
 
453
443
  const res = fromImport(value.loadRoute())
454
- const Component = getPageExport(res) as React.ComponentType<any>
444
+ const Component = (res.default || EmptyRoute) as React.ComponentType<any>
445
+ const CatchBoundary = res.ErrorBoundary
455
446
  const LayoutSuspenseFallback =
456
447
  value.type === 'layout' ? res.SuspenseFallback : undefined
457
448
  const match =
@@ -491,9 +482,10 @@ export function getQualifiedRouteComponent(value: RouteNode) {
491
482
  />
492
483
  )
493
484
  } else {
485
+ const page = <Component {...props} {...slotProps} {...loaderDataProps} ref={ref} />
494
486
  rendered = (
495
487
  <RouteErrorBoundary routeName={value.route}>
496
- <Component {...props} {...slotProps} {...loaderDataProps} ref={ref} />
488
+ {CatchBoundary ? <Try catch={CatchBoundary}>{page}</Try> : page}
497
489
  </RouteErrorBoundary>
498
490
  )
499
491
  }
@@ -227,17 +227,18 @@ export function globbedRoutesToRouteContext(
227
227
  })
228
228
  },
229
229
  clearFile: (file: string) => {
230
- hmrVersion++
231
230
  const normalizedFile = file.replace(/\\/g, '/').replace(/^\//, '')
232
231
  const routeId = moduleKeys.find(
233
232
  (key) =>
234
233
  routePaths[key].replace(/\\/g, '/').replace(/^\//, '') === normalizedFile
235
234
  )
236
- if (!routeId) return
235
+ if (!routeId) return false
237
236
 
237
+ hmrVersion++
238
238
  delete loadedRoutes[routeId]
239
239
  delete promises[routeId]
240
240
  delete preloadedModules[routePaths[routeId]]
241
+ return true
241
242
  },
242
243
  getVersion: () => hmrVersion,
243
244
  }
@@ -1,7 +1,7 @@
1
1
  // A fork of `useFocusEffect` that waits for the navigation state to load before
2
2
  // running the effect. This is especially useful for native redirects.
3
3
 
4
- import { useEffect } from 'react'
4
+ import { useEffect, useRef } from 'react'
5
5
  import { useOptionalNavigation } from './link/useLoadedNavigation'
6
6
 
7
7
  type EffectCallback = () => undefined | void | (() => void)
@@ -30,6 +30,18 @@ type EffectCallback = () => undefined | void | (() => void)
30
30
  export function useFocusEffect(effect: EffectCallback, deps: any[] = []) {
31
31
  const navigation = useOptionalNavigation()
32
32
 
33
+ const prevDepsRef = useRef(deps)
34
+ const depsCountRef = useRef(0)
35
+ if (
36
+ !Array.isArray(deps) ||
37
+ !Array.isArray(prevDepsRef.current) ||
38
+ prevDepsRef.current.length !== deps.length ||
39
+ prevDepsRef.current.some((d, i) => !Object.is(d, deps[i]))
40
+ ) {
41
+ prevDepsRef.current = deps
42
+ depsCountRef.current++
43
+ }
44
+
33
45
  useEffect(() => {
34
46
  if (!navigation) {
35
47
  return
@@ -102,7 +114,5 @@ export function useFocusEffect(effect: EffectCallback, deps: any[] = []) {
102
114
  unsubscribeFocus()
103
115
  unsubscribeBlur()
104
116
  }
105
- // guard the spread: a caller passing `undefined` (or a non-array) for `deps`
106
- // would otherwise throw "deps is not iterable" and crash the screen.
107
- }, [navigation, ...(Array.isArray(deps) ? deps : [])])
117
+ }, [navigation, depsCountRef.current])
108
118
  }
package/src/vite/one.ts CHANGED
@@ -860,7 +860,9 @@ export function one(options: One.PluginOptions = {}): PluginOption {
860
860
  // environment, so nothing in `config.plugins` reaches it. one's own plugins
861
861
  // go first, then whatever the app opted in through native.bundlerOptions.
862
862
  const viteBundlerOptions =
863
- nativeOptions?.bundler === 'metro' ? undefined : (nativeOptions?.bundlerOptions as any)
863
+ nativeOptions?.bundler === 'metro'
864
+ ? undefined
865
+ : (nativeOptions?.bundlerOptions as any)
864
866
 
865
867
  globalThis.__vxrnAddNativePlugins = [
866
868
  clientTreeShakePlugin({ runtime: 'rolldown', routerRoot }),
@@ -1,6 +1,10 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
- import { getSourceInspectorPath, resolveEditorFilePath } from './sourceInspectorPlugin'
3
+ import {
4
+ getSourceInspectorPath,
5
+ injectSourceToJsx,
6
+ resolveEditorFilePath,
7
+ } from './sourceInspectorPlugin'
4
8
 
5
9
  describe('sourceInspectorPlugin helpers', () => {
6
10
  describe('getSourceInspectorPath', () => {
@@ -37,4 +41,36 @@ describe('sourceInspectorPlugin helpers', () => {
37
41
  ).toBe('/Users/n8/shared/ui/Button.tsx')
38
42
  })
39
43
  })
44
+
45
+ describe('injectSourceToJsx', () => {
46
+ it('tags dom elements and components but leaves custom reconciler tags alone', async () => {
47
+ const out = await injectSourceToJsx(
48
+ [
49
+ 'export const Scene = () => (',
50
+ ' <div>',
51
+ ' <Canvas>',
52
+ ' <mesh position={[0, 1, 0]}>',
53
+ ' <boxGeometry />',
54
+ ' <meshStandardMaterial color="red" />',
55
+ ' </mesh>',
56
+ ' <instancedMesh args={[geometry, material, 4]} />',
57
+ ' </Canvas>',
58
+ ' <svg><linearGradient id="g" /></svg>',
59
+ ' </div>',
60
+ ')',
61
+ ].join('\n'),
62
+ `${process.cwd()}/src/Scene.tsx`
63
+ )
64
+ const code = out?.code ?? ''
65
+ expect(code).toContain('<div data-one-source=')
66
+ expect(code).toContain('<Canvas data-one-source=')
67
+ expect(code).toContain('<svg data-one-source=')
68
+ expect(code).toContain('<linearGradient data-one-source=')
69
+ expect(code).toContain('<mesh position=')
70
+ expect(code).toContain('<boxGeometry />')
71
+ expect(code).toContain('<meshStandardMaterial color=')
72
+ expect(code).toContain('<instancedMesh args=')
73
+ expect(code).not.toMatch(/<(mesh|boxGeometry|meshStandardMaterial|instancedMesh) data-one-source/)
74
+ })
75
+ })
40
76
  })
@@ -18,6 +18,22 @@ interface JsxLocation {
18
18
  /**
19
19
  * Parse code with oxc and find all JSX opening elements.
20
20
  */
21
+ // lowercase jsx tags are host elements. on the web only real html and svg
22
+ // tags accept a data attribute; other lowercase tags belong to a custom
23
+ // reconciler (react-three-fiber's <mesh>, <group>, <instancedMesh>...) which
24
+ // applies props to plain objects and throws on the dashed attribute.
25
+ const DOM_TAGS = new Set(
26
+ (
27
+ 'a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption cite code col colgroup data datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd label legend li link main map mark menu meta meter nav noscript object ol optgroup option output p picture pre progress q rp rt ruby s samp script search section select slot small source span strong style sub summary sup table tbody td template textarea tfoot th thead time title tr track u ul var video wbr ' +
28
+ 'svg animate animateMotion animateTransform circle clipPath defs desc ellipse feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence filter foreignObject g image line linearGradient marker mask metadata mpath path pattern polygon polyline radialGradient rect set stop switch symbol text textPath tspan use view'
29
+ ).split(' ')
30
+ )
31
+
32
+ function isHostTag(tagName: string): boolean {
33
+ const first = tagName.charCodeAt(0)
34
+ return first >= 97 && first <= 122 && !tagName.includes('.')
35
+ }
36
+
21
37
  async function findJsxElements(code: string, filename: string): Promise<JsxLocation[]> {
22
38
  const result = await parse(filename, code)
23
39
 
@@ -52,8 +68,13 @@ async function findJsxElements(code: string, filename: string): Promise<JsxLocat
52
68
  if (node.type === 'JSXOpeningElement' && node.name) {
53
69
  const tagName = getJsxName(node.name)
54
70
 
55
- // skip Fragment and already-tagged elements
56
- if (tagName && tagName !== 'Fragment' && !tagName.endsWith('.Fragment')) {
71
+ // skip Fragment, non-dom host elements, and already-tagged elements
72
+ if (
73
+ tagName &&
74
+ tagName !== 'Fragment' &&
75
+ !tagName.endsWith('.Fragment') &&
76
+ (!isHostTag(tagName) || DOM_TAGS.has(tagName))
77
+ ) {
57
78
  const hasSourceAttr = node.attributes?.some(
58
79
  (attr: any) =>
59
80
  attr.type === 'JSXAttribute' && attr.name?.name === 'data-one-source'
@@ -123,7 +144,7 @@ export function resolveEditorFilePath(
123
144
  /**
124
145
  * Transforms JSX to inject data-one-source attributes using oxc-parser.
125
146
  */
126
- async function injectSourceToJsx(code: string, id: string): Promise<TransformOut> {
147
+ export async function injectSourceToJsx(code: string, id: string): Promise<TransformOut> {
127
148
  const [filePath] = id.split('?')
128
149
  if (!filePath) return
129
150
 
@@ -1 +1 @@
1
- {"version":3,"file":"getNormalizedStatePath.d.ts","sourceRoot":"","sources":["../../src/router/getNormalizedStatePath.tsx"],"names":[],"mappings":"AAEA,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAA;AAErD,MAAM,MAAM,SAAS,GAAG;IACtB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAGD,wBAAgB,sBAAsB,CACpC,EACE,IAAI,EAAE,SAAS,EACf,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,GAAG,CAAA;CACZ,EACD,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC,CA6BxC"}
1
+ {"version":3,"file":"getNormalizedStatePath.d.ts","sourceRoot":"","sources":["../../src/router/getNormalizedStatePath.tsx"],"names":[],"mappings":"AAGA,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAA;AAErD,MAAM,MAAM,SAAS,GAAG;IACtB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAGD,wBAAgB,sBAAsB,CACpC,EACE,IAAI,EAAE,SAAS,EACf,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,GAAG,CAAA;CACZ,EACD,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC,CA6BxC"}
@@ -1,4 +1,9 @@
1
+ import { type State } from '../fork/getPathFromState';
1
2
  import type { OneRouter } from '../interfaces/router';
2
3
  import { type UrlObject } from './getNormalizedStatePath';
3
4
  export declare function getRouteInfo(state: OneRouter.ResultState): UrlObject;
5
+ export declare function getRouteInfoFromState(getPathFromState: (state: State, asPath: boolean) => {
6
+ path: string;
7
+ params: any;
8
+ }, state: State, baseUrl?: string): UrlObject;
4
9
  //# sourceMappingURL=getRouteInfo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getRouteInfo.d.ts","sourceRoot":"","sources":["../../src/router/getRouteInfo.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAIjF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,aAYxD"}
1
+ {"version":3,"file":"getRouteInfo.d.ts","sourceRoot":"","sources":["../../src/router/getRouteInfo.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAE3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAKjF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,aAYxD;AAED,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,EAClF,KAAK,EAAE,KAAK,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,CAYX"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=getRouteInfo.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getRouteInfo.test.d.ts","sourceRoot":"","sources":["../../src/router/getRouteInfo.test.ts"],"names":[],"mappings":""}
@@ -1,3 +1,4 @@
1
+ export declare function stripPathSuffix(path: string): string;
1
2
  export declare function stripTrailingSlash(pathname: string): string;
2
3
  export declare function normalizeRoutePathname(pathname: string): string;
3
4
  export declare function hasLostDynamicSegment(path: string): boolean;