@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bd6e11bc

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 (285) hide show
  1. package/README.md +196 -43
  2. package/dist/bin/rango.js +277 -99
  3. package/dist/testing/vitest.js +48 -0
  4. package/dist/vite/index.js +2779 -1064
  5. package/dist/vite/index.js.bak +5448 -0
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +57 -11
  8. package/skills/breadcrumbs/SKILL.md +3 -1
  9. package/skills/bundle-analysis/SKILL.md +159 -0
  10. package/skills/cache-guide/SKILL.md +243 -21
  11. package/skills/caching/SKILL.md +155 -6
  12. package/skills/composability/SKILL.md +27 -2
  13. package/skills/document-cache/SKILL.md +78 -55
  14. package/skills/handler-use/SKILL.md +364 -0
  15. package/skills/hooks/SKILL.md +229 -20
  16. package/skills/host-router/SKILL.md +45 -20
  17. package/skills/i18n/SKILL.md +276 -0
  18. package/skills/intercept/SKILL.md +46 -4
  19. package/skills/layout/SKILL.md +28 -7
  20. package/skills/links/SKILL.md +249 -17
  21. package/skills/loader/SKILL.md +273 -53
  22. package/skills/middleware/SKILL.md +49 -12
  23. package/skills/migrate-nextjs/SKILL.md +562 -0
  24. package/skills/migrate-react-router/SKILL.md +769 -0
  25. package/skills/mime-routes/SKILL.md +27 -0
  26. package/skills/observability/SKILL.md +137 -0
  27. package/skills/parallel/SKILL.md +197 -6
  28. package/skills/prerender/SKILL.md +123 -100
  29. package/skills/rango/SKILL.md +242 -22
  30. package/skills/react-compiler/SKILL.md +168 -0
  31. package/skills/response-routes/SKILL.md +66 -9
  32. package/skills/route/SKILL.md +88 -4
  33. package/skills/router-setup/SKILL.md +90 -5
  34. package/skills/server-actions/SKILL.md +751 -0
  35. package/skills/streams-and-websockets/SKILL.md +283 -0
  36. package/skills/testing/SKILL.md +716 -0
  37. package/skills/typesafety/SKILL.md +329 -27
  38. package/skills/use-cache/SKILL.md +34 -5
  39. package/skills/view-transitions/SKILL.md +294 -0
  40. package/src/__augment-tests__/augment.ts +81 -0
  41. package/src/__augment-tests__/augmented.check.ts +117 -0
  42. package/src/__internal.ts +1 -1
  43. package/src/browser/action-coordinator.ts +53 -36
  44. package/src/browser/app-shell.ts +52 -0
  45. package/src/browser/app-version.ts +14 -0
  46. package/src/browser/event-controller.ts +91 -70
  47. package/src/browser/history-state.ts +21 -0
  48. package/src/browser/index.ts +3 -3
  49. package/src/browser/navigation-bridge.ts +102 -16
  50. package/src/browser/navigation-client.ts +164 -59
  51. package/src/browser/navigation-store.ts +75 -17
  52. package/src/browser/navigation-transaction.ts +21 -37
  53. package/src/browser/partial-update.ts +139 -38
  54. package/src/browser/prefetch/cache.ts +175 -15
  55. package/src/browser/prefetch/fetch.ts +180 -33
  56. package/src/browser/prefetch/queue.ts +123 -20
  57. package/src/browser/prefetch/resource-ready.ts +77 -0
  58. package/src/browser/rango-state.ts +53 -13
  59. package/src/browser/react/Link.tsx +81 -9
  60. package/src/browser/react/NavigationProvider.tsx +110 -33
  61. package/src/browser/react/context.ts +7 -2
  62. package/src/browser/react/filter-segment-order.ts +51 -7
  63. package/src/browser/react/index.ts +3 -0
  64. package/src/browser/react/location-state-shared.ts +175 -4
  65. package/src/browser/react/location-state.ts +39 -13
  66. package/src/browser/react/use-handle.ts +23 -64
  67. package/src/browser/react/use-navigation.ts +22 -2
  68. package/src/browser/react/use-params.ts +20 -8
  69. package/src/browser/react/use-reverse.ts +106 -0
  70. package/src/browser/react/use-router.ts +43 -10
  71. package/src/browser/react/use-segments.ts +11 -8
  72. package/src/browser/response-adapter.ts +25 -0
  73. package/src/browser/rsc-router.tsx +191 -74
  74. package/src/browser/scroll-restoration.ts +41 -14
  75. package/src/browser/segment-reconciler.ts +36 -9
  76. package/src/browser/segment-structure-assert.ts +2 -2
  77. package/src/browser/server-action-bridge.ts +31 -36
  78. package/src/browser/types.ts +57 -5
  79. package/src/build/collect-fallback-refs.ts +107 -0
  80. package/src/build/generate-manifest.ts +65 -40
  81. package/src/build/generate-route-types.ts +5 -0
  82. package/src/build/index.ts +2 -0
  83. package/src/build/route-trie.ts +52 -25
  84. package/src/build/route-types/codegen.ts +4 -4
  85. package/src/build/route-types/include-resolution.ts +9 -2
  86. package/src/build/route-types/per-module-writer.ts +7 -4
  87. package/src/build/route-types/router-processing.ts +278 -88
  88. package/src/build/route-types/scan-filter.ts +9 -2
  89. package/src/build/route-types/source-scan.ts +118 -0
  90. package/src/build/runtime-discovery.ts +9 -20
  91. package/src/cache/cache-runtime.ts +15 -11
  92. package/src/cache/cache-scope.ts +76 -49
  93. package/src/cache/cf/cf-cache-store.ts +501 -18
  94. package/src/cache/cf/index.ts +5 -1
  95. package/src/cache/document-cache.ts +17 -7
  96. package/src/cache/index.ts +1 -0
  97. package/src/cache/taint.ts +55 -0
  98. package/src/client.rsc.tsx +3 -0
  99. package/src/client.tsx +94 -238
  100. package/src/context-var.ts +72 -2
  101. package/src/debug.ts +2 -2
  102. package/src/decode-loader-results.ts +36 -0
  103. package/src/errors.ts +30 -1
  104. package/src/handle.ts +65 -12
  105. package/src/host/index.ts +2 -2
  106. package/src/host/router.ts +129 -57
  107. package/src/host/types.ts +31 -2
  108. package/src/host/utils.ts +1 -1
  109. package/src/href-client.ts +140 -20
  110. package/src/index.rsc.ts +12 -5
  111. package/src/index.ts +61 -11
  112. package/src/loader-store.ts +500 -0
  113. package/src/loader.rsc.ts +2 -5
  114. package/src/loader.ts +3 -10
  115. package/src/missing-id-error.ts +68 -0
  116. package/src/outlet-context.ts +1 -1
  117. package/src/prerender/store.ts +5 -4
  118. package/src/prerender.ts +141 -80
  119. package/src/response-utils.ts +37 -0
  120. package/src/reverse.ts +65 -15
  121. package/src/route-content-wrapper.tsx +6 -28
  122. package/src/route-definition/dsl-helpers.ts +435 -260
  123. package/src/route-definition/helper-factories.ts +29 -139
  124. package/src/route-definition/helpers-types.ts +110 -34
  125. package/src/route-definition/index.ts +3 -0
  126. package/src/route-definition/redirect.ts +11 -3
  127. package/src/route-definition/resolve-handler-use.ts +155 -0
  128. package/src/route-definition/use-item-types.ts +32 -0
  129. package/src/route-map-builder.ts +7 -1
  130. package/src/route-types.ts +37 -41
  131. package/src/router/basename.ts +14 -0
  132. package/src/router/content-negotiation.ts +113 -1
  133. package/src/router/error-handling.ts +1 -1
  134. package/src/router/find-match.ts +4 -2
  135. package/src/router/handler-context.ts +77 -38
  136. package/src/router/intercept-resolution.ts +15 -22
  137. package/src/router/lazy-includes.ts +12 -9
  138. package/src/router/loader-resolution.ts +174 -22
  139. package/src/router/logging.ts +5 -2
  140. package/src/router/manifest.ts +31 -16
  141. package/src/router/match-api.ts +128 -192
  142. package/src/router/match-handlers.ts +63 -20
  143. package/src/router/match-middleware/background-revalidation.ts +30 -2
  144. package/src/router/match-middleware/cache-lookup.ts +136 -106
  145. package/src/router/match-middleware/cache-store.ts +54 -10
  146. package/src/router/match-middleware/intercept-resolution.ts +9 -7
  147. package/src/router/match-middleware/segment-resolution.ts +61 -5
  148. package/src/router/match-result.ts +125 -10
  149. package/src/router/metrics.ts +7 -2
  150. package/src/router/middleware-types.ts +21 -34
  151. package/src/router/middleware.ts +103 -90
  152. package/src/router/navigation-snapshot.ts +182 -0
  153. package/src/router/pattern-matching.ts +101 -17
  154. package/src/router/prerender-match.ts +110 -10
  155. package/src/router/preview-match.ts +32 -102
  156. package/src/router/request-classification.ts +286 -0
  157. package/src/router/revalidation.ts +58 -2
  158. package/src/router/route-snapshot.ts +245 -0
  159. package/src/router/router-context.ts +6 -1
  160. package/src/router/router-interfaces.ts +77 -28
  161. package/src/router/router-options.ts +76 -11
  162. package/src/router/router-registry.ts +2 -5
  163. package/src/router/segment-resolution/fresh.ts +223 -24
  164. package/src/router/segment-resolution/helpers.ts +29 -24
  165. package/src/router/segment-resolution/loader-cache.ts +1 -0
  166. package/src/router/segment-resolution/revalidation.ts +466 -285
  167. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  168. package/src/router/segment-wrappers.ts +2 -0
  169. package/src/router/substitute-pattern-params.ts +56 -0
  170. package/src/router/telemetry.ts +99 -0
  171. package/src/router/trie-matching.ts +18 -13
  172. package/src/router/types.ts +9 -0
  173. package/src/router/url-params.ts +49 -0
  174. package/src/router.ts +91 -23
  175. package/src/rsc/handler-context.ts +2 -2
  176. package/src/rsc/handler.ts +440 -381
  177. package/src/rsc/helpers.ts +91 -43
  178. package/src/rsc/index.ts +1 -1
  179. package/src/rsc/loader-fetch.ts +23 -3
  180. package/src/rsc/manifest-init.ts +5 -1
  181. package/src/rsc/origin-guard.ts +28 -10
  182. package/src/rsc/progressive-enhancement.ts +18 -2
  183. package/src/rsc/response-route-handler.ts +46 -53
  184. package/src/rsc/rsc-rendering.ts +41 -48
  185. package/src/rsc/runtime-warnings.ts +9 -10
  186. package/src/rsc/server-action.ts +25 -37
  187. package/src/rsc/ssr-setup.ts +18 -2
  188. package/src/rsc/types.ts +17 -3
  189. package/src/search-params.ts +4 -4
  190. package/src/segment-content-promise.ts +67 -0
  191. package/src/segment-loader-promise.ts +122 -0
  192. package/src/segment-system.tsx +219 -67
  193. package/src/serialize.ts +243 -0
  194. package/src/server/context.ts +277 -61
  195. package/src/server/cookie-store.ts +28 -4
  196. package/src/server/handle-store.ts +19 -0
  197. package/src/server/loader-registry.ts +9 -8
  198. package/src/server/request-context.ts +204 -60
  199. package/src/ssr/index.tsx +9 -1
  200. package/src/static-handler.ts +19 -7
  201. package/src/testing/cache-status.ts +166 -0
  202. package/src/testing/collect-handle.ts +63 -0
  203. package/src/testing/dispatch.ts +440 -0
  204. package/src/testing/dom.entry.ts +22 -0
  205. package/src/testing/e2e/fixture.ts +154 -0
  206. package/src/testing/e2e/index.ts +149 -0
  207. package/src/testing/e2e/matchers.ts +51 -0
  208. package/src/testing/e2e/page-helpers.ts +272 -0
  209. package/src/testing/e2e/parity.ts +306 -0
  210. package/src/testing/e2e/server.ts +183 -0
  211. package/src/testing/flight-matchers.ts +104 -0
  212. package/src/testing/flight-runtime.d.ts +21 -0
  213. package/src/testing/flight.entry.ts +22 -0
  214. package/src/testing/flight.ts +182 -0
  215. package/src/testing/generated-routes.ts +223 -0
  216. package/src/testing/index.ts +106 -0
  217. package/src/testing/internal/context.ts +255 -0
  218. package/src/testing/render-route.tsx +565 -0
  219. package/src/testing/run-loader.ts +296 -0
  220. package/src/testing/run-middleware.ts +179 -0
  221. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  222. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  223. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  224. package/src/testing/vitest-stubs/version.ts +5 -0
  225. package/src/testing/vitest.ts +183 -0
  226. package/src/types/cache-types.ts +4 -4
  227. package/src/types/global-namespace.ts +39 -26
  228. package/src/types/handler-context.ts +194 -72
  229. package/src/types/index.ts +1 -0
  230. package/src/types/loader-types.ts +41 -15
  231. package/src/types/request-scope.ts +126 -0
  232. package/src/types/route-entry.ts +19 -1
  233. package/src/types/segments.ts +37 -1
  234. package/src/urls/include-helper.ts +34 -67
  235. package/src/urls/index.ts +0 -3
  236. package/src/urls/path-helper-types.ts +50 -9
  237. package/src/urls/path-helper.ts +63 -63
  238. package/src/urls/pattern-types.ts +48 -19
  239. package/src/urls/response-types.ts +25 -22
  240. package/src/urls/type-extraction.ts +26 -116
  241. package/src/urls/urls-function.ts +1 -5
  242. package/src/use-loader.tsx +487 -44
  243. package/src/vite/debug.ts +185 -0
  244. package/src/vite/discovery/bundle-postprocess.ts +34 -37
  245. package/src/vite/discovery/discover-routers.ts +105 -51
  246. package/src/vite/discovery/discovery-errors.ts +194 -0
  247. package/src/vite/discovery/gate-state.ts +171 -0
  248. package/src/vite/discovery/prerender-collection.ts +188 -93
  249. package/src/vite/discovery/route-types-writer.ts +40 -84
  250. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  251. package/src/vite/discovery/state.ts +46 -6
  252. package/src/vite/discovery/virtual-module-codegen.ts +13 -23
  253. package/src/vite/index.ts +6 -0
  254. package/src/vite/plugin-types.ts +111 -72
  255. package/src/vite/plugins/cjs-to-esm.ts +8 -7
  256. package/src/vite/plugins/client-ref-dedup.ts +16 -0
  257. package/src/vite/plugins/client-ref-hashing.ts +28 -5
  258. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  259. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  260. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  261. package/src/vite/plugins/expose-action-id.ts +55 -33
  262. package/src/vite/plugins/expose-id-utils.ts +24 -8
  263. package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
  264. package/src/vite/plugins/expose-ids/handler-transform.ts +12 -35
  265. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
  266. package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
  267. package/src/vite/plugins/expose-internal-ids.ts +544 -317
  268. package/src/vite/plugins/performance-tracks.ts +92 -0
  269. package/src/vite/plugins/refresh-cmd.ts +88 -26
  270. package/src/vite/plugins/use-cache-transform.ts +65 -50
  271. package/src/vite/plugins/version-injector.ts +39 -23
  272. package/src/vite/plugins/version-plugin.ts +72 -3
  273. package/src/vite/plugins/virtual-entries.ts +2 -2
  274. package/src/vite/rango.ts +265 -226
  275. package/src/vite/router-discovery.ts +920 -137
  276. package/src/vite/utils/ast-handler-extract.ts +15 -15
  277. package/src/vite/utils/banner.ts +4 -4
  278. package/src/vite/utils/bundle-analysis.ts +4 -2
  279. package/src/vite/utils/client-chunks.ts +190 -0
  280. package/src/vite/utils/forward-user-plugins.ts +193 -0
  281. package/src/vite/utils/manifest-utils.ts +21 -5
  282. package/src/vite/utils/package-resolution.ts +41 -1
  283. package/src/vite/utils/prerender-utils.ts +38 -5
  284. package/src/vite/utils/shared-utils.ts +109 -27
  285. package/src/browser/action-response-classifier.ts +0 -99
package/dist/bin/rango.js CHANGED
@@ -139,7 +139,7 @@ function generatePerModuleTypesSource(routes) {
139
139
  const valid = routes.filter(({ name }) => {
140
140
  if (!name || /["'\\`\n\r]/.test(name)) {
141
141
  console.warn(
142
- `[rsc-router] Skipping route with invalid name: ${JSON.stringify(name)}`
142
+ `[rango] Skipping route with invalid name: ${JSON.stringify(name)}`
143
143
  );
144
144
  return false;
145
145
  }
@@ -149,7 +149,7 @@ function generatePerModuleTypesSource(routes) {
149
149
  for (const { name, pattern, params, search } of valid) {
150
150
  if (deduped.has(name)) {
151
151
  console.warn(
152
- `[rsc-router] Duplicate route name "${name}" \u2014 keeping first definition`
152
+ `[rango] Duplicate route name "${name}" \u2014 keeping first definition`
153
153
  );
154
154
  continue;
155
155
  }
@@ -186,7 +186,7 @@ ${objectBody}
186
186
  } as const;
187
187
 
188
188
  declare global {
189
- namespace RSCRouter {
189
+ namespace Rango {
190
190
  interface GeneratedRouteMap extends Readonly<typeof NamedRoutes> {}
191
191
  }
192
192
  }
@@ -211,14 +211,15 @@ function findTsFiles(dir, filter) {
211
211
  entries = readdirSync(dir, { withFileTypes: true });
212
212
  } catch (err) {
213
213
  console.warn(
214
- `[rsc-router] Failed to scan directory ${dir}: ${err.message}`
214
+ `[rango] Failed to scan directory ${dir}: ${err.message}`
215
215
  );
216
216
  return results;
217
217
  }
218
218
  for (const entry of entries) {
219
219
  const fullPath = join(dir, entry.name);
220
220
  if (entry.isDirectory()) {
221
- if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
221
+ if (entry.name === "node_modules" || entry.name.startsWith(".") || entry.name === "dist" || entry.name === "build" || entry.name === "coverage")
222
+ continue;
222
223
  results.push(...findTsFiles(fullPath, filter));
223
224
  } else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".tsx") || entry.name.endsWith(".js") || entry.name.endsWith(".jsx")) && !entry.name.includes(".gen.")) {
224
225
  if (filter && !filter(fullPath)) continue;
@@ -450,12 +451,12 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
450
451
  }
451
452
  return routeMap;
452
453
  }
453
- function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut) {
454
+ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock) {
454
455
  visited = visited ?? /* @__PURE__ */ new Set();
455
456
  const realPath = resolve(filePath);
456
457
  const key = variableName ? `${realPath}:${variableName}` : realPath;
457
458
  if (visited.has(key)) {
458
- console.warn(`[rsc-router] Circular include detected, skipping: ${key}`);
459
+ console.warn(`[rango] Circular include detected, skipping: ${key}`);
459
460
  return { routes: {}, searchSchemas: {} };
460
461
  }
461
462
  visited.add(key);
@@ -466,7 +467,9 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
466
467
  return { routes: {}, searchSchemas: {} };
467
468
  }
468
469
  let block;
469
- if (variableName) {
470
+ if (inlineBlock) {
471
+ block = inlineBlock;
472
+ } else if (variableName) {
470
473
  const extracted = extractUrlsBlockForVariable(source, variableName);
471
474
  if (!extracted) return { routes: {}, searchSchemas: {} };
472
475
  block = extracted;
@@ -540,12 +543,12 @@ function writePerModuleRouteTypesForFile(filePath) {
540
543
  } else {
541
544
  routes = extractRoutesFromSource(source);
542
545
  }
543
- const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
546
+ const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
544
547
  if (routes.length === 0) {
545
548
  if (varNames.length > 0 && !existsSync2(genPath)) {
546
549
  writeFileSync(genPath, generatePerModuleTypesSource([]));
547
550
  console.log(
548
- `[rsc-router] Generated route types (placeholder) -> ${genPath}`
551
+ `[rango] Generated route types (placeholder) -> ${genPath}`
549
552
  );
550
553
  }
551
554
  return;
@@ -554,11 +557,11 @@ function writePerModuleRouteTypesForFile(filePath) {
554
557
  const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
555
558
  if (existing !== genSource) {
556
559
  writeFileSync(genPath, genSource);
557
- console.log(`[rsc-router] Generated route types -> ${genPath}`);
560
+ console.log(`[rango] Generated route types -> ${genPath}`);
558
561
  }
559
562
  } catch (err) {
560
563
  console.warn(
561
- `[rsc-router] Failed to generate route types for ${filePath}: ${err.message}`
564
+ `[rango] Failed to generate route types for ${filePath}: ${err.message}`
562
565
  );
563
566
  }
564
567
  }
@@ -573,6 +576,75 @@ var init_per_module_writer = __esm({
573
576
  }
574
577
  });
575
578
 
579
+ // src/build/route-types/source-scan.ts
580
+ function isLineTerminator(ch) {
581
+ const c = ch.charCodeAt(0);
582
+ return c === 10 || c === 13 || c === 8232 || c === 8233;
583
+ }
584
+ function makeCodeClassifier(code) {
585
+ const n = code.length;
586
+ let i = 0;
587
+ let skipStart = -1;
588
+ let skipEnd = -1;
589
+ return (q) => {
590
+ if (q >= skipStart && q < skipEnd) return false;
591
+ while (i < n && i <= q) {
592
+ const c = code[i];
593
+ const d = i + 1 < n ? code[i + 1] : "";
594
+ let end = -1;
595
+ if (c === "/" && d === "/") {
596
+ let j = i + 2;
597
+ while (j < n && !isLineTerminator(code[j])) j++;
598
+ end = j;
599
+ } else if (c === "/" && d === "*") {
600
+ let j = i + 2;
601
+ while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
602
+ end = Math.min(n, j + 2);
603
+ } else if (c === '"' || c === "'" || c === "`") {
604
+ let j = i + 1;
605
+ while (j < n) {
606
+ if (code[j] === "\\") {
607
+ j += 2;
608
+ continue;
609
+ }
610
+ if (code[j] === c) {
611
+ j++;
612
+ break;
613
+ }
614
+ j++;
615
+ }
616
+ end = j;
617
+ }
618
+ if (end >= 0) {
619
+ if (q < end) {
620
+ skipStart = i;
621
+ skipEnd = end;
622
+ return false;
623
+ }
624
+ i = end;
625
+ } else {
626
+ i++;
627
+ }
628
+ }
629
+ return true;
630
+ };
631
+ }
632
+ function firstCodeMatchIndex(code, pattern) {
633
+ const inCode = makeCodeClassifier(code);
634
+ pattern.lastIndex = 0;
635
+ let m;
636
+ while ((m = pattern.exec(code)) !== null) {
637
+ if (inCode(m.index)) return m.index;
638
+ if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
639
+ }
640
+ return -1;
641
+ }
642
+ var init_source_scan = __esm({
643
+ "src/build/route-types/source-scan.ts"() {
644
+ "use strict";
645
+ }
646
+ });
647
+
576
648
  // src/build/route-types/router-processing.ts
577
649
  import {
578
650
  readFileSync as readFileSync3,
@@ -601,7 +673,7 @@ function countPublicRouteEntries(source) {
601
673
  return count;
602
674
  }
603
675
  function isRoutableSourceFile(name) {
604
- return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.");
676
+ return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
605
677
  }
606
678
  function findRouterFilesRecursive(dir, filter, results) {
607
679
  let entries;
@@ -609,7 +681,7 @@ function findRouterFilesRecursive(dir, filter, results) {
609
681
  entries = readdirSync2(dir, { withFileTypes: true });
610
682
  } catch (err) {
611
683
  console.warn(
612
- `[rsc-router] Failed to scan directory ${dir}: ${err.message}`
684
+ `[rango] Failed to scan directory ${dir}: ${err.message}`
613
685
  );
614
686
  return;
615
687
  }
@@ -618,7 +690,8 @@ function findRouterFilesRecursive(dir, filter, results) {
618
690
  for (const entry of entries) {
619
691
  const fullPath = join2(dir, entry.name);
620
692
  if (entry.isDirectory()) {
621
- if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
693
+ if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "coverage" || entry.name === "__tests__" || entry.name === "__mocks__" || entry.name.startsWith("."))
694
+ continue;
622
695
  childDirs.push(fullPath);
623
696
  continue;
624
697
  }
@@ -626,7 +699,7 @@ function findRouterFilesRecursive(dir, filter, results) {
626
699
  if (filter && !filter(fullPath)) continue;
627
700
  try {
628
701
  const source = readFileSync3(fullPath, "utf-8");
629
- if (ROUTER_CALL_PATTERN.test(source)) {
702
+ if (ROUTER_CALL_PATTERN.test(source) && firstCodeMatchIndex(source, ROUTER_CALL_PATTERN_G) >= 0) {
630
703
  routerFilesInDir.push(fullPath);
631
704
  }
632
705
  } catch {
@@ -664,13 +737,13 @@ function findNestedRouterConflict(routerFiles) {
664
737
  }
665
738
  return null;
666
739
  }
667
- function formatNestedRouterConflictError(conflict, prefix = "[rsc-router]") {
740
+ function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
668
741
  return `${prefix} Nested router roots are not supported.
669
742
  Router root: ${conflict.ancestor}
670
743
  Nested router: ${conflict.nested}
671
744
  Move the nested router into a sibling directory or configure it as a separate app root.`;
672
745
  }
673
- function extractUrlsVariableFromRouter(code) {
746
+ function extractUrlsFromRouter(code) {
674
747
  const sourceFile = ts5.createSourceFile(
675
748
  "router.tsx",
676
749
  code,
@@ -684,24 +757,70 @@ function extractUrlsVariableFromRouter(code) {
684
757
  const callee = node.expression;
685
758
  return ts5.isIdentifier(callee) && callee.text === "createRouter";
686
759
  }
760
+ function isInlineBuilder(node) {
761
+ return ts5.isArrowFunction(node) || ts5.isFunctionExpression(node);
762
+ }
763
+ function isRoutesOnCreateRouter(node) {
764
+ if (!ts5.isPropertyAccessExpression(node.expression) || node.expression.name.text !== "routes")
765
+ return false;
766
+ let inner = node.expression.expression;
767
+ while (ts5.isCallExpression(inner) && ts5.isPropertyAccessExpression(inner.expression)) {
768
+ inner = inner.expression.expression;
769
+ }
770
+ return isCreateRouterCall(inner);
771
+ }
687
772
  function visit(node) {
688
773
  if (result) return;
689
- if (ts5.isCallExpression(node) && ts5.isPropertyAccessExpression(node.expression) && node.expression.name.text === "routes" && node.arguments.length >= 1 && ts5.isIdentifier(node.arguments[0])) {
690
- let inner = node.expression.expression;
691
- while (ts5.isCallExpression(inner) && ts5.isPropertyAccessExpression(inner.expression)) {
692
- inner = inner.expression.expression;
693
- }
694
- if (isCreateRouterCall(inner)) {
695
- result = node.arguments[0].text;
696
- return;
774
+ if (ts5.isCallExpression(node) && node.arguments.length >= 1 && isRoutesOnCreateRouter(node)) {
775
+ const arg = node.arguments[0];
776
+ if (ts5.isIdentifier(arg)) {
777
+ result = { kind: "variable", name: arg.text };
778
+ } else if (isInlineBuilder(arg)) {
779
+ result = { kind: "inline", block: arg.getText(sourceFile) };
697
780
  }
781
+ return;
698
782
  }
699
783
  if (isCreateRouterCall(node)) {
700
784
  const callExpr = node;
701
- for (const arg of callExpr.arguments) {
785
+ for (const callArg of callExpr.arguments) {
786
+ if (ts5.isObjectLiteralExpression(callArg)) {
787
+ for (const prop of callArg.properties) {
788
+ if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "urls") {
789
+ if (ts5.isIdentifier(prop.initializer)) {
790
+ result = { kind: "variable", name: prop.initializer.text };
791
+ } else if (isInlineBuilder(prop.initializer)) {
792
+ result = {
793
+ kind: "inline",
794
+ block: prop.initializer.getText(sourceFile)
795
+ };
796
+ }
797
+ return;
798
+ }
799
+ }
800
+ }
801
+ }
802
+ }
803
+ ts5.forEachChild(node, visit);
804
+ }
805
+ visit(sourceFile);
806
+ return result;
807
+ }
808
+ function extractBasenameFromRouter(code) {
809
+ const sourceFile = ts5.createSourceFile(
810
+ "router.tsx",
811
+ code,
812
+ ts5.ScriptTarget.Latest,
813
+ true,
814
+ ts5.ScriptKind.TSX
815
+ );
816
+ let result;
817
+ function visit(node) {
818
+ if (result !== void 0) return;
819
+ if (ts5.isCallExpression(node) && ts5.isIdentifier(node.expression) && node.expression.text === "createRouter") {
820
+ for (const arg of node.arguments) {
702
821
  if (ts5.isObjectLiteralExpression(arg)) {
703
822
  for (const prop of arg.properties) {
704
- if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "urls" && ts5.isIdentifier(prop.initializer)) {
823
+ if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "basename" && ts5.isStringLiteral(prop.initializer)) {
705
824
  result = prop.initializer.text;
706
825
  return;
707
826
  }
@@ -714,6 +833,38 @@ function extractUrlsVariableFromRouter(code) {
714
833
  visit(sourceFile);
715
834
  return result;
716
835
  }
836
+ function applyBasenameToRoutes(result, basename) {
837
+ const prefixed = {};
838
+ for (const [name, pattern] of Object.entries(result.routes)) {
839
+ if (pattern === "/") {
840
+ prefixed[name] = basename;
841
+ } else if (basename.endsWith("/") && pattern.startsWith("/")) {
842
+ prefixed[name] = basename + pattern.slice(1);
843
+ } else {
844
+ prefixed[name] = basename + pattern;
845
+ }
846
+ }
847
+ return { routes: prefixed, searchSchemas: result.searchSchemas };
848
+ }
849
+ function genFileTsPath(sourceFile) {
850
+ const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
851
+ return join2(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
852
+ }
853
+ function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
854
+ if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
855
+ return runtimeSchemas;
856
+ }
857
+ const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
858
+ if (Object.keys(staticParsed.searchSchemas).length === 0) {
859
+ return runtimeSchemas;
860
+ }
861
+ const filtered = {};
862
+ for (const name of publicRouteNames) {
863
+ const schema = staticParsed.searchSchemas[name];
864
+ if (schema) filtered[name] = schema;
865
+ }
866
+ return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
867
+ }
717
868
  function buildCombinedRouteMapForRouterFile(routerFilePath) {
718
869
  let routerSource;
719
870
  try {
@@ -721,19 +872,40 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
721
872
  } catch {
722
873
  return { routes: {}, searchSchemas: {} };
723
874
  }
724
- const urlsVarName = extractUrlsVariableFromRouter(routerSource);
725
- if (!urlsVarName) {
875
+ const extraction = extractUrlsFromRouter(routerSource);
876
+ if (!extraction) {
726
877
  return { routes: {}, searchSchemas: {} };
727
878
  }
728
- const imported = resolveImportedVariable(routerSource, urlsVarName);
729
- if (imported) {
730
- const targetFile = resolveImportPath(imported.specifier, routerFilePath);
731
- if (!targetFile) {
732
- return { routes: {}, searchSchemas: {} };
879
+ const rawBasename = extractBasenameFromRouter(routerSource);
880
+ const basename = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
881
+ let result;
882
+ if (extraction.kind === "inline") {
883
+ result = buildCombinedRouteMapWithSearch(
884
+ routerFilePath,
885
+ void 0,
886
+ void 0,
887
+ void 0,
888
+ extraction.block
889
+ );
890
+ } else {
891
+ const imported = resolveImportedVariable(routerSource, extraction.name);
892
+ if (imported) {
893
+ const targetFile = resolveImportPath(imported.specifier, routerFilePath);
894
+ if (!targetFile) {
895
+ return { routes: {}, searchSchemas: {} };
896
+ }
897
+ result = buildCombinedRouteMapWithSearch(
898
+ targetFile,
899
+ imported.exportedName
900
+ );
901
+ } else {
902
+ result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
733
903
  }
734
- return buildCombinedRouteMapWithSearch(targetFile, imported.exportedName);
735
904
  }
736
- return buildCombinedRouteMapWithSearch(routerFilePath, urlsVarName);
905
+ if (basename) {
906
+ result = applyBasenameToRoutes(result, basename);
907
+ }
908
+ return result;
737
909
  }
738
910
  function detectUnresolvableIncludes(routerFilePath) {
739
911
  const realPath = resolve2(routerFilePath);
@@ -743,9 +915,20 @@ function detectUnresolvableIncludes(routerFilePath) {
743
915
  } catch {
744
916
  return [];
745
917
  }
746
- const urlsVarName = extractUrlsVariableFromRouter(source);
747
- if (!urlsVarName) return [];
748
- const imported = resolveImportedVariable(source, urlsVarName);
918
+ const extraction = extractUrlsFromRouter(source);
919
+ if (!extraction) return [];
920
+ const diagnostics = [];
921
+ if (extraction.kind === "inline") {
922
+ buildCombinedRouteMapWithSearch(
923
+ realPath,
924
+ void 0,
925
+ /* @__PURE__ */ new Set(),
926
+ diagnostics,
927
+ extraction.block
928
+ );
929
+ return diagnostics;
930
+ }
931
+ const imported = resolveImportedVariable(source, extraction.name);
749
932
  let targetFile;
750
933
  let exportedName;
751
934
  if (imported) {
@@ -765,9 +948,8 @@ function detectUnresolvableIncludes(routerFilePath) {
765
948
  exportedName = imported.exportedName;
766
949
  } else {
767
950
  targetFile = realPath;
768
- exportedName = urlsVarName;
951
+ exportedName = extraction.name;
769
952
  }
770
- const diagnostics = [];
771
953
  buildCombinedRouteMapWithSearch(
772
954
  targetFile,
773
955
  exportedName,
@@ -803,7 +985,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
803
985
  if (existsSync3(oldCombinedPath)) {
804
986
  unlinkSync(oldCombinedPath);
805
987
  console.log(
806
- `[rsc-router] Removed stale combined route types: ${oldCombinedPath}`
988
+ `[rango] Removed stale combined route types: ${oldCombinedPath}`
807
989
  );
808
990
  }
809
991
  } catch {
@@ -815,38 +997,22 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
815
997
  throw new Error(formatNestedRouterConflictError(nestedRouterConflict));
816
998
  }
817
999
  for (const routerFilePath of routerFilePaths) {
818
- let routerSource;
819
- try {
820
- routerSource = readFileSync3(routerFilePath, "utf-8");
821
- } catch {
822
- continue;
823
- }
824
- const urlsVarName = extractUrlsVariableFromRouter(routerSource);
825
- if (!urlsVarName) continue;
826
- let result;
827
- const imported = resolveImportedVariable(routerSource, urlsVarName);
828
- if (imported) {
829
- const targetFile = resolveImportPath(imported.specifier, routerFilePath);
830
- if (!targetFile) continue;
831
- result = buildCombinedRouteMapWithSearch(
832
- targetFile,
833
- imported.exportedName
834
- );
835
- } else {
836
- result = buildCombinedRouteMapWithSearch(routerFilePath, urlsVarName);
1000
+ const result = buildCombinedRouteMapForRouterFile(routerFilePath);
1001
+ if (Object.keys(result.routes).length === 0 && Object.keys(result.searchSchemas).length === 0) {
1002
+ let routerSource;
1003
+ try {
1004
+ routerSource = readFileSync3(routerFilePath, "utf-8");
1005
+ } catch {
1006
+ continue;
1007
+ }
1008
+ if (!extractUrlsFromRouter(routerSource)) continue;
837
1009
  }
838
- const routerBasename = pathBasename(routerFilePath).replace(
839
- /\.(tsx?|jsx?)$/,
840
- ""
841
- );
842
- const outPath = join2(
843
- dirname2(routerFilePath),
844
- `${routerBasename}.named-routes.gen.ts`
845
- );
1010
+ const outPath = genFileTsPath(routerFilePath);
846
1011
  const existing = existsSync3(outPath) ? readFileSync3(outPath, "utf-8") : null;
847
1012
  if (Object.keys(result.routes).length === 0) {
848
1013
  if (!existing) {
849
1014
  const emptySource = generateRouteTypesSource({});
1015
+ opts?.onWrite?.(outPath, emptySource);
850
1016
  writeFileSync2(outPath, emptySource);
851
1017
  }
852
1018
  continue;
@@ -866,22 +1032,25 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
866
1032
  continue;
867
1033
  }
868
1034
  }
1035
+ opts?.onWrite?.(outPath, source);
869
1036
  writeFileSync2(outPath, source);
870
1037
  console.log(
871
- `[rsc-router] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
1038
+ `[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
872
1039
  );
873
1040
  }
874
1041
  }
875
1042
  }
876
- var ROUTER_CALL_PATTERN;
1043
+ var ROUTER_CALL_PATTERN, ROUTER_CALL_PATTERN_G;
877
1044
  var init_router_processing = __esm({
878
1045
  "src/build/route-types/router-processing.ts"() {
879
1046
  "use strict";
880
1047
  init_codegen();
1048
+ init_source_scan();
881
1049
  init_include_resolution();
882
1050
  init_per_module_writer();
883
1051
  init_route_name();
884
1052
  ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
1053
+ ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
885
1054
  }
886
1055
  });
887
1056
 
@@ -919,7 +1088,7 @@ import {
919
1088
  import { createElement, StrictMode } from "react";
920
1089
  import { hydrateRoot } from "react-dom/client";
921
1090
  import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
922
- import { initBrowserApp, RSCRouter } from "@rangojs/router/browser";
1091
+ import { initBrowserApp, Rango } from "@rangojs/router/browser";
923
1092
 
924
1093
  async function initializeApp() {
925
1094
  const deps = {
@@ -934,7 +1103,7 @@ async function initializeApp() {
934
1103
 
935
1104
  hydrateRoot(
936
1105
  document,
937
- createElement(StrictMode, null, createElement(RSCRouter))
1106
+ createElement(StrictMode, null, createElement(Rango))
938
1107
  );
939
1108
  }
940
1109
 
@@ -966,7 +1135,8 @@ export const renderHTML = createSSRHandler({
966
1135
  // src/vite/plugins/version-plugin.ts
967
1136
  var version_plugin_exports = {};
968
1137
  __export(version_plugin_exports, {
969
- createVersionPlugin: () => createVersionPlugin
1138
+ createVersionPlugin: () => createVersionPlugin,
1139
+ isViteDepCachePath: () => isViteDepCachePath
970
1140
  });
971
1141
  import { parseAst } from "vite";
972
1142
  function isCodeModule(id) {
@@ -978,7 +1148,7 @@ function normalizeModuleId(id) {
978
1148
  function getClientModuleSignature(source) {
979
1149
  let program;
980
1150
  try {
981
- program = parseAst(source, { jsx: true });
1151
+ program = parseAst(source, { lang: "tsx" });
982
1152
  } catch {
983
1153
  return void 0;
984
1154
  }
@@ -1061,10 +1231,12 @@ function createVersionPlugin() {
1061
1231
  let currentVersion = buildVersion;
1062
1232
  let isDev = false;
1063
1233
  let server = null;
1234
+ let resolvedCacheDir;
1064
1235
  const clientModuleSignatures = /* @__PURE__ */ new Map();
1236
+ let versionCounter = 0;
1065
1237
  const bumpVersion = (reason) => {
1066
- currentVersion = Date.now().toString(16);
1067
- console.log(`[rsc-router] ${reason}, version updated: ${currentVersion}`);
1238
+ currentVersion = Date.now().toString(16) + String(++versionCounter);
1239
+ console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
1068
1240
  const rscEnv = server?.environments?.rsc;
1069
1241
  const versionMod = rscEnv?.moduleGraph?.getModuleById(
1070
1242
  "\0" + VIRTUAL_IDS.version
@@ -1078,6 +1250,7 @@ function createVersionPlugin() {
1078
1250
  enforce: "pre",
1079
1251
  configResolved(config) {
1080
1252
  isDev = config.command === "serve";
1253
+ resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
1081
1254
  },
1082
1255
  configureServer(devServer) {
1083
1256
  server = devServer;
@@ -1119,6 +1292,10 @@ function createVersionPlugin() {
1119
1292
  if (!isDev) return;
1120
1293
  const isRscModule = this.environment?.name === "rsc";
1121
1294
  if (!isRscModule) return;
1295
+ if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
1296
+ if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
1297
+ return;
1298
+ }
1122
1299
  if (isCodeModule(ctx.file)) {
1123
1300
  const filePath = normalizeModuleId(ctx.file);
1124
1301
  const previousSignature = clientModuleSignatures.get(filePath);
@@ -1145,6 +1322,17 @@ function createVersionPlugin() {
1145
1322
  }
1146
1323
  };
1147
1324
  }
1325
+ function isViteDepCachePath(filePath, cacheDir) {
1326
+ if (!filePath) return false;
1327
+ const normalized = filePath.replace(/\\/g, "/");
1328
+ if (cacheDir) {
1329
+ const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
1330
+ if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
1331
+ return true;
1332
+ }
1333
+ }
1334
+ return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
1335
+ }
1148
1336
  var init_version_plugin = __esm({
1149
1337
  "src/vite/plugins/version-plugin.ts"() {
1150
1338
  "use strict";
@@ -1190,7 +1378,7 @@ var runtime_discovery_exports = {};
1190
1378
  __export(runtime_discovery_exports, {
1191
1379
  discoverAndWriteRouteTypes: () => discoverAndWriteRouteTypes
1192
1380
  });
1193
- import { dirname as dirname3, join as join3, basename, resolve as resolve3 } from "node:path";
1381
+ import { resolve as resolve3 } from "node:path";
1194
1382
  import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
1195
1383
  async function discoverAndWriteRouteTypes(opts) {
1196
1384
  let createViteServer;
@@ -1300,22 +1488,12 @@ This means createRouter() stack trace parsing matched an internal frame.
1300
1488
  Set an explicit \`id\` on createRouter() or check the call site.`
1301
1489
  );
1302
1490
  }
1303
- if (!routeSearchSchemas || Object.keys(routeSearchSchemas).length === 0) {
1304
- const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
1305
- if (Object.keys(staticParsed.searchSchemas).length > 0) {
1306
- const filtered = {};
1307
- for (const name of Object.keys(routeManifest)) {
1308
- const schema = staticParsed.searchSchemas[name];
1309
- if (schema) filtered[name] = schema;
1310
- }
1311
- if (Object.keys(filtered).length > 0) {
1312
- routeSearchSchemas = filtered;
1313
- }
1314
- }
1315
- }
1316
- const routerDir = dirname3(sourceFile);
1317
- const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
1318
- const outPath = join3(routerDir, `${routerBasename}.named-routes.gen.ts`);
1491
+ routeSearchSchemas = resolveSearchSchemas(
1492
+ Object.keys(routeManifest),
1493
+ routeSearchSchemas,
1494
+ sourceFile
1495
+ );
1496
+ const outPath = genFileTsPath(sourceFile);
1319
1497
  const source = generateRouteTypesSource(
1320
1498
  routeManifest,
1321
1499
  routeSearchSchemas && Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : void 0
@@ -1352,7 +1530,7 @@ var init_runtime_discovery = __esm({
1352
1530
 
1353
1531
  // src/bin/rango.ts
1354
1532
  init_generate_route_types();
1355
- import { resolve as resolve4, dirname as dirname4 } from "node:path";
1533
+ import { resolve as resolve4, dirname as dirname3 } from "node:path";
1356
1534
  import { readFileSync as readFileSync5, statSync, existsSync as existsSync5 } from "node:fs";
1357
1535
  var [command, ...rawArgs] = process.argv.slice(2);
1358
1536
  if (command === "generate") {
@@ -1423,12 +1601,12 @@ Examples:
1423
1601
  );
1424
1602
  }
1425
1603
  function findProjectRoot(fromPath) {
1426
- let dir = dirname4(resolve4(fromPath));
1427
- while (dir !== dirname4(dir)) {
1604
+ let dir = dirname3(resolve4(fromPath));
1605
+ while (dir !== dirname3(dir)) {
1428
1606
  if (existsSync5(resolve4(dir, "package.json")) || existsSync5(resolve4(dir, "vite.config.ts")) || existsSync5(resolve4(dir, "vite.config.js"))) {
1429
1607
  return dir;
1430
1608
  }
1431
- dir = dirname4(dir);
1609
+ dir = dirname3(dir);
1432
1610
  }
1433
1611
  return process.cwd();
1434
1612
  }