one 1.21.1 → 1.21.2

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 (117) hide show
  1. package/dist/cjs/cli/build.cjs +1 -4
  2. package/dist/cjs/cli/build.native.js +1 -4
  3. package/dist/cjs/cli/build.native.js.map +1 -1
  4. package/dist/cjs/cli/buildPage.cjs +1 -1
  5. package/dist/cjs/cli/buildPage.native.js +1 -1
  6. package/dist/cjs/cli/buildPage.native.js.map +1 -1
  7. package/dist/cjs/daemon/ipc.cjs +21 -3
  8. package/dist/cjs/daemon/ipc.native.js +21 -3
  9. package/dist/cjs/daemon/ipc.native.js.map +1 -1
  10. package/dist/cjs/router/hmrImport.native.js +13 -2
  11. package/dist/cjs/router/hmrImport.native.js.map +1 -1
  12. package/dist/cjs/router/hmrImport.native.test.cjs +52 -0
  13. package/dist/cjs/router/hmrImport.native.test.native.js +61 -0
  14. package/dist/cjs/router/hmrImport.native.test.native.js.map +1 -0
  15. package/dist/cjs/router/routeHmr.cjs +32 -0
  16. package/dist/cjs/router/routeHmr.native.js +57 -0
  17. package/dist/cjs/router/routeHmr.native.js.map +1 -0
  18. package/dist/cjs/router/routeHmr.native.test.cjs +83 -0
  19. package/dist/cjs/router/routeHmr.native.test.native.js +95 -0
  20. package/dist/cjs/router/routeHmr.native.test.native.js.map +1 -0
  21. package/dist/cjs/router/useScreens.cjs +2 -0
  22. package/dist/cjs/router/useScreens.native.js +2 -0
  23. package/dist/cjs/router/useScreens.native.js.map +1 -1
  24. package/dist/cjs/router/useViteRoutes.cjs +7 -17
  25. package/dist/cjs/router/useViteRoutes.native.js +8 -18
  26. package/dist/cjs/router/useViteRoutes.native.js.map +1 -1
  27. package/dist/cjs/router/useViteRoutes.test.cjs +42 -0
  28. package/dist/cjs/router/useViteRoutes.test.native.js +55 -0
  29. package/dist/cjs/router/useViteRoutes.test.native.js.map +1 -0
  30. package/dist/cjs/utils/cleanUrl.cjs +12 -2
  31. package/dist/cjs/utils/cleanUrl.native.js +15 -3
  32. package/dist/cjs/utils/cleanUrl.native.js.map +1 -1
  33. package/dist/cjs/utils/cleanUrl.test.cjs +37 -0
  34. package/dist/cjs/utils/cleanUrl.test.native.js +37 -0
  35. package/dist/cjs/utils/cleanUrl.test.native.js.map +1 -1
  36. package/dist/esm/cli/build.mjs +1 -4
  37. package/dist/esm/cli/build.mjs.map +1 -1
  38. package/dist/esm/cli/build.native.js +1 -4
  39. package/dist/esm/cli/build.native.js.map +1 -1
  40. package/dist/esm/cli/buildPage.mjs +2 -2
  41. package/dist/esm/cli/buildPage.mjs.map +1 -1
  42. package/dist/esm/cli/buildPage.native.js +2 -2
  43. package/dist/esm/cli/buildPage.native.js.map +1 -1
  44. package/dist/esm/daemon/ipc.mjs +21 -3
  45. package/dist/esm/daemon/ipc.mjs.map +1 -1
  46. package/dist/esm/daemon/ipc.native.js +21 -3
  47. package/dist/esm/daemon/ipc.native.js.map +1 -1
  48. package/dist/esm/router/hmrImport.native.js +13 -2
  49. package/dist/esm/router/hmrImport.native.js.map +1 -1
  50. package/dist/esm/router/hmrImport.native.test.js +51 -0
  51. package/dist/esm/router/hmrImport.native.test.js.map +6 -0
  52. package/dist/esm/router/hmrImport.native.test.mjs +53 -0
  53. package/dist/esm/router/hmrImport.native.test.mjs.map +1 -0
  54. package/dist/esm/router/hmrImport.native.test.native.js +59 -0
  55. package/dist/esm/router/hmrImport.native.test.native.js.map +1 -0
  56. package/dist/esm/router/routeHmr.mjs +6 -0
  57. package/dist/esm/router/routeHmr.mjs.map +1 -0
  58. package/dist/esm/router/routeHmr.native.js +28 -0
  59. package/dist/esm/router/routeHmr.native.js.map +1 -0
  60. package/dist/esm/router/routeHmr.native.test.js +58 -0
  61. package/dist/esm/router/routeHmr.native.test.js.map +6 -0
  62. package/dist/esm/router/routeHmr.native.test.mjs +60 -0
  63. package/dist/esm/router/routeHmr.native.test.mjs.map +1 -0
  64. package/dist/esm/router/routeHmr.native.test.native.js +69 -0
  65. package/dist/esm/router/routeHmr.native.test.native.js.map +1 -0
  66. package/dist/esm/router/useScreens.mjs +1 -0
  67. package/dist/esm/router/useScreens.mjs.map +1 -1
  68. package/dist/esm/router/useScreens.native.js +2 -0
  69. package/dist/esm/router/useScreens.native.js.map +1 -1
  70. package/dist/esm/router/useViteRoutes.mjs +7 -17
  71. package/dist/esm/router/useViteRoutes.mjs.map +1 -1
  72. package/dist/esm/router/useViteRoutes.native.js +8 -18
  73. package/dist/esm/router/useViteRoutes.native.js.map +1 -1
  74. package/dist/esm/router/useViteRoutes.test.mjs +43 -0
  75. package/dist/esm/router/useViteRoutes.test.mjs.map +1 -0
  76. package/dist/esm/router/useViteRoutes.test.native.js +53 -0
  77. package/dist/esm/router/useViteRoutes.test.native.js.map +1 -0
  78. package/dist/esm/utils/cleanUrl.mjs +11 -3
  79. package/dist/esm/utils/cleanUrl.mjs.map +1 -1
  80. package/dist/esm/utils/cleanUrl.native.js +14 -4
  81. package/dist/esm/utils/cleanUrl.native.js.map +1 -1
  82. package/dist/esm/utils/cleanUrl.test.mjs +38 -1
  83. package/dist/esm/utils/cleanUrl.test.mjs.map +1 -1
  84. package/dist/esm/utils/cleanUrl.test.native.js +38 -1
  85. package/dist/esm/utils/cleanUrl.test.native.js.map +1 -1
  86. package/package.json +9 -9
  87. package/src/cli/build.ts +1 -1
  88. package/src/cli/buildPage.ts +12 -2
  89. package/src/daemon/ipc.ts +46 -4
  90. package/src/router/hmrImport.native.test.ts +55 -0
  91. package/src/router/hmrImport.native.ts +25 -5
  92. package/src/router/routeHmr.native.test.ts +71 -0
  93. package/src/router/routeHmr.native.ts +37 -0
  94. package/src/router/routeHmr.ts +8 -0
  95. package/src/router/useScreens.tsx +12 -0
  96. package/src/router/useViteRoutes.test.ts +49 -0
  97. package/src/router/useViteRoutes.tsx +12 -21
  98. package/src/utils/cleanUrl.test.ts +63 -1
  99. package/src/utils/cleanUrl.ts +25 -3
  100. package/types/cli/buildPage.d.ts.map +1 -1
  101. package/types/daemon/ipc.d.ts.map +1 -1
  102. package/types/router/hmrImport.native.d.ts +8 -3
  103. package/types/router/hmrImport.native.d.ts.map +1 -1
  104. package/types/router/hmrImport.native.test.d.ts +2 -0
  105. package/types/router/hmrImport.native.test.d.ts.map +1 -0
  106. package/types/router/routeHmr.d.ts +3 -0
  107. package/types/router/routeHmr.d.ts.map +1 -0
  108. package/types/router/routeHmr.native.d.ts +6 -0
  109. package/types/router/routeHmr.native.d.ts.map +1 -0
  110. package/types/router/routeHmr.native.test.d.ts +2 -0
  111. package/types/router/routeHmr.native.test.d.ts.map +1 -0
  112. package/types/router/useScreens.d.ts.map +1 -1
  113. package/types/router/useViteRoutes.d.ts.map +1 -1
  114. package/types/router/useViteRoutes.test.d.ts +2 -0
  115. package/types/router/useViteRoutes.test.d.ts.map +1 -0
  116. package/types/utils/cleanUrl.d.ts +2 -0
  117. package/types/utils/cleanUrl.d.ts.map +1 -1
@@ -0,0 +1,43 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { globbedRoutesToRouteContext } from "./useViteRoutes.mjs";
3
+ const mocks = vi.hoisted(() => ({
4
+ hmrImport: vi.fn()
5
+ }));
6
+ vi.mock("./hmrImport", () => ({
7
+ hmrImport: mocks.hmrImport
8
+ }));
9
+ const realWindow = globalThis.window;
10
+ afterEach(() => {
11
+ vi.unstubAllEnvs();
12
+ mocks.hmrImport.mockReset();
13
+ globalThis.window = realWindow;
14
+ });
15
+ async function resolveRoute(context) {
16
+ try {
17
+ return context("./index.tsx");
18
+ } catch (pending) {
19
+ await pending;
20
+ return context("./index.tsx");
21
+ }
22
+ }
23
+ describe("globbedRoutesToRouteContext HMR", () => {
24
+ it("evicts and reloads a route under a custom router root", async () => {
25
+ vi.stubEnv("NODE_ENV", "development");
26
+ globalThis.window = {};
27
+ const initialRoute = {
28
+ default: () => "initial"
29
+ };
30
+ const updatedRoute = {
31
+ default: () => "updated"
32
+ };
33
+ const context = globbedRoutesToRouteContext({
34
+ "/routes/index.tsx": () => Promise.resolve(initialRoute)
35
+ }, "routes");
36
+ await expect(resolveRoute(context)).resolves.toBe(initialRoute);
37
+ mocks.hmrImport.mockResolvedValue(updatedRoute);
38
+ globalThis.window.__oneRouteCache.clearFile("routes/index.tsx");
39
+ await expect(resolveRoute(context)).resolves.toBe(updatedRoute);
40
+ expect(mocks.hmrImport).toHaveBeenCalledWith("/routes/index.tsx");
41
+ });
42
+ });
43
+ //# sourceMappingURL=useViteRoutes.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["afterEach","describe","expect","it","vi","globbedRoutesToRouteContext","mocks","hoisted","hmrImport","fn","mock","realWindow","globalThis","window","unstubAllEnvs","mockReset","resolveRoute","context","pending","stubEnv","initialRoute","default","updatedRoute","/routes/index.tsx","Promise","resolve","resolves","toBe","mockResolvedValue","__oneRouteCache","clearFile","toHaveBeenCalledWith"],"sources":["../../../src/router/useViteRoutes.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,SAAA,EAAWC,QAAA,EAAUC,MAAA,EAAQC,EAAA,EAAIC,EAAA,QAAU;AAUpD,SAASC,2BAAA,QAAmC;AAR5C,MAAMC,KAAA,GAAQF,EAAA,CAAGG,OAAA,CAAQ,OAAO;EAC9BC,SAAA,EAAWJ,EAAA,CAAGK,EAAA,CAAG;AACnB,EAAE;AAEFL,EAAA,CAAGM,IAAA,CAAK,eAAe,OAAO;EAC5BF,SAAA,EAAWF,KAAA,CAAME;AACnB,EAAE;AAIF,MAAMG,UAAA,GAAcC,UAAA,CAAmBC,MAAA;AAEvCb,SAAA,CAAU,MAAM;EACdI,EAAA,CAAGU,aAAA,CAAc;EACjBR,KAAA,CAAME,SAAA,CAAUO,SAAA,CAAU;EACxBH,UAAA,CAAmBC,MAAA,GAASF,UAAA;AAChC,CAAC;AAED,eAAeK,aAAaC,OAAA,EAAyD;EACnF,IAAI;IACF,OAAOA,OAAA,CAAQ,aAAa;EAC9B,SAASC,OAAA,EAAS;IAChB,MAAMA,OAAA;IACN,OAAOD,OAAA,CAAQ,aAAa;EAC9B;AACF;AAEAhB,QAAA,CAAS,mCAAmC,MAAM;EAChDE,EAAA,CAAG,yDAAyD,YAAY;IACtEC,EAAA,CAAGe,OAAA,CAAQ,YAAY,aAAa;IAClCP,UAAA,CAAmBC,MAAA,GAAS,CAAC;IAC/B,MAAMO,YAAA,GAAe;MAAEC,OAAA,EAASA,CAAA,KAAM;IAAU;IAChD,MAAMC,YAAA,GAAe;MAAED,OAAA,EAASA,CAAA,KAAM;IAAU;IAChD,MAAMJ,OAAA,GAAUZ,2BAAA,CACd;MAAE,qBAAqBkB,CAAA,KAAMC,OAAA,CAAQC,OAAA,CAAQL,YAAY;IAAE,GAC3D,QACF;IAEA,MAAMlB,MAAA,CAAOc,YAAA,CAAaC,OAAO,CAAC,EAAES,QAAA,CAASC,IAAA,CAAKP,YAAY;IAE9Dd,KAAA,CAAME,SAAA,CAAUoB,iBAAA,CAAkBN,YAAY;IAC5CV,UAAA,CAAmBC,MAAA,CAAOgB,eAAA,CAAgBC,SAAA,CAAU,kBAAkB;IAExE,MAAM5B,MAAA,CAAOc,YAAA,CAAaC,OAAO,CAAC,EAAES,QAAA,CAASC,IAAA,CAAKL,YAAY;IAC9DpB,MAAA,CAAOI,KAAA,CAAME,SAAS,EAAEuB,oBAAA,CAAqB,mBAAmB;EAClE,CAAC;AACH,CAAC","ignoreList":[]}
@@ -0,0 +1,53 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { globbedRoutesToRouteContext } from "./useViteRoutes.native.js";
3
+ var mocks = vi.hoisted(function () {
4
+ return {
5
+ hmrImport: vi.fn()
6
+ };
7
+ });
8
+ vi.mock("./hmrImport", function () {
9
+ return {
10
+ hmrImport: mocks.hmrImport
11
+ };
12
+ });
13
+ var realWindow = globalThis.window;
14
+ afterEach(function () {
15
+ vi.unstubAllEnvs();
16
+ mocks.hmrImport.mockReset();
17
+ globalThis.window = realWindow;
18
+ });
19
+ async function resolveRoute(context) {
20
+ try {
21
+ return context("./index.tsx");
22
+ } catch (pending) {
23
+ await pending;
24
+ return context("./index.tsx");
25
+ }
26
+ }
27
+ describe("globbedRoutesToRouteContext HMR", function () {
28
+ it("evicts and reloads a route under a custom router root", async function () {
29
+ vi.stubEnv("NODE_ENV", "development");
30
+ globalThis.window = {};
31
+ var initialRoute = {
32
+ default: function () {
33
+ return "initial";
34
+ }
35
+ };
36
+ var updatedRoute = {
37
+ default: function () {
38
+ return "updated";
39
+ }
40
+ };
41
+ var context = globbedRoutesToRouteContext({
42
+ "/routes/index.tsx": function () {
43
+ return Promise.resolve(initialRoute);
44
+ }
45
+ }, "routes");
46
+ await expect(resolveRoute(context)).resolves.toBe(initialRoute);
47
+ mocks.hmrImport.mockResolvedValue(updatedRoute);
48
+ globalThis.window.__oneRouteCache.clearFile("routes/index.tsx");
49
+ await expect(resolveRoute(context)).resolves.toBe(updatedRoute);
50
+ expect(mocks.hmrImport).toHaveBeenCalledWith("/routes/index.tsx");
51
+ });
52
+ });
53
+ //# sourceMappingURL=useViteRoutes.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["afterEach","describe","expect","it","vi","globbedRoutesToRouteContext","mocks","hoisted","hmrImport","fn","mock","realWindow","globalThis","window","unstubAllEnvs","mockReset","resolveRoute","context","pending","stubEnv","initialRoute","default","updatedRoute"],"sources":["../../../src/router/useViteRoutes.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,SAAA,EAAWC,QAAA,EAAUC,MAAA,EAAQC,EAAA,EAAIC,EAAA,QAAU;AAUpD,SAASC,2BAAA,QAAmC;AAR5C,IAAAC,KAAM,GAAAF,EAAQ,CAAAG,OAAG,aAAe;EAC9B;IACAC,SAAA,EAAAJ,EAAA,CAAAK,EAAA;EAEF,CAAG;AAA2B,EAC5B;AACFL,EAAE,CAAAM,IAAA;EAIF,OAAM;IAENF,SAAU,EAAAF,KAAM,CAAAE;EACd;AACA;AACC,IAACG,UAAmB,GAAAC,UAAS,CAAAC,MAAA;AAChCb,SAAC;EAEDI,EAAA,CAAAU,aAAe;EACbR,KAAI,CAAAE,SAAA,CAAAO,SAAA;EACFH,UAAO,CAAAC,MAAQ,GAAAF,UAAa;AAAA,EAC9B;AACE,eAAMK,aAAAC,OAAA;EACN;IACF,OAAAA,OAAA;EACF,SAAAC,OAAA;IAEA,MAASA,OAAA;IACP,OAAGD,OAAA;EACD;AACC;AACDhB,QAAA,kCAAsC,cAAU;EAChDE,EAAA,wDAAgD;IAChDC,EAAA,CAAAe,OAAM,WAAU;IAAAP,UACZ,CAAAC,MAAA;IAAyD,IAC3DO,YAAA;MACFC,OAAA,WAAAA,CAAA;QAEA,OAAM,SAAO;MAEb;IACE;IAEF,IAAAC,YAAa;MACbD,OAAO,WAAAA,CAAA,EAAe;QACvB;MACF","ignoreList":[]}
@@ -1,8 +1,16 @@
1
1
  import { CSS_PRELOAD_JS_POSTFIX, isNative, LOADER_JS_POSTFIX, LOADER_JS_POSTFIX_REGEX, PRELOAD_JS_POSTFIX } from "../constants.mjs";
2
2
  import { getURL } from "../getURL.mjs";
3
3
  import { removeSearch } from "./removeSearch.mjs";
4
+ function encodeReservedFilenameChars(path) {
5
+ return path.replaceAll("=", "=3d").replace(/[<>:"|?*]/g, char => `=${char.charCodeAt(0).toString(16).padStart(2, "0")}`);
6
+ }
7
+ function decodeReservedFilenameChars(path) {
8
+ return path.replace(/=([0-9a-f]{2})/g, (_match, hexCode) => String.fromCharCode(Number.parseInt(hexCode, 16)));
9
+ }
4
10
  function cleanUrl(path) {
5
- return removeSearch(path).replace(/\/$/, "").replaceAll("_", "__").replaceAll("/", "_");
11
+ return encodeReservedFilenameChars(removeSearch(path).replace(/\/$/, "")
12
+ // remove trailing slash before encoding
13
+ ).replaceAll("_", "__").replaceAll("/", "_");
6
14
  }
7
15
  const isClient = typeof window !== "undefined";
8
16
  const clientSideURL = isClient ? getURL() : "";
@@ -21,7 +29,7 @@ function getLoaderPath(currentPath, includeUrl = isNative, cacheBust) {
21
29
  return `${baseURL}${devPath}/assets/${cleanedUrl}${cacheBustSegment}${LOADER_JS_POSTFIX}`;
22
30
  }
23
31
  function getPathFromLoaderPath(loaderPath) {
24
- return loaderPath.replace(LOADER_JS_POSTFIX_REGEX, "").replace(/^(\/_one)?\/assets/, "").replace(/_refetch_\d+_?/, "").replace(/__|_/g, match => match === "__" ? "_" : "/");
32
+ return decodeReservedFilenameChars(loaderPath.replace(LOADER_JS_POSTFIX_REGEX, "").replace(/^(\/_one)?\/assets/, "").replace(/_refetch_\d+_?/, "").replace(/__|_/g, match => match === "__" ? "_" : "/"));
25
33
  }
26
- export { getLoaderPath, getPathFromLoaderPath, getPreloadCSSPath, getPreloadPath };
34
+ export { decodeReservedFilenameChars, encodeReservedFilenameChars, getLoaderPath, getPathFromLoaderPath, getPreloadCSSPath, getPreloadPath };
27
35
  //# sourceMappingURL=cleanUrl.mjs.map
@@ -1 +1 @@
1
- {"version":3,"names":["CSS_PRELOAD_JS_POSTFIX","isNative","LOADER_JS_POSTFIX","LOADER_JS_POSTFIX_REGEX","PRELOAD_JS_POSTFIX","getURL","removeSearch","cleanUrl","path","replace","replaceAll","isClient","window","clientSideURL","getPreloadPath","currentPath","slice","getPreloadCSSPath","getLoaderPath","includeUrl","cacheBust","baseURL","devPath","process","env","NODE_ENV","currentPathUrl","URL","cleanedUrl","pathname","cacheBustSegment","getPathFromLoaderPath","loaderPath","match"],"sources":["../../../src/utils/cleanUrl.ts"],"sourcesContent":[null],"mappings":"AAAA,SACEA,sBAAA,EACAC,QAAA,EACAC,iBAAA,EACAC,uBAAA,EACAC,kBAAA,QACK;AACP,SAASC,MAAA,QAAc;AACvB,SAASC,YAAA,QAAoB;AAE7B,SAASC,SAASC,IAAA,EAAc;EAC9B,OAAOF,YAAA,CAAaE,IAAI,EACrBC,OAAA,CAAQ,OAAO,EAAE,EACjBC,UAAA,CAAW,KAAK,IAAI,EACpBA,UAAA,CAAW,KAAK,GAAG;AACxB;AAEA,MAAMC,QAAA,GAAW,OAAOC,MAAA,KAAW;AACnC,MAAMC,aAAA,GAAgBF,QAAA,GAAWN,MAAA,CAAO,IAAI;AAErC,SAASS,eAAeC,WAAA,EAAqB;EAClD,OAAO,GAAGF,aAAa,WAAWN,QAAA,CAASQ,WAAA,CAAYC,KAAA,CAAM,CAAC,CAAC,CAAC,GAAGZ,kBAAkB;AACvF;AAEO,SAASa,kBAAkBF,WAAA,EAAqB;EACrD,OAAO,GAAGF,aAAa,WAAWN,QAAA,CAASQ,WAAA,CAAYC,KAAA,CAAM,CAAC,CAAC,CAAC,GAAGhB,sBAAsB;AAC3F;AAEO,SAASkB,cACdH,WAAA,EACAI,UAAA,GAAalB,QAAA,EACbmB,SAAA,EACA;EACA,MAAMC,OAAA,GAAUF,UAAA,GAAad,MAAA,CAAO,IAAI;EACxC,MAAMiB,OAAA,GAAUC,OAAA,CAAQC,GAAA,CAAIC,QAAA,KAAa,gBAAgB,UAAU;EAEnE,MAAMC,cAAA,GAAiB,IAAIC,GAAA,CAAIZ,WAAA,EAAa,oBAAoB;EAEhE,MAAMa,UAAA,GAAarB,QAAA,CAASmB,cAAA,CAAeG,QAAA,CAASb,KAAA,CAAM,CAAC,CAAC;EAC5D,MAAMc,gBAAA,GAAmBV,SAAA,GAAY,YAAYA,SAAS,MAAM;EAEhE,OAAO,GAAGC,OAAO,GAAGC,OAAO,WAAWM,UAAU,GAAGE,gBAAgB,GAAG5B,iBAAiB;AACzF;AAEO,SAAS6B,sBAAsBC,UAAA,EAAoB;EACxD,OACEA,UAAA,CACGvB,OAAA,CAAQN,uBAAA,EAAyB,EAAE,EACnCM,OAAA,CAAQ,sBAAsB,EAAE,EAChCA,OAAA,CAAQ,kBAAkB,EAAE,EAE5BA,OAAA,CAAQ,SAAUwB,KAAA,IAAWA,KAAA,KAAU,OAAO,MAAM,GAAI;AAE/D","ignoreList":[]}
1
+ {"version":3,"names":["CSS_PRELOAD_JS_POSTFIX","isNative","LOADER_JS_POSTFIX","LOADER_JS_POSTFIX_REGEX","PRELOAD_JS_POSTFIX","getURL","removeSearch","encodeReservedFilenameChars","path","replaceAll","replace","char","charCodeAt","toString","padStart","decodeReservedFilenameChars","_match","hexCode","String","fromCharCode","Number","parseInt","cleanUrl","isClient","window","clientSideURL","getPreloadPath","currentPath","slice","getPreloadCSSPath","getLoaderPath","includeUrl","cacheBust","baseURL","devPath","process","env","NODE_ENV","currentPathUrl","URL","cleanedUrl","pathname","cacheBustSegment","getPathFromLoaderPath","loaderPath","match"],"sources":["../../../src/utils/cleanUrl.ts"],"sourcesContent":[null],"mappings":"AAAA,SACEA,sBAAA,EACAC,QAAA,EACAC,iBAAA,EACAC,uBAAA,EACAC,kBAAA,QACK;AACP,SAASC,MAAA,QAAc;AACvB,SAASC,YAAA,QAAoB;AAQtB,SAASC,4BAA4BC,IAAA,EAAc;EACxD,OAAOA,IAAA,CACJC,UAAA,CAAW,KAAK,KAAK,EACrBC,OAAA,CACC,cACCC,IAAA,IAAS,IAAIA,IAAA,CAAKC,UAAA,CAAW,CAAC,EAAEC,QAAA,CAAS,EAAE,EAAEC,QAAA,CAAS,GAAG,GAAG,CAAC,EAChE;AACJ;AAEO,SAASC,4BAA4BP,IAAA,EAAc;EACxD,OAAOA,IAAA,CAAKE,OAAA,CAAQ,mBAAmB,CAACM,MAAA,EAAQC,OAAA,KAC9CC,MAAA,CAAOC,YAAA,CAAaC,MAAA,CAAOC,QAAA,CAASJ,OAAA,EAAS,EAAE,CAAC,CAClD;AACF;AAEA,SAASK,SAASd,IAAA,EAAc;EAC9B,OAAOD,2BAAA,CACLD,YAAA,CAAaE,IAAI,EAAEE,OAAA,CAAQ,OAAO,EAAE;EAAA;EACtC,EACGD,UAAA,CAAW,KAAK,IAAI,EACpBA,UAAA,CAAW,KAAK,GAAG;AACxB;AAEA,MAAMc,QAAA,GAAW,OAAOC,MAAA,KAAW;AACnC,MAAMC,aAAA,GAAgBF,QAAA,GAAWlB,MAAA,CAAO,IAAI;AAErC,SAASqB,eAAeC,WAAA,EAAqB;EAClD,OAAO,GAAGF,aAAa,WAAWH,QAAA,CAASK,WAAA,CAAYC,KAAA,CAAM,CAAC,CAAC,CAAC,GAAGxB,kBAAkB;AACvF;AAEO,SAASyB,kBAAkBF,WAAA,EAAqB;EACrD,OAAO,GAAGF,aAAa,WAAWH,QAAA,CAASK,WAAA,CAAYC,KAAA,CAAM,CAAC,CAAC,CAAC,GAAG5B,sBAAsB;AAC3F;AAEO,SAAS8B,cACdH,WAAA,EACAI,UAAA,GAAa9B,QAAA,EACb+B,SAAA,EACA;EACA,MAAMC,OAAA,GAAUF,UAAA,GAAa1B,MAAA,CAAO,IAAI;EACxC,MAAM6B,OAAA,GAAUC,OAAA,CAAQC,GAAA,CAAIC,QAAA,KAAa,gBAAgB,UAAU;EAEnE,MAAMC,cAAA,GAAiB,IAAIC,GAAA,CAAIZ,WAAA,EAAa,oBAAoB;EAEhE,MAAMa,UAAA,GAAalB,QAAA,CAASgB,cAAA,CAAeG,QAAA,CAASb,KAAA,CAAM,CAAC,CAAC;EAC5D,MAAMc,gBAAA,GAAmBV,SAAA,GAAY,YAAYA,SAAS,MAAM;EAEhE,OAAO,GAAGC,OAAO,GAAGC,OAAO,WAAWM,UAAU,GAAGE,gBAAgB,GAAGxC,iBAAiB;AACzF;AAEO,SAASyC,sBAAsBC,UAAA,EAAoB;EACxD,OAAO7B,2BAAA,CACL6B,UAAA,CACGlC,OAAA,CAAQP,uBAAA,EAAyB,EAAE,EACnCO,OAAA,CAAQ,sBAAsB,EAAE,EAChCA,OAAA,CAAQ,kBAAkB,EAAE,EAE5BA,OAAA,CAAQ,SAAUmC,KAAA,IAAWA,KAAA,KAAU,OAAO,MAAM,GAAI,CAC7D;AACF","ignoreList":[]}
@@ -1,8 +1,18 @@
1
1
  import { CSS_PRELOAD_JS_POSTFIX, isNative, LOADER_JS_POSTFIX, LOADER_JS_POSTFIX_REGEX, PRELOAD_JS_POSTFIX } from "../constants.native.js";
2
2
  import { getURL } from "../getURL.native.js";
3
3
  import { removeSearch } from "./removeSearch.native.js";
4
+ function encodeReservedFilenameChars(path) {
5
+ return path.replaceAll("=", "=3d").replace(/[<>:"|?*]/g, function (char) {
6
+ return `=${char.charCodeAt(0).toString(16).padStart(2, "0")}`;
7
+ });
8
+ }
9
+ function decodeReservedFilenameChars(path) {
10
+ return path.replace(/=([0-9a-f]{2})/g, function (_match, hexCode) {
11
+ return String.fromCharCode(Number.parseInt(hexCode, 16));
12
+ });
13
+ }
4
14
  function cleanUrl(path) {
5
- return removeSearch(path).replace(/\/$/, "").replaceAll("_", "__").replaceAll("/", "_");
15
+ return encodeReservedFilenameChars(removeSearch(path).replace(/\/$/, "")).replaceAll("_", "__").replaceAll("/", "_");
6
16
  }
7
17
  var isClient = typeof window !== "undefined";
8
18
  var clientSideURL = isClient ? getURL() : "";
@@ -23,9 +33,9 @@ function getLoaderPath(currentPath) {
23
33
  return `${baseURL}${devPath}/assets/${cleanedUrl}${cacheBustSegment}${LOADER_JS_POSTFIX}`;
24
34
  }
25
35
  function getPathFromLoaderPath(loaderPath) {
26
- return loaderPath.replace(LOADER_JS_POSTFIX_REGEX, "").replace(/^(\/_one)?\/assets/, "").replace(/_refetch_\d+_?/, "").replace(/__|_/g, function (match) {
36
+ return decodeReservedFilenameChars(loaderPath.replace(LOADER_JS_POSTFIX_REGEX, "").replace(/^(\/_one)?\/assets/, "").replace(/_refetch_\d+_?/, "").replace(/__|_/g, function (match) {
27
37
  return match === "__" ? "_" : "/";
28
- });
38
+ }));
29
39
  }
30
- export { getLoaderPath, getPathFromLoaderPath, getPreloadCSSPath, getPreloadPath };
40
+ export { decodeReservedFilenameChars, encodeReservedFilenameChars, getLoaderPath, getPathFromLoaderPath, getPreloadCSSPath, getPreloadPath };
31
41
  //# sourceMappingURL=cleanUrl.native.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["CSS_PRELOAD_JS_POSTFIX","isNative","LOADER_JS_POSTFIX","LOADER_JS_POSTFIX_REGEX","PRELOAD_JS_POSTFIX","getURL","removeSearch","cleanUrl","path","replace","replaceAll","isClient","window","clientSideURL","getPreloadPath","currentPath","slice","getPreloadCSSPath","getLoaderPath","includeUrl","arguments","length","cacheBust","baseURL","devPath","process","env","NODE_ENV","currentPathUrl","URL","cleanedUrl","pathname","cacheBustSegment","getPathFromLoaderPath","loaderPath","match"],"sources":["../../../src/utils/cleanUrl.ts"],"sourcesContent":[null],"mappings":"AAAA,SAAAA,sBAAA,EAAAC,QAAA,EAAAC,iBAAA,EAAAC,uBAAA,EAAAC,kBAAA;AAAA,SACEC,MAAA;AAAA,SACAC,YAAA;AAAA,SACAC,SAAAC,IAAA;EACA,OAAAF,YAAA,CAAAE,IAAA,EAAAC,OAAA,YAAAC,UAAA,YAAAA,UAAA;AAAA;AACA,IAAAC,QACK,UAAAC,MAAA;AACP,IAAAC,aAAS,GAAAF,QAAc,GAAAN,MAAA;AACvB,SAASS,eAAAC,WAAoB;EAE7B,OAAS,GAAAF,aAAuB,WAAAN,QAAA,CAAAQ,WAAA,CAAAC,KAAA,OAAAZ,kBAAA;AAC9B;AAIF,SAAAa,kBAAAF,WAAA;EAEA,OAAM,GAAAF,aAAkB,WAAWN,QAAA,CAAAQ,WAAA,CAAAC,KAAA,OAAAhB,sBAAA;AACnC;AAEO,SAASkB,cAAAH,WAAe;EAC7B,IAAAI,UAAU,GAAAC,SAAa,CAAAC,MAAA,GAAW,KAAAD,SAAS,QAAY,KAAQ,CAAC,GAAGA,SAAA,MAAAnB,QAAkB;IAAAqB,SAAA,GAAAF,SAAA,CAAAC,MAAA,OAAAD,SAAA;EACvF,IAAAG,OAAA,GAAAJ,UAAA,GAAAd,MAAA;EAEO,IAAAmB,OAAS,GAAAC,OAAA,CAAAC,GAAkB,CAAAC,QAAA,KAAqB;EACrD,IAAAC,cAAU,OAAaC,GAAA,CAAAd,WAAW,sBAA4B,CAAC;EACjE,IAAAe,UAAA,GAAAvB,QAAA,CAAAqB,cAAA,CAAAG,QAAA,CAAAf,KAAA;EAEO,IAAAgB,gBAAS,GACdV,SAAA,GACA,YAAaA,SAAA,GACb;EAEA,OAAM,GAAAC,OAAU,GAAAC,OAAA,WAAoBM,UAAI,GAAAE,gBAAA,GAAA9B,iBAAA;AACxC;AAEA,SAAM+B,qBAAqBA,CAAAC,UAAI;EAE/B,OAAMA,UAAA,CAAAzB,OAAa,CAAAN,uBAAwB,IAAS,EAAAM,OAAQ,2BAAAA,OAAA,uBAAAA,OAAA,oBAAA0B,KAAA;IAC5D,OAAMA,KAAA,YAAmB;EAEzB;AACF;AAEO,SACLjB,aACE,EAOJe,qBAAA,E","ignoreList":[]}
1
+ {"version":3,"names":["CSS_PRELOAD_JS_POSTFIX","isNative","LOADER_JS_POSTFIX","LOADER_JS_POSTFIX_REGEX","PRELOAD_JS_POSTFIX","getURL","removeSearch","encodeReservedFilenameChars","path","replaceAll","replace","char","charCodeAt","toString","padStart","decodeReservedFilenameChars","_match","hexCode","String","fromCharCode","Number","parseInt","cleanUrl","isClient","window","clientSideURL","getPreloadPath","currentPath","slice","getPreloadCSSPath","getLoaderPath","includeUrl","arguments","length","cacheBust","baseURL","devPath","process","env","NODE_ENV","currentPathUrl","URL","cleanedUrl","pathname","cacheBustSegment","getPathFromLoaderPath","loaderPath","match"],"sources":["../../../src/utils/cleanUrl.ts"],"sourcesContent":[null],"mappings":"AAAA,SAAAA,sBAAA,EAAAC,QAAA,EAAAC,iBAAA,EAAAC,uBAAA,EAAAC,kBAAA;AAAA,SACEC,MAAA;AAAA,SACAC,YAAA;AAAA,SACAC,4BAAAC,IAAA;EACA,OAAAA,IAAA,CAAAC,UAAA,aAAAC,OAAA,yBAAAC,IAAA;IACA,WAAAA,IAAA,CAAAC,UAAA,IAAAC,QAAA,KAAAC,QAAA;EAAA;AAEF;AACA,SAASC,2BAAoBA,CAAAP,IAAA;EAQtB,OAASA,IAAA,CAAAE,OAAA,kBAA4B,YAAcM,MAAA,EAAAC,OAAA;IACxD,OAAOC,MACJ,CAAAC,YAAgB,CAAAC,MAChB,CAAAC,QAAA,CAAAJ,OAAA;EAAA,EACC;AAAA;AAC8D,SAChEK,SAAAd,IAAA;EACJ,OAAAD,2BAAA,CAAAD,YAAA,CAAAE,IAAA,EAAAE,OAAA,aAAAD,UAAA,YAAAA,UAAA;AAEO;AACL,IAAAc,QAAO,GAAK,OAAAC,MAAA;AAAA,IAAQC,aAAA,GAAAF,QAAA,GAAAlB,MAAA;AAAA,SAAoBqB,cAAQA,CAAAC,WACvC;EACT,UAAAF,aAAA,WAAAH,QAAA,CAAAK,WAAA,CAAAC,KAAA,OAAAxB,kBAAA;AACF;AAEA,SAASyB,iBAAuBA,CAAAF,WAAA;EAC9B,OAAO,GAAAF,aAAA,WAAAH,QAAA,CAAAK,WAAA,CAAAC,KAAA,OAAA5B,sBAAA;AAAA;AAC+B,SAAA8B,cAAAH,WAAA;EACtC,IACGI,UAAW,GAAAC,SACX,CAAAC,MAAA,GAAW,KAAKD,SAAG,iBAAAA,SAAA,MAAA/B,QAAA;IAAAiC,SAAA,GAAAF,SAAA,CAAAC,MAAA,OAAAD,SAAA;EACxB,IAAAG,OAAA,GAAAJ,UAAA,GAAA1B,MAAA;EAEA,IAAM+B,OAAA,GAAAC,OAAW,CAAOC,GAAA,CAAAC,QAAW;EACnC,IAAMC,cAAA,GAAgB,IAAAC,GAAA,CAAAd,WAAkB,EAAI;EAErC,IAAAe,UAAS,GAAApB,QAAe,CAAAkB,cAAqB,CAAAG,QAAA,CAAAf,KAAA;EAClD,IAAAgB,gBAAU,GAAaV,SAAA,GAAW,YAASA,SAAY,MAAO,EAAE;EAClE,UAAAC,OAAA,GAAAC,OAAA,WAAAM,UAAA,GAAAE,gBAAA,GAAA1C,iBAAA;AAEO;AACL,SAAO2C,qBAAgBA,CAAAC,UAAW;EACpC,OAAA/B,2BAAA,CAAA+B,UAAA,CAAApC,OAAA,CAAAP,uBAAA,MAAAO,OAAA,2BAAAA,OAAA,uBAAAA,OAAA,oBAAAqC,KAAA;IAEO,OAASA,KAAA,SACd,YACA;EAGA;AACA;AAEA,SAEAhC,2BAAmB,EACnBR,2BAAyB,EAEzBuB,aAAU,EACZe,qBAAA,EAEOhB,iBAAS,EACdH,cAAO","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { getLoaderPath, getPathFromLoaderPath } from "./cleanUrl.mjs";
2
+ import { encodeReservedFilenameChars, getLoaderPath, getPathFromLoaderPath, getPreloadPath } from "./cleanUrl.mjs";
3
3
  function roundtrip(path) {
4
4
  const loaderPath = getLoaderPath(path, false);
5
5
  return getPathFromLoaderPath(loaderPath);
@@ -63,6 +63,43 @@ describe("getLoaderPath format", () => {
63
63
  expect(result).toContain("_refetch_12345_");
64
64
  });
65
65
  });
66
+ describe("NTFS-reserved characters in route-derived names", () => {
67
+ it("roundtrips a root dynamic route pattern", () => {
68
+ expect(roundtrip("/:param")).toBe("/:param");
69
+ });
70
+ it("roundtrips a nested dynamic route pattern", () => {
71
+ expect(roundtrip("/dashboard/:appId")).toBe("/dashboard/:appId");
72
+ });
73
+ it("roundtrips a catch-all pattern", () => {
74
+ expect(roundtrip("/*")).toBe("/*");
75
+ });
76
+ it("roundtrips hostile concrete param values (chars that survive URL parsing raw)", () => {
77
+ expect(roundtrip("/blog/a:b*c")).toBe("/blog/a:b*c");
78
+ });
79
+ it("emits filesystem-legal names for the full reserved set via preload paths", () => {
80
+ expect(getPreloadPath('/blog/a:b*c"d<e>f|g?h')).not.toMatch(/[<>:"|?*]/);
81
+ });
82
+ it("roundtrips literal equals signs (self-escape)", () => {
83
+ expect(roundtrip("/foo=bar")).toBe("/foo=bar");
84
+ });
85
+ it("roundtrips equals followed by hex-looking characters", () => {
86
+ expect(roundtrip("/x=3ay")).toBe("/x=3ay");
87
+ });
88
+ it("emits no NTFS-reserved characters in loader filenames", () => {
89
+ expect(getLoaderPath("/dashboard/:appId", false)).not.toMatch(/[<>:"|?*]/);
90
+ });
91
+ it("emits no NTFS-reserved characters in preload filenames", () => {
92
+ expect(getPreloadPath("/:param")).not.toMatch(/[<>:"|?*]/);
93
+ expect(getPreloadPath("/*")).not.toMatch(/[<>:"|?*]/);
94
+ });
95
+ it("encodeReservedFilenameChars is identity for clean paths", () => {
96
+ expect(encodeReservedFilenameChars("/blog/my-slug.html")).toBe("/blog/my-slug.html");
97
+ });
98
+ it("encodes the html artifact path for non-prerendered dynamic routes", () => {
99
+ expect(encodeReservedFilenameChars("/dashboard/:appId.html")).toBe("/dashboard/=3aappId.html");
100
+ expect(encodeReservedFilenameChars("/*.html")).toBe("/=2a.html");
101
+ });
102
+ });
66
103
  describe("getPathFromLoaderPath", () => {
67
104
  it("strips /_one/assets prefix", () => {
68
105
  expect(getPathFromLoaderPath("/_one/assets/docs_intro_999_vxrn_loader.js")).toBe("/docs/intro");
@@ -1 +1 @@
1
- {"version":3,"names":["describe","expect","it","getLoaderPath","getPathFromLoaderPath","roundtrip","path","loaderPath","toBe","result","toMatch","originalEnv","process","env","NODE_ENV","toContain"],"sources":["../../../src/utils/cleanUrl.test.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["describe","expect","it","encodeReservedFilenameChars","getLoaderPath","getPathFromLoaderPath","getPreloadPath","roundtrip","path","loaderPath","toBe","result","toMatch","originalEnv","process","env","NODE_ENV","toContain","not"],"sources":["../../../src/utils/cleanUrl.test.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { getLoaderPath, getPathFromLoaderPath } from "./cleanUrl.native.js";
2
+ import { encodeReservedFilenameChars, getLoaderPath, getPathFromLoaderPath, getPreloadPath } from "./cleanUrl.native.js";
3
3
  function roundtrip(path) {
4
4
  var loaderPath = getLoaderPath(path, false);
5
5
  return getPathFromLoaderPath(loaderPath);
@@ -63,6 +63,43 @@ describe("getLoaderPath format", function () {
63
63
  expect(result).toContain("_refetch_12345_");
64
64
  });
65
65
  });
66
+ describe("NTFS-reserved characters in route-derived names", function () {
67
+ it("roundtrips a root dynamic route pattern", function () {
68
+ expect(roundtrip("/:param")).toBe("/:param");
69
+ });
70
+ it("roundtrips a nested dynamic route pattern", function () {
71
+ expect(roundtrip("/dashboard/:appId")).toBe("/dashboard/:appId");
72
+ });
73
+ it("roundtrips a catch-all pattern", function () {
74
+ expect(roundtrip("/*")).toBe("/*");
75
+ });
76
+ it("roundtrips hostile concrete param values (chars that survive URL parsing raw)", function () {
77
+ expect(roundtrip("/blog/a:b*c")).toBe("/blog/a:b*c");
78
+ });
79
+ it("emits filesystem-legal names for the full reserved set via preload paths", function () {
80
+ expect(getPreloadPath('/blog/a:b*c"d<e>f|g?h')).not.toMatch(/[<>:"|?*]/);
81
+ });
82
+ it("roundtrips literal equals signs (self-escape)", function () {
83
+ expect(roundtrip("/foo=bar")).toBe("/foo=bar");
84
+ });
85
+ it("roundtrips equals followed by hex-looking characters", function () {
86
+ expect(roundtrip("/x=3ay")).toBe("/x=3ay");
87
+ });
88
+ it("emits no NTFS-reserved characters in loader filenames", function () {
89
+ expect(getLoaderPath("/dashboard/:appId", false)).not.toMatch(/[<>:"|?*]/);
90
+ });
91
+ it("emits no NTFS-reserved characters in preload filenames", function () {
92
+ expect(getPreloadPath("/:param")).not.toMatch(/[<>:"|?*]/);
93
+ expect(getPreloadPath("/*")).not.toMatch(/[<>:"|?*]/);
94
+ });
95
+ it("encodeReservedFilenameChars is identity for clean paths", function () {
96
+ expect(encodeReservedFilenameChars("/blog/my-slug.html")).toBe("/blog/my-slug.html");
97
+ });
98
+ it("encodes the html artifact path for non-prerendered dynamic routes", function () {
99
+ expect(encodeReservedFilenameChars("/dashboard/:appId.html")).toBe("/dashboard/=3aappId.html");
100
+ expect(encodeReservedFilenameChars("/*.html")).toBe("/=2a.html");
101
+ });
102
+ });
66
103
  describe("getPathFromLoaderPath", function () {
67
104
  it("strips /_one/assets prefix", function () {
68
105
  expect(getPathFromLoaderPath("/_one/assets/docs_intro_999_vxrn_loader.js")).toBe("/docs/intro");
@@ -1 +1 @@
1
- {"version":3,"names":["describe","expect","it","getLoaderPath","getPathFromLoaderPath","roundtrip","path","loaderPath","toBe","result","toMatch","originalEnv","process","env","NODE_ENV","toContain"],"sources":["../../../src/utils/cleanUrl.test.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,MAAA,EAAQC,EAAA,QAAU;AACrC,SAASC,aAAA,EAAeC,qBAAA,QAA6B;AAcrD,SAASC,UAAUC,IAAA,EAAsB;EACvC,IAAAC,UAAM,GAAAJ,aAAa,CAAAG,IAAc,OAAM;EACvC,OAAOF,qBAAA,CAAsBG,UAAU;AACzC;AAEAP,QAAA,CAAS,sBAAsB,YAAM;EACnCE,EAAA,CAAG,eAAe,YAAM;IACtBD,MAAA,CAAOI,SAAA,CAAU,uBAAuB,CAAC,EAAEG,IAAA,CAAK,uBAAuB;EACzE,CAAC;EAEDN,EAAA,CAAG,yCAAyC,YAAM;IAChDD,MAAA,CAAOI,SAAA,CAAU,yBAAyB,CAAC,EAAEG,IAAA,CAAK,yBAAyB;EAC7E,CAAC;EAEDN,EAAA,CAAG,0CAA0C,YAAM;IACjDD,MAAA,CAAOI,SAAA,CAAU,UAAU,CAAC,EAAEG,IAAA,CAAK,UAAU;EAC/C,CAAC;EAEDN,EAAA,CAAG,wCAAwC,YAAM;IAC/CD,MAAA,CAAOI,SAAA,CAAU,eAAe,CAAC,EAAEG,IAAA,CAAK,eAAe;EACzD,CAAC;EAEDN,EAAA,CAAG,sBAAsB,YAAM;IAC7BD,MAAA,CAAOI,SAAA,CAAU,wBAAwB,CAAC,EAAEG,IAAA,CAAK,wBAAwB;EAC3E,CAAC;EAEDN,EAAA,CAAG,aAAa,YAAM;IACpBD,MAAA,CAAOI,SAAA,CAAU,GAAG,CAAC,EAAEG,IAAA,CAAK,GAAG;EACjC,CAAC;EAEDN,EAAA,CAAG,kBAAkB,YAAM;IACzBD,MAAA,CAAOI,SAAA,CAAU,QAAQ,CAAC,EAAEG,IAAA,CAAK,QAAQ;EAC3C,CAAC;EAEDN,EAAA,CAAG,sCAAsC,YAAM;IAC7C,IAAAK,UAAM,GAAAJ,aAAa,sBAAc,OAAuB;IACxDF,MAAA,CAAOG,qBAAA,CAAsBG,UAAU,CAAC,EAAEC,IAAA,CAAK,aAAa;EAC9D,CAAC;EAEDN,EAAA,CAAG,8BAA8B,YAAM;IACrC,IAAAK,UAAM,GAAAJ,aAAa,sBAAc,OAAuB;IACxDF,MAAA,CAAOG,qBAAA,CAAsBG,UAAU,CAAC,EAAEC,IAAA,CAAK,aAAa;EAC9D,CAAC;EAEDN,EAAA,CAAG,4BAA4B,YAAM;IACnC,IAAAK,UAAM,GAAAJ,aAAa,eAAc,OAAgB;IACjDF,MAAA,CAAOG,qBAAA,CAAsBG,UAAU,CAAC,EAAEC,IAAA,CAAK,aAAa;EAC9D,CAAC;AACH,CAAC;AAEDR,QAAA,CAAS,wBAAwB,YAAM;EACrCE,EAAA,CAAG,4BAA4B,YAAM;IACnC,IAAAO,MAAM,GAAAN,aAAS,cAAc,OAAe;IAC5CF,MAAA,CAAOQ,MAAM,EAAEC,OAAA,CAAQ,aAAa;EACtC,CAAC;EAEDR,EAAA,CAAG,4BAA4B,YAAM;IACnC,IAAAO,MAAM,GAAAN,aAAS,cAAc,OAAe;IAC5CF,MAAA,CAAOQ,MAAM,EAAEC,OAAA,CAAQ,uBAAuB;EAChD,CAAC;EAEDR,EAAA,CAAG,qCAAqC,YAAM;IAC5C,IAAAS,WAAM,GAAAC,OAAc,CAAAC,GAAQ,CAAAC,QAAI;IAChCF,OAAA,CAAQC,GAAA,CAAIC,QAAA,GAAW;IACvB,IAAI;MACF,IAAAL,MAAM,GAAAN,aAAS,cAAc,OAAe;MAC5CF,MAAA,CAAOQ,MAAM,EAAEC,OAAA,CAAQ,mBAAmB;IAC5C,UAAE;MACAE,OAAA,CAAQC,GAAA,CAAIC,QAAA,GAAWH,WAAA;IACzB;EACF,CAAC;EAEDT,EAAA,CAAG,+BAA+B,YAAM;IACtC,IAAAO,MAAM,GAAAN,aAAS,cAAc,OAAe,SAAO;IACnDF,MAAA,CAAOQ,MAAM,EAAEM,SAAA,CAAU,iBAAiB;EAC5C,CAAC;AACH,CAAC;AAEDf,QAAA,CAAS,yBAAyB,YAAM;EACtCE,EAAA,CAAG,8BAA8B,YAAM;IACrCD,MAAA,CAAOG,qBAAA,CAAsB,4CAA4C,CAAC,EAAEI,IAAA;EAAA;EAC1EN,EACF;IACDD,MAAA,CAAAG,qBAAA,2CAAAI,IAAA;EAED;EACEN,EAAA,4BAAO,EAAsB;IAA0CD,MACrE,CAAAG,qBAAA,0DAAAI,IAAA;EAAA,EACF;EACFN,EAAC;IAEDD,MAAG,CAAAG,qBAAA,2CAAmC,GAAAI,IAAA;EACpC;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["describe","expect","it","encodeReservedFilenameChars","getLoaderPath","getPathFromLoaderPath","getPreloadPath","roundtrip","path","loaderPath","toBe","result","toMatch","originalEnv","process","env","NODE_ENV","toContain","not"],"sources":["../../../src/utils/cleanUrl.test.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one",
3
- "version": "1.21.1",
3
+ "version": "1.21.2",
4
4
  "license": "BSD-3-Clause",
5
5
  "sideEffects": [
6
6
  "setup.mjs",
@@ -181,18 +181,18 @@
181
181
  "@cloudflare/vite-plugin": "^1.33.1",
182
182
  "@swc/core": "^1.14.0",
183
183
  "@ungap/structured-clone": "^1.2.0",
184
- "@vxrn/color-scheme": "1.21.1",
185
- "@vxrn/compiler": "1.21.1",
186
- "@vxrn/resolve": "1.21.1",
187
- "@vxrn/tslib-lite": "1.21.1",
188
- "@vxrn/use-isomorphic-layout-effect": "1.21.1",
189
- "@vxrn/vite-plugin-metro": "1.21.1",
184
+ "@vxrn/color-scheme": "1.21.2",
185
+ "@vxrn/compiler": "1.21.2",
186
+ "@vxrn/resolve": "1.21.2",
187
+ "@vxrn/tslib-lite": "1.21.2",
188
+ "@vxrn/use-isomorphic-layout-effect": "1.21.2",
189
+ "@vxrn/vite-plugin-metro": "1.21.2",
190
190
  "babel-dead-code-elimination": "1.0.10",
191
191
  "babel-plugin-module-resolver": "^5.0.2",
192
192
  "babel-preset-expo": "~55.0.0",
193
193
  "citty": "^0.1.6",
194
194
  "core-js": "^3.38.1",
195
- "create-vxrn": "1.21.1",
195
+ "create-vxrn": "1.21.2",
196
196
  "escape-string-regexp": "^5.0.0",
197
197
  "expo-linking": "~55.0.7",
198
198
  "expo-modules-core": "~55.0.16",
@@ -212,7 +212,7 @@
212
212
  "tsconfig-paths": "^4",
213
213
  "use-latest-callback": "^0.2.3",
214
214
  "vite": "^8.0.13",
215
- "vxrn": "1.21.1",
215
+ "vxrn": "1.21.2",
216
216
  "ws": "^8.21.0",
217
217
  "xxhashjs": "^0.2.2"
218
218
  },
package/src/cli/build.ts CHANGED
@@ -1251,7 +1251,7 @@ export async function build(args: {
1251
1251
 
1252
1252
  // once done building static we can move it to client dir:
1253
1253
  await moveAllFiles(staticDir, clientDir)
1254
- await FSExtra.rm(staticDir, { force: true, recursive: true })
1254
+ await FSExtra.remove(staticDir)
1255
1255
 
1256
1256
  // write out the static paths (pathname => html) for the server
1257
1257
  const routeMap: Record<string, string> = {}
@@ -4,7 +4,12 @@ import { normalizePath } from 'vite'
4
4
  import * as constants from '../constants'
5
5
  import { LOADER_JS_POSTFIX_UNCACHED } from '../constants'
6
6
  import type { LoaderProps } from '../types'
7
- import { getLoaderPath, getPreloadCSSPath, getPreloadPath } from '../utils/cleanUrl'
7
+ import {
8
+ encodeReservedFilenameChars,
9
+ getLoaderPath,
10
+ getPreloadCSSPath,
11
+ getPreloadPath,
12
+ } from '../utils/cleanUrl'
8
13
  import { isResponse } from '../utils/isResponse'
9
14
  import { toAbsolute, toAbsoluteUrl } from '../utils/toAbsolute'
10
15
  import { replaceLoader } from '../vite/replaceLoader'
@@ -64,7 +69,12 @@ export async function buildPage(
64
69
  const render = await getRender(serverEntry)
65
70
  recordTiming('getRender', performance.now() - t0)
66
71
 
67
- const htmlPath = `${path.endsWith('/') ? `${removeTrailingSlash(path)}/index` : path}.html`
72
+ // encode NTFS-reserved characters (`:` from `/:param` patterns, `*` from
73
+ // catch-alls, hostile param values) so the artifact is writable on Windows;
74
+ // routeMap stores this same string, so serve-side lookups stay consistent
75
+ const htmlPath = encodeReservedFilenameChars(
76
+ `${path.endsWith('/') ? `${removeTrailingSlash(path)}/index` : path}.html`
77
+ )
68
78
  // forward-slash for cross-platform manifest hygiene (matches serverJsPath)
69
79
  const clientJsPath = clientManifestEntry
70
80
  ? normalizePath(join(clientDir, clientManifestEntry.file))
package/src/daemon/ipc.ts CHANGED
@@ -4,6 +4,7 @@ import * as net from 'node:net'
4
4
  import * as fs from 'node:fs'
5
5
  import * as path from 'node:path'
6
6
  import * as os from 'node:os'
7
+ import { createHash } from 'node:crypto'
7
8
  import type { IPCMessage, IPCResponse, DaemonState } from './types'
8
9
  import {
9
10
  registerServer,
@@ -18,9 +19,32 @@ import {
18
19
  } from './registry'
19
20
 
20
21
  const SOCKET_DIR = path.join(os.homedir(), '.one')
21
- const SOCKET_PATH = path.join(SOCKET_DIR, 'daemon.sock')
22
22
  const SERVERS_FILE = path.join(SOCKET_DIR, 'servers.json')
23
23
 
24
+ /**
25
+ * Resolve the daemon IPC endpoint for the current platform.
26
+ *
27
+ * Node's `net` implements local IPC as a Unix domain socket on POSIX and a named
28
+ * pipe on Windows — the same `listen(path)`/`connect(path)` API, but on Windows
29
+ * the name must live under `\\.\pipe\` (a flat, machine-global namespace) rather
30
+ * than the filesystem. So we select each platform's native primitive: an AF_UNIX
31
+ * socket file inside the owner-only `~/.one` dir on POSIX, a named pipe on
32
+ * Windows. The Windows name is a deterministic per-user hash so the daemon and
33
+ * the CLI derive the same pipe independently, and so distinct users on one
34
+ * machine don't collide in the shared pipe namespace.
35
+ *
36
+ * @see https://nodejs.org/api/net.html#identifying-paths-for-ipc-connections
37
+ */
38
+ function resolveSocketPath(): string {
39
+ if (process.platform === 'win32') {
40
+ const scope = createHash('sha256').update(SOCKET_DIR).digest('hex').slice(0, 8)
41
+ return path.win32.join(String.raw`\\.\pipe`, `one-daemon-${scope}`)
42
+ }
43
+ return path.join(SOCKET_DIR, 'daemon.sock')
44
+ }
45
+
46
+ const SOCKET_PATH = resolveSocketPath()
47
+
24
48
  export function getSocketPath(): string {
25
49
  return SOCKET_PATH
26
50
  }
@@ -124,9 +148,24 @@ export function createIPCServer(
124
148
  })
125
149
  })
126
150
 
151
+ // surface a bind failure as an actionable message rather than an uncaught
152
+ // 'error' event that crashes the process (e.g. another daemon already owns the
153
+ // socket/pipe).
154
+ server.on('error', (err: NodeJS.ErrnoException) => {
155
+ if (err.code === 'EADDRINUSE') {
156
+ console.error(`[daemon] Another daemon is already listening at ${SOCKET_PATH}`)
157
+ } else {
158
+ console.error('[daemon] IPC server error:', err.message)
159
+ }
160
+ process.exit(1)
161
+ })
162
+
127
163
  server.listen(SOCKET_PATH, () => {
128
- // owner-only permissions for security
129
- fs.chmodSync(SOCKET_PATH, 0o600)
164
+ // owner-only permissions on POSIX; the Windows named pipe is not a filesystem
165
+ // entry, so chmod does not apply there (and would throw).
166
+ if (process.platform !== 'win32') {
167
+ fs.chmodSync(SOCKET_PATH, 0o600)
168
+ }
130
169
  })
131
170
 
132
171
  return server
@@ -205,7 +244,10 @@ function handleMessage(
205
244
 
206
245
  export async function isDaemonRunning(): Promise<boolean> {
207
246
  return new Promise((resolve) => {
208
- if (!fs.existsSync(SOCKET_PATH)) {
247
+ // On POSIX a stale socket file may linger, so a cheap existence check avoids a
248
+ // needless connect. On Windows the endpoint is a named pipe — not a filesystem
249
+ // entry — so existsSync is always false there; probe by connecting instead.
250
+ if (process.platform !== 'win32' && !fs.existsSync(SOCKET_PATH)) {
209
251
  resolve(false)
210
252
  return
211
253
  }
@@ -0,0 +1,55 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest'
2
+ import { hmrImport } from './hmrImport.native'
3
+
4
+ const realRuntime = (globalThis as any).__rolldown_runtime__
5
+ afterEach(() => {
6
+ ;(globalThis as any).__rolldown_runtime__ = realRuntime
7
+ vi.restoreAllMocks()
8
+ })
9
+ const setRuntime = (runtime: unknown) => {
10
+ ;(globalThis as any).__rolldown_runtime__ = runtime
11
+ }
12
+
13
+ describe('hmrImport (native)', () => {
14
+ it('rejects when no runtime is present', async () => {
15
+ setRuntime(undefined)
16
+ await expect(hmrImport('foo.tsx')).rejects.toThrow(
17
+ 'HMR import not supported on native'
18
+ )
19
+ })
20
+
21
+ it('rejects when loadExports is missing', async () => {
22
+ setRuntime({})
23
+ await expect(hmrImport('foo.tsx')).rejects.toThrow(
24
+ 'HMR import not supported on native'
25
+ )
26
+ })
27
+
28
+ it('resolves with the runtime exports and strips ./ and / prefixes', async () => {
29
+ const exports = { default: () => null }
30
+ const loadExports = vi.fn(() => exports)
31
+ setRuntime({ loadExports })
32
+
33
+ await expect(hmrImport('./foo.tsx')).resolves.toBe(exports)
34
+ await expect(hmrImport('/foo.tsx')).resolves.toBe(exports)
35
+ await expect(hmrImport('foo.tsx')).resolves.toBe(exports)
36
+ expect(loadExports).toHaveBeenNthCalledWith(1, 'foo.tsx')
37
+ expect(loadExports).toHaveBeenNthCalledWith(2, 'foo.tsx')
38
+ expect(loadExports).toHaveBeenNthCalledWith(3, 'foo.tsx')
39
+ })
40
+
41
+ it('rejects when loadExports returns null', async () => {
42
+ setRuntime({ loadExports: () => null })
43
+ await expect(hmrImport('foo.tsx')).rejects.toThrow('no exports for foo.tsx')
44
+ })
45
+
46
+ it('rejects when loadExports throws', async () => {
47
+ const boom = new Error('boom')
48
+ setRuntime({
49
+ loadExports: () => {
50
+ throw boom
51
+ },
52
+ })
53
+ await expect(hmrImport('foo.tsx')).rejects.toBe(boom)
54
+ })
55
+ })
@@ -1,8 +1,28 @@
1
1
  /**
2
- * Native stub: HMR cache-busting is not supported on native.
3
- * This avoids the dynamic import() syntax that Hermes cannot parse.
2
+ * native HMR re-import
3
+ *
4
+ * vxrn's native dev runtime re-registers the edited module into
5
+ * `globalThis.__rolldown_runtime__` before One evicts its route cache, so the
6
+ * fresh exports can be pulled straight from the runtime without dynamic `import()`
7
+ * (which Hermes cannot parse). Rejects when the runtime is unavailable so a
8
+ * broken development runtime is visible instead of serving a stale route.
4
9
  */
5
- export function hmrImport(_path: string): Promise<any> {
6
- // Return a rejected promise to fall back to normal import
7
- return Promise.reject(new Error('HMR import not supported on native'))
10
+ export function hmrImport(path: string): Promise<any> {
11
+ const runtime = (
12
+ globalThis as typeof globalThis & {
13
+ __rolldown_runtime__?: { loadExports(id: string): unknown }
14
+ }
15
+ ).__rolldown_runtime__
16
+ if (!runtime || typeof runtime.loadExports !== 'function') {
17
+ return Promise.reject(new Error('HMR import not supported on native'))
18
+ }
19
+ // route paths arrive as `./foo.tsx` / `/foo.tsx`; rolldown ids are bare (`foo.tsx`)
20
+ const id = path.replace(/^\.\//, '').replace(/^\//, '')
21
+ return Promise.resolve().then(() => {
22
+ const mod = runtime.loadExports(id)
23
+ if (mod == null) {
24
+ throw new Error(`no exports for ${id}`)
25
+ }
26
+ return mod
27
+ })
8
28
  }