@wular/pnext 0.0.3 → 0.0.6

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 (392) hide show
  1. package/README.md +11 -11
  2. package/bin/pnext +1 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +1 -1
  8. package/reference/config.md +2 -2
  9. package/reference/css.md +13 -9
  10. package/reference/dev.md +1 -1
  11. package/reference/metadata.md +7 -7
  12. package/reference/navigation.md +35 -28
  13. package/reference/performance.md +70 -70
  14. package/reference/rendering.md +17 -17
  15. package/reference/routing.md +17 -17
  16. package/reference/typegen.md +12 -8
  17. package/src/api/cache.ts +36 -37
  18. package/src/api/client-cache.ts +2 -2
  19. package/src/api/client-navigation.ts +113 -109
  20. package/src/api/dynamic.tsx +58 -55
  21. package/src/api/link.tsx +49 -52
  22. package/src/api/navigation.ts +59 -58
  23. package/src/api/server.ts +152 -144
  24. package/src/api/suspense.ts +4 -4
  25. package/src/cli/adapters/vercel-warm.ts +126 -121
  26. package/src/cli/adapters/vercel.ts +437 -443
  27. package/src/cli/analyze.ts +333 -144
  28. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  29. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  30. package/src/cli/build.ts +976 -978
  31. package/src/cli/create.ts +71 -63
  32. package/src/cli/dev.ts +116 -116
  33. package/src/cli/index.ts +88 -85
  34. package/src/cli/migrate/package-json.ts +73 -71
  35. package/src/cli/migrate/report.ts +32 -33
  36. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  37. package/src/cli/migrate/scan.ts +46 -46
  38. package/src/cli/migrate/spinner.ts +9 -9
  39. package/src/cli/migrate/tsconfig.ts +35 -35
  40. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  41. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  42. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  43. package/src/cli/start.ts +65 -66
  44. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  45. package/src/client/build.ts +794 -768
  46. package/src/client/chunk-fold.ts +245 -240
  47. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  48. package/src/client/entry.ts +162 -147
  49. package/src/client/prebuilt.ts +231 -223
  50. package/src/client/profile.ts +29 -29
  51. package/src/client/react-compiler.ts +20 -15
  52. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  53. package/src/client/reference-stub.ts +51 -51
  54. package/src/client/reference.ts +19 -19
  55. package/src/{api → client}/router/events.ts +17 -17
  56. package/src/{api → client}/router/history.ts +16 -16
  57. package/src/{api → client}/router/hub.ts +52 -53
  58. package/src/{api/router.ts → client/router/index.ts} +61 -60
  59. package/src/{api → client}/router/policies.ts +24 -24
  60. package/src/{api → client}/router/runtime.ts +1988 -1961
  61. package/src/{api → client}/router/types.ts +93 -98
  62. package/src/compat/actions/client-plugin.ts +42 -43
  63. package/src/compat/actions/client-stub.ts +14 -14
  64. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  65. package/src/compat/actions/config.ts +63 -64
  66. package/src/compat/actions/detect.ts +68 -68
  67. package/src/compat/actions/discovery.ts +105 -105
  68. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  69. package/src/compat/actions/early-submit.ts +1 -1
  70. package/src/compat/actions/endpoint.ts +198 -198
  71. package/src/compat/actions/extensions.ts +811 -0
  72. package/src/compat/actions/flight.ts +23 -23
  73. package/src/compat/actions/form-state.ts +34 -34
  74. package/src/compat/actions/hoist.ts +382 -236
  75. package/src/compat/actions/ids.ts +7 -12
  76. package/src/compat/actions/index.ts +8 -8
  77. package/src/compat/actions/instances.ts +46 -46
  78. package/src/compat/actions/origin.ts +47 -48
  79. package/src/compat/actions/protocol.ts +22 -22
  80. package/src/compat/actions/registry.ts +19 -19
  81. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  82. package/src/compat/actions/rewrite.ts +125 -125
  83. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  84. package/src/compat/actions/serve.ts +132 -136
  85. package/src/compat/actions/server-tag.ts +4 -4
  86. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  87. package/src/compat/actions/unrecognized-error.ts +4 -4
  88. package/src/compat/{index.ts → aliases.ts} +112 -109
  89. package/src/compat/bundler/bun-externals.ts +18 -18
  90. package/src/compat/bundler/cjs-exports.ts +271 -223
  91. package/src/compat/bundler/config.ts +116 -111
  92. package/src/compat/bundler/externals.ts +12 -12
  93. package/src/compat/bundler/import-meta-url.ts +19 -19
  94. package/src/compat/bundler/modularize-imports.ts +36 -33
  95. package/src/compat/bundler/new-url-asset.ts +22 -24
  96. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  97. package/src/compat/bundler/polyfill.ts +28 -28
  98. package/src/compat/bundler/react-compiler.ts +35 -29
  99. package/src/compat/bundler/react-profiler.tsx +11 -11
  100. package/src/compat/bundler/relay-transform.ts +48 -47
  101. package/src/compat/bundler/require-context.ts +119 -113
  102. package/src/compat/bundler/resolve-extensions.ts +19 -19
  103. package/src/compat/bundler/source-cache.ts +25 -25
  104. package/src/compat/bundler/static-imports.ts +7 -7
  105. package/src/compat/bundler/symlink-imports.ts +46 -46
  106. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  107. package/src/compat/bundler/wasm.ts +58 -60
  108. package/src/compat/bundler/webpack-loaders.ts +254 -241
  109. package/src/compat/bundler/worker.ts +101 -104
  110. package/src/compat/cache/build-flags.ts +29 -29
  111. package/src/compat/cache/build-prerender-errors.ts +40 -44
  112. package/src/compat/cache/custom-handler.ts +60 -53
  113. package/src/compat/cache/fetch-patch.ts +240 -240
  114. package/src/compat/cache/handler.ts +27 -31
  115. package/src/compat/cache/modern-handler.ts +148 -126
  116. package/src/compat/cache/resume-data-cache.ts +47 -45
  117. package/src/compat/cache/revalidate.ts +233 -232
  118. package/src/compat/cache/runtime-error.ts +35 -35
  119. package/src/compat/cache/use-cache-transform.ts +442 -417
  120. package/src/compat/cache/use-cache.ts +650 -614
  121. package/src/compat/cache-control.ts +140 -142
  122. package/src/compat/client/base-path.ts +21 -20
  123. package/src/compat/client/css-order.ts +18 -18
  124. package/src/compat/client/errors/bare-boundary.ts +11 -11
  125. package/src/compat/client/errors/control-flow.ts +23 -23
  126. package/src/compat/client/errors/error-boundary.ts +61 -61
  127. package/src/compat/client/errors/global-error.ts +101 -91
  128. package/src/compat/client/errors/install.ts +71 -72
  129. package/src/compat/client/errors/lazy.ts +23 -23
  130. package/src/compat/client/errors/primitive-throw.ts +47 -45
  131. package/src/compat/client/errors/soft-refresh.ts +4 -4
  132. package/src/compat/client/link-status.ts +33 -33
  133. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  134. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  135. package/src/compat/client/navigation-scroll.ts +63 -63
  136. package/src/compat/client/optimistic-routing.ts +93 -88
  137. package/src/compat/client/prefetch-cache.ts +23 -24
  138. package/src/compat/client/route-announcer.ts +35 -35
  139. package/src/compat/client/segment-cache-policy.ts +20 -20
  140. package/src/compat/client/segment-cache.ts +309 -315
  141. package/src/compat/client/segment-prefetch.ts +127 -132
  142. package/src/compat/client/trailing-slash.ts +5 -4
  143. package/src/compat/css/chunking.ts +113 -116
  144. package/src/compat/css/inline-css.ts +21 -21
  145. package/src/compat/css/lightningcss.ts +37 -38
  146. package/src/compat/css/modules.ts +161 -175
  147. package/src/compat/css/nonce.ts +7 -7
  148. package/src/compat/css/sass-plugin.ts +18 -21
  149. package/src/compat/css/sass.ts +150 -152
  150. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  151. package/src/compat/css/styled-jsx.ts +21 -21
  152. package/src/compat/edge-runtime.ts +27 -27
  153. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  154. package/src/compat/export/client.ts +29 -31
  155. package/src/compat/export/{index.ts → emit.ts} +111 -110
  156. package/src/compat/export/standalone.ts +62 -54
  157. package/src/compat/image-optimizer/cache.ts +51 -49
  158. package/src/compat/image-optimizer/detect.ts +52 -52
  159. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  160. package/src/compat/image-optimizer/source.ts +77 -80
  161. package/src/compat/lifecycle/after-scope.ts +26 -26
  162. package/src/compat/lifecycle/after.ts +48 -45
  163. package/src/compat/lifecycle/error-funnel.ts +98 -102
  164. package/src/compat/lifecycle/error-serialize.ts +30 -26
  165. package/src/compat/lifecycle/error-ui.ts +67 -32
  166. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  167. package/src/compat/lifecycle/instrumentation.ts +85 -85
  168. package/src/compat/lifecycle/node-console.ts +11 -11
  169. package/src/compat/lifecycle/testmode.ts +160 -132
  170. package/src/compat/mdx/compile.ts +60 -57
  171. package/src/compat/mdx/plugin.ts +11 -11
  172. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  173. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  174. package/src/compat/metadata.ts +75 -81
  175. package/src/compat/next/cache.ts +68 -69
  176. package/src/compat/next/canonical-url.ts +9 -9
  177. package/src/compat/next/client-cache.ts +19 -19
  178. package/src/compat/next/client-navigation.ts +112 -116
  179. package/src/compat/next/client-only.ts +1 -1
  180. package/src/compat/next/client-script.tsx +99 -93
  181. package/src/compat/next/client-server.ts +10 -10
  182. package/src/compat/next/config-loader.ts +176 -173
  183. package/src/compat/next/config.ts +7 -7
  184. package/src/compat/next/constants.cjs +6 -6
  185. package/src/compat/next/constants.ts +6 -6
  186. package/src/compat/next/custom-server.ts +26 -24
  187. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  188. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  189. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  190. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  191. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  192. package/src/compat/next/dynamic.tsx +21 -18
  193. package/src/compat/next/error.tsx +52 -52
  194. package/src/compat/next/font/cache.ts +74 -74
  195. package/src/compat/next/font/google.ts +2 -2
  196. package/src/compat/next/font/index.ts +1 -1
  197. package/src/compat/next/font/local.ts +3 -3
  198. package/src/compat/next/font/runtime-client.ts +17 -15
  199. package/src/compat/next/font/runtime.ts +443 -408
  200. package/src/compat/next/font/shared.ts +120 -108
  201. package/src/compat/next/form.tsx +63 -63
  202. package/src/compat/next/head.tsx +2 -2
  203. package/src/compat/next/headers.ts +103 -95
  204. package/src/compat/next/image/client.tsx +220 -0
  205. package/src/compat/next/image/config.ts +56 -58
  206. package/src/compat/next/image/optimizer.ts +40 -36
  207. package/src/compat/next/image/patterns.ts +37 -40
  208. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  209. package/src/compat/next/image/shared.ts +65 -57
  210. package/src/compat/next/image/static-metadata.ts +98 -107
  211. package/src/compat/next/image/validate.ts +79 -88
  212. package/src/compat/next/image.tsx +19 -23
  213. package/src/compat/next/index.ts +1 -1
  214. package/src/compat/next/legacy-image.tsx +59 -60
  215. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  216. package/src/compat/next/link.tsx +158 -158
  217. package/src/compat/next/navigation.cjs +12 -3
  218. package/src/compat/next/navigation.ts +48 -50
  219. package/src/compat/next/offline.ts +27 -27
  220. package/src/compat/next/og.ts +121 -124
  221. package/src/compat/next/preferred-region.ts +13 -14
  222. package/src/compat/next/redirects.ts +58 -56
  223. package/src/compat/next/resource-hints.ts +73 -76
  224. package/src/compat/next/rewrites.ts +130 -133
  225. package/src/compat/next/root-params.ts +45 -45
  226. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  227. package/src/compat/next/router.cjs +4 -2
  228. package/src/compat/next/router.ts +58 -61
  229. package/src/compat/next/script.tsx +108 -108
  230. package/src/compat/next/server-only.ts +1 -1
  231. package/src/compat/next/server.ts +19 -19
  232. package/src/compat/next/svgr.ts +18 -17
  233. package/src/compat/next/telemetry.ts +24 -24
  234. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  235. package/src/compat/next/user-agent.ts +53 -49
  236. package/src/compat/next/web-vitals.ts +22 -24
  237. package/src/compat/otel/api.ts +41 -41
  238. package/src/compat/otel/client-trace-metadata.ts +25 -27
  239. package/src/compat/otel/fetch-span.ts +29 -29
  240. package/src/compat/otel/tracer.ts +331 -331
  241. package/src/compat/pages/api.ts +456 -0
  242. package/src/compat/pages/client-plugin.ts +36 -36
  243. package/src/compat/pages/router-state.ts +34 -34
  244. package/src/compat/pages/{index.ts → router.ts} +130 -135
  245. package/src/compat/ppr/io.ts +12 -12
  246. package/src/compat/ppr/missing-root-params.ts +34 -38
  247. package/src/compat/ppr/root-params-scan.ts +66 -66
  248. package/src/compat/ppr/root-params-transform.ts +24 -26
  249. package/src/compat/ppr/root-params.ts +30 -30
  250. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  251. package/src/compat/protocol.ts +71 -70
  252. package/src/compat/react/action-state.ts +47 -48
  253. package/src/compat/react/client-lite.ts +15 -15
  254. package/src/compat/react/client.ts +4 -4
  255. package/src/compat/react/compiler-runtime.ts +11 -11
  256. package/src/compat/react/dom-client.ts +44 -44
  257. package/src/compat/react/dom-react-server.ts +10 -16
  258. package/src/compat/react/dom-server.ts +10 -10
  259. package/src/compat/react/dom.ts +52 -52
  260. package/src/compat/react/hooks-extra.ts +34 -35
  261. package/src/compat/react/parity.ts +64 -61
  262. package/src/compat/react/preact.ts +81 -82
  263. package/src/compat/react/react-server.ts +28 -28
  264. package/src/compat/react/router-shim.ts +1 -1
  265. package/src/compat/react/server-component-use.ts +8 -8
  266. package/src/compat/react/server-inserted-html.ts +30 -31
  267. package/src/compat/react/server.ts +53 -55
  268. package/src/compat/react/use.ts +32 -32
  269. package/src/compat/react/view-transition.ts +20 -20
  270. package/src/compat/register/actions.ts +35 -824
  271. package/src/compat/register/boot.ts +41 -41
  272. package/src/compat/register/build-tier.ts +5 -5
  273. package/src/compat/register/build.ts +74 -70
  274. package/src/compat/register/bundler.ts +161 -156
  275. package/src/compat/register/cache.ts +20 -20
  276. package/src/compat/register/client-errors.ts +3 -3
  277. package/src/compat/register/config.ts +6 -6
  278. package/src/compat/register/css-extras.ts +30 -34
  279. package/src/compat/register/edge-runtime.ts +3 -3
  280. package/src/compat/register/errors.ts +10 -12
  281. package/src/compat/register/export.ts +16 -16
  282. package/src/compat/register/font.ts +11 -11
  283. package/src/compat/register/hooks.ts +2 -2
  284. package/src/compat/register/image.ts +40 -40
  285. package/src/compat/register/index.ts +59 -62
  286. package/src/compat/register/instrumentation-client.ts +10 -10
  287. package/src/compat/register/lifecycle.ts +25 -28
  288. package/src/compat/register/mdx.ts +10 -10
  289. package/src/compat/register/middleware.ts +226 -16
  290. package/src/compat/register/otel.ts +80 -88
  291. package/src/compat/register/pages-api.ts +10 -463
  292. package/src/compat/register/ppr.ts +16 -16
  293. package/src/compat/register/protocol.ts +17 -18
  294. package/src/compat/register/proxy.ts +49 -51
  295. package/src/compat/register/render.ts +79 -76
  296. package/src/compat/register/routing.ts +162 -159
  297. package/src/compat/register/segment.ts +24 -1887
  298. package/src/compat/register/static-image.ts +3 -3
  299. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  300. package/src/compat/register/typed-routes.ts +14 -14
  301. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  302. package/src/compat/register/validation.ts +18 -18
  303. package/src/compat/segment/loading-boundary.ts +43 -45
  304. package/src/compat/segment/page-slot.ts +69 -69
  305. package/src/compat/segment/serve.ts +1884 -0
  306. package/src/compat/segment/tree.ts +113 -112
  307. package/src/compat/segment/vary-key.ts +38 -38
  308. package/src/compat/segment/vary-params.ts +138 -142
  309. package/src/compat/static-params.ts +14 -12
  310. package/src/compat/tsconfig-defaults.ts +87 -91
  311. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  312. package/src/compat/typecheck/worker.ts +15 -12
  313. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  314. package/src/compat/typed-routes/manifest.ts +174 -170
  315. package/src/compat/typed-routes/typegen.ts +127 -110
  316. package/src/compat/validation/errors.ts +16 -19
  317. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  318. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  319. package/src/compat-bootstrap.ts +16 -16
  320. package/src/config.ts +69 -69
  321. package/src/css/build.ts +230 -227
  322. package/src/css/postcss.ts +79 -80
  323. package/src/css/worker.ts +14 -15
  324. package/src/dev/client-actions.ts +10 -10
  325. package/src/dev/client-chunk-store.ts +27 -27
  326. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  327. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  328. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  329. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  330. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  331. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  332. package/src/dev/server.ts +804 -820
  333. package/src/env.ts +46 -43
  334. package/src/extensions.ts +491 -478
  335. package/src/index.ts +8 -8
  336. package/src/internal.ts +20 -23
  337. package/src/{islands → render}/boundary-error.ts +3 -3
  338. package/src/render/hooks.ts +71 -71
  339. package/src/render/island-context.ts +14 -14
  340. package/src/render/metadata.ts +310 -310
  341. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  342. package/src/{ppr.ts → render/ppr.ts} +244 -245
  343. package/src/render/renderer.ts +2076 -2082
  344. package/src/render/resource-hints.ts +16 -17
  345. package/src/render/slots.tsx +224 -235
  346. package/src/{islands → render}/static-children.ts +9 -12
  347. package/src/{islands → render}/static-slots.ts +37 -37
  348. package/src/{cache/context.ts → request/cache.ts} +20 -20
  349. package/src/request/context.ts +107 -107
  350. package/src/{dynamic/source.ts → resolve/dynamic.ts} +152 -143
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +442 -186
  354. package/src/resolve/source-text.ts +37 -37
  355. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  356. package/src/routing/forwarded.ts +19 -19
  357. package/src/routing/handler.ts +84 -91
  358. package/src/routing/href.ts +69 -70
  359. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  360. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  361. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  362. package/src/routing/routes.ts +833 -848
  363. package/src/routing/slots.ts +164 -160
  364. package/src/runtime/loader.ts +952 -0
  365. package/src/{dev → runtime}/module-cache.ts +309 -287
  366. package/src/{dev → runtime}/module-generations.ts +9 -9
  367. package/src/{dev → runtime}/module-transform.ts +81 -72
  368. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  369. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  370. package/src/runtime/vendor.ts +425 -404
  371. package/src/styles.d.ts +9 -0
  372. package/src/types.ts +320 -335
  373. package/src/utils/ansi.ts +5 -5
  374. package/src/utils/{source.ts → code.ts} +15 -12
  375. package/src/utils/content-type.ts +3 -3
  376. package/src/utils/decode.ts +2 -2
  377. package/src/utils/dev-profile.ts +13 -13
  378. package/src/utils/error-log.ts +6 -6
  379. package/src/utils/esbuild.ts +18 -18
  380. package/src/utils/fs-cache.ts +13 -13
  381. package/src/utils/fs.ts +57 -49
  382. package/src/utils/html.ts +20 -24
  383. package/src/utils/native-require.ts +8 -8
  384. package/src/utils/serialize.ts +139 -146
  385. package/src/utils/verbose.ts +18 -18
  386. package/src/cli/analyze-print.ts +0 -181
  387. package/src/compat/middleware/manifest.ts +0 -210
  388. package/src/compat/next/image-client.tsx +0 -215
  389. package/src/compat/next/link-usage.ts +0 -29
  390. package/src/css/index.ts +0 -2
  391. package/src/render/index.ts +0 -1
  392. package/src/style-modules.d.ts +0 -9
@@ -2,8 +2,8 @@
2
2
  // here is read by the router runtime and by nothing else, so it loads with the
3
3
  // runtime chunk — the installers finish before the facade hands the runtime out,
4
4
  // so the first fetch already sees Next's windows and caches.
5
- import { setSoftNavBoundary } from '../../api/router';
6
- import { setNavigationScrollAction } from '../../api/router/events';
5
+ import { setSoftNavBoundary } from '../../client/router'
6
+ import { setNavigationScrollAction } from '../../client/router/events'
7
7
  import {
8
8
  setLoadingShellPredictionPolicy,
9
9
  setPrefetchStaleTimePolicy,
@@ -11,44 +11,44 @@ import {
11
11
  setSegmentCachePolicy,
12
12
  setShellStaleTimePolicy,
13
13
  setStylesheetReconciler,
14
- } from '../../api/router/policies';
15
- import { installSegmentCachePolicy } from './segment-cache-policy';
14
+ } from '../../client/router/policies'
15
+ import { installSegmentCachePolicy } from './segment-cache-policy'
16
16
  // `output: 'export'` document fetching. Imported for its module-scope
17
17
  // registration, which has to beat the router's first prefetches — this module
18
18
  // resolving before the runtime is handed out is exactly that guarantee.
19
- import '../export/client';
20
- import { reconcileNextStylesheets } from './css-order';
21
- import { staleTimeForEntryMs, staticStaleTimeMs } from './prefetch-cache';
22
- import { isOutsideBasePath } from './base-path';
23
- import { predictNextLoadingShell } from './optimistic-routing';
24
- import { applyNextNavigationScroll } from './navigation-scroll';
25
- import { installRouteAnnouncer } from './route-announcer';
19
+ import '../export/client'
20
+ import { reconcileNextStylesheets } from './css-order'
21
+ import { staleTimeForEntryMs, staticStaleTimeMs } from './prefetch-cache'
22
+ import { isOutsideBasePath } from './base-path'
23
+ import { predictNextLoadingShell } from './optimistic-routing'
24
+ import { applyNextNavigationScroll } from './navigation-scroll'
25
+ import { installRouteAnnouncer } from './route-announcer'
26
26
 
27
27
  export function installNavPolicies() {
28
28
  // Route announcer: mount the empty `<next-route-announcer>` and update it on
29
29
  // every soft-nav commit (a11y — announce client route changes to AT). Next
30
30
  // mounts it at hydration; it announces nothing until the first navigation, and
31
31
  // this tier lands on idle, long before one can happen.
32
- installRouteAnnouncer();
32
+ installRouteAnnouncer()
33
33
  // Prefetch staleTime policy: static 300s / dynamic 0, with the
34
34
  // experimental.staleTimes override injected as window.__PNEXT_STALE_TIMES__,
35
35
  // and a response `x-nextjs-stale-time` header overriding both when present.
36
- setPrefetchStaleTimePolicy(staleTimeForEntryMs);
37
- setRevalidationPrefetchDelay(300);
36
+ setPrefetchStaleTimePolicy(staleTimeForEntryMs)
37
+ setRevalidationPrefetchDelay(300)
38
38
  // Loading-shell window: a route's cached loading boundary (and the prefetch
39
39
  // entry carrying it) reuses for the STATIC window even when its dynamic data
40
40
  // is immediately stale — Next's split staleness model.
41
- setShellStaleTimePolicy(staticStaleTimeMs);
42
- setLoadingShellPredictionPolicy(predictNextLoadingShell);
41
+ setShellStaleTimePolicy(staticStaleTimeMs)
42
+ setLoadingShellPredictionPolicy(predictNextLoadingShell)
43
43
  // Per-segment (vary-params) client cache — Segment-M2 deliverable 3. Entries
44
44
  // are keyed on the params a segment provably reads, so one entry serves every
45
45
  // param value it does not depend on.
46
- setSegmentCachePolicy(installSegmentCachePolicy());
47
- setNavigationScrollAction(applyNextNavigationScroll);
48
- setStylesheetReconciler(reconcileNextStylesheets);
46
+ setSegmentCachePolicy(installSegmentCachePolicy())
47
+ setNavigationScrollAction(applyNextNavigationScroll)
48
+ setStylesheetReconciler(reconcileNextStylesheets)
49
49
  // basePath boundary: a same-origin URL outside the configured basePath must
50
50
  // hard-navigate (a `basePath:false` target), not soft-swap.
51
- setSoftNavBoundary(isOutsideBasePath);
51
+ setSoftNavBoundary(isOutsideBasePath)
52
52
  // NOTE: the standalone segment-prefetch wire runtime (segment-prefetch.ts) is
53
53
  // deliberately NOT installed: its intent-time tree/body fetches fed caches
54
54
  // nothing consumed and broke Next's request-count contracts (a hover inside a
@@ -10,33 +10,32 @@ import {
10
10
  registerDeferredInstall,
11
11
  setBlockedJavascriptUrlReporter,
12
12
  softNavigate,
13
- } from '../../api/router';
13
+ } from '../../client/router'
14
14
 
15
- const BLOCKED_JS_URL_MESSAGE =
16
- 'Next.js has blocked a javascript: URL as a security precaution.';
15
+ const BLOCKED_JS_URL_MESSAGE = 'Next.js has blocked a javascript: URL as a security precaution.'
17
16
 
18
17
  export function installNavCompat() {
19
- if (!process.browser && typeof window === 'undefined') return;
20
- setBlockedJavascriptUrlReporter(() => console.error(BLOCKED_JS_URL_MESSAGE));
21
- const windowWithReporter = window as typeof window & { __PNEXT_JS_URL_REPORTER__?: boolean };
18
+ if (!process.browser && typeof window === 'undefined') return
19
+ setBlockedJavascriptUrlReporter(() => console.error(BLOCKED_JS_URL_MESSAGE))
20
+ const windowWithReporter = window as typeof window & { __PNEXT_JS_URL_REPORTER__?: boolean }
22
21
  if (!windowWithReporter.__PNEXT_JS_URL_REPORTER__) {
23
- windowWithReporter.__PNEXT_JS_URL_REPORTER__ = true;
22
+ windowWithReporter.__PNEXT_JS_URL_REPORTER__ = true
24
23
  window.addEventListener('pnext:blocked-javascript-url', () => {
25
- console.error(BLOCKED_JS_URL_MESSAGE);
26
- });
24
+ console.error(BLOCKED_JS_URL_MESSAGE)
25
+ })
27
26
  }
28
- installNextRouterGlobal();
29
- registerDeferredInstall(() => import('./nav-compat-runtime').then(m => m.installNavPolicies()));
27
+ installNextRouterGlobal()
28
+ registerDeferredInstall(() => import('./nav-runtime').then(m => m.installNavPolicies()))
30
29
  }
31
30
 
32
31
  // `window.next.router` — Next's own global handle. Pure-core apps have no such
33
32
  // namespace, so it installs from compat rather than from the router hub.
34
33
  function installNextRouterGlobal() {
35
- window.next ??= {};
34
+ window.next ??= {}
36
35
  window.next.router = {
37
36
  ...window.next.router,
38
37
  push: href => softNavigate(String(href)),
39
38
  replace: href => softNavigate(String(href), { replace: true }),
40
39
  prefetch: href => prefetchRoute(String(href), { strict: true }),
41
- };
40
+ }
42
41
  }
@@ -1,54 +1,54 @@
1
- import type { NavigationScrollAction, NavigationScrollOptions } from '../../api/router';
1
+ import type { NavigationScrollAction, NavigationScrollOptions } from '../../client/router'
2
2
 
3
- const RECT_PROPERTIES = ['bottom', 'height', 'left', 'right', 'top', 'width', 'x', 'y'] as const;
3
+ const RECT_PROPERTIES = ['bottom', 'height', 'left', 'right', 'top', 'width', 'x', 'y'] as const
4
4
 
5
- export type NextScrollPlan = 'hash' | 'preserve' | 'restore' | 'top' | 'top-then-target';
5
+ export type NextScrollPlan = 'hash' | 'preserve' | 'restore' | 'top' | 'top-then-target'
6
6
 
7
7
  export function nextScrollPlan(
8
8
  url: URL,
9
9
  options: NavigationScrollOptions,
10
10
  targetInViewport: boolean | undefined,
11
11
  ): NextScrollPlan {
12
- if (options.pop) return 'restore';
13
- if (options.scroll === false) return 'preserve';
14
- if (url.hash) return 'hash';
15
- if (targetInViewport === undefined) return 'top';
16
- return targetInViewport ? 'preserve' : 'top-then-target';
12
+ if (options.pop) return 'restore'
13
+ if (options.scroll === false) return 'preserve'
14
+ if (url.hash) return 'hash'
15
+ if (targetInViewport === undefined) return 'top'
16
+ return targetInViewport ? 'preserve' : 'top-then-target'
17
17
  }
18
18
 
19
19
  export function firstScrollCandidate<T>(
20
20
  candidates: Iterable<T>,
21
21
  shouldSkip: (candidate: T) => boolean,
22
22
  ): T | undefined {
23
- for (const candidate of candidates) if (!shouldSkip(candidate)) return candidate;
24
- return undefined;
23
+ for (const candidate of candidates) if (!shouldSkip(candidate)) return candidate
24
+ return undefined
25
25
  }
26
26
 
27
27
  export function deepestSingleChild<T>(node: T | undefined, onlyChild: (node: T) => T | undefined) {
28
28
  while (node) {
29
- const child = onlyChild(node);
30
- if (!child) return node;
31
- node = child;
29
+ const child = onlyChild(node)
30
+ if (!child) return node
31
+ node = child
32
32
  }
33
- return undefined;
33
+ return undefined
34
34
  }
35
35
 
36
36
  export function topOnlyScrollPosition(scrollX: number): [number, number] {
37
- return [scrollX, 0];
37
+ return [scrollX, 0]
38
38
  }
39
39
 
40
40
  export const applyNextNavigationScroll: NavigationScrollAction = (url, options) => {
41
- const target = scrollFocusTarget();
41
+ const target = scrollFocusTarget()
42
42
  const plan = nextScrollPlan(
43
43
  url,
44
44
  options,
45
45
  target ? targetTopInViewport(target, document.documentElement.clientHeight) : undefined,
46
- );
46
+ )
47
47
  if (plan === 'restore') {
48
- const state = history.state as { __pnextScroll?: [number, number] } | null;
49
- const [x, y] = state?.__pnextScroll ?? [0, 0];
50
- window.scrollTo(x, y);
51
- return;
48
+ const state = history.state as { __pnextScroll?: [number, number] } | null
49
+ const [x, y] = state?.__pnextScroll ?? [0, 0]
50
+ window.scrollTo(x, y)
51
+ return
52
52
  }
53
53
  // React hoists a rendered <style precedence>/<link rel=stylesheet>/metadata element out of the segment
54
54
  // and into <head>. Next resolves its scroll target with findDOMNode() on the changed segment, so when
@@ -56,43 +56,43 @@ export const applyNextNavigationScroll: NavigationScrollAction = (url, options)
56
56
  // zero-rect sibling there and runs out - the navigation scrolls nowhere and focuses nothing. pnext
57
57
  // renders those elements in place, so recognize the leading hoisted element and reproduce the same
58
58
  // no-op. Placed after `restore` so history traversal still restores its saved position.
59
- if (segmentLeadsWithHoistedElement()) return;
59
+ if (segmentLeadsWithHoistedElement()) return
60
60
  if (plan === 'hash') {
61
- scrollToHash(url.hash);
62
- return;
61
+ scrollToHash(url.hash)
62
+ return
63
63
  }
64
64
  if (plan === 'preserve') {
65
- if (target && options.scroll !== false) focusSegment(target);
66
- return;
65
+ if (target && options.scroll !== false) focusSegment(target)
66
+ return
67
67
  }
68
68
  if (plan === 'top') {
69
- window.scrollTo(...topOnlyScrollPosition(window.scrollX));
70
- return;
69
+ window.scrollTo(...topOnlyScrollPosition(window.scrollX))
70
+ return
71
71
  }
72
- if (!target) return;
73
- window.scrollTo(...topOnlyScrollPosition(window.scrollX));
74
- if (!targetTopInViewport(target, document.documentElement.clientHeight)) target.scrollIntoView();
75
- focusSegment(target);
76
- };
72
+ if (!target) return
73
+ window.scrollTo(...topOnlyScrollPosition(window.scrollX))
74
+ if (!targetTopInViewport(target, document.documentElement.clientHeight)) target.scrollIntoView()
75
+ focusSegment(target)
76
+ }
77
77
 
78
78
  function shouldSkipScrollElement(element: HTMLElement) {
79
- const position = getComputedStyle(element).position;
80
- if (position === 'sticky' || position === 'fixed') return true;
81
- const rect = element.getBoundingClientRect();
82
- return RECT_PROPERTIES.every(item => rect[item] === 0);
79
+ const position = getComputedStyle(element).position
80
+ if (position === 'sticky' || position === 'fixed') return true
81
+ const rect = element.getBoundingClientRect()
82
+ return RECT_PROPERTIES.every(item => rect[item] === 0)
83
83
  }
84
84
 
85
85
  function targetTopInViewport(element: HTMLElement, viewportHeight: number) {
86
- const rects = element.getClientRects();
87
- if (rects.length === 0) return false;
88
- let top = Number.POSITIVE_INFINITY;
89
- for (const rect of rects) top = Math.min(top, rect.top);
90
- return top >= 0 && top <= viewportHeight;
86
+ const rects = element.getClientRects()
87
+ if (rects.length === 0) return false
88
+ let top = Number.POSITIVE_INFINITY
89
+ for (const rect of rects) top = Math.min(top, rect.top)
90
+ return top >= 0 && top <= viewportHeight
91
91
  }
92
92
 
93
93
  function scrollFocusTarget(): HTMLElement | null {
94
- const segment = changedSegmentRoot();
95
- if (!segment) return null;
94
+ const segment = changedSegmentRoot()
95
+ if (!segment) return null
96
96
  // Next resolves the target with findDOMNode() on the changed segment: the
97
97
  // FIRST host element the segment rendered, never a descendant of it. The page
98
98
  // container IS that segment, so its first element child is the target as-is.
@@ -103,51 +103,51 @@ function scrollFocusTarget(): HTMLElement | null {
103
103
  ? (segment.firstElementChild ?? undefined)
104
104
  : deepestSingleChild(segment.firstElementChild ?? undefined, node =>
105
105
  node.nextElementSibling === null ? (node.firstElementChild ?? undefined) : undefined,
106
- );
107
- const nodes: HTMLElement[] = [];
106
+ )
107
+ const nodes: HTMLElement[] = []
108
108
  for (let node = first; node; node = node.nextElementSibling ?? undefined) {
109
- if (node instanceof HTMLElement) nodes.push(node);
109
+ if (node instanceof HTMLElement) nodes.push(node)
110
110
  }
111
- return firstScrollCandidate(nodes, shouldSkipScrollElement) ?? null;
111
+ return firstScrollCandidate(nodes, shouldSkipScrollElement) ?? null
112
112
  }
113
113
 
114
114
  /** The renderer's page-slot wrapper — the segment a navigation replaced. */
115
- const PAGE_CONTAINER_ID = 'pnext-page';
115
+ const PAGE_CONTAINER_ID = 'pnext-page'
116
116
 
117
117
  // Elements React relocates into <head> when a component renders them.
118
- const HOISTED_TAGS = new Set(['style', 'link', 'title', 'meta', 'base']);
118
+ const HOISTED_TAGS = new Set(['style', 'link', 'title', 'meta', 'base'])
119
119
 
120
120
  /**
121
121
  * Whether the changed segment's first rendered element is one React would have hoisted into <head> -
122
122
  * the state in which Next's scroll walk never reaches the page content (see the call site).
123
123
  */
124
124
  function segmentLeadsWithHoistedElement(): boolean {
125
- const segment = changedSegmentRoot();
126
- const first = segment?.firstElementChild;
127
- return first !== null && first !== undefined && HOISTED_TAGS.has(first.localName);
125
+ const segment = changedSegmentRoot()
126
+ const first = segment?.firstElementChild
127
+ return first !== null && first !== undefined && HOISTED_TAGS.has(first.localName)
128
128
  }
129
129
 
130
130
  function changedSegmentRoot(): HTMLElement | null {
131
- const page = document.getElementById(PAGE_CONTAINER_ID);
132
- if (page instanceof HTMLElement) return page;
133
- const root = document.querySelector('[data-pnext-root]');
134
- return root instanceof HTMLElement ? root : document.body;
131
+ const page = document.getElementById(PAGE_CONTAINER_ID)
132
+ if (page instanceof HTMLElement) return page
133
+ const root = document.querySelector('[data-pnext-root]')
134
+ return root instanceof HTMLElement ? root : document.body
135
135
  }
136
136
 
137
137
  function scrollToHash(hash: string) {
138
- const id = decodeURIComponent(hash.slice(1));
139
- const target = id === 'top' ? document.body : (document.getElementById(id) ?? namedTarget(id));
140
- target?.scrollIntoView();
138
+ const id = decodeURIComponent(hash.slice(1))
139
+ const target = id === 'top' ? document.body : (document.getElementById(id) ?? namedTarget(id))
140
+ target?.scrollIntoView()
141
141
  }
142
142
 
143
143
  function namedTarget(name: string): HTMLElement | null {
144
- const named = document.getElementsByName(name)[0];
145
- return named instanceof HTMLElement ? named : null;
144
+ const named = document.getElementsByName(name)[0]
145
+ return named instanceof HTMLElement ? named : null
146
146
  }
147
147
 
148
148
  function focusSegment(target: HTMLElement) {
149
149
  try {
150
- target.focus({ preventScroll: true });
150
+ target.focus({ preventScroll: true })
151
151
  } catch {
152
152
  // A swap can detach the target before focus runs.
153
153
  }
@@ -12,26 +12,26 @@
12
12
  // produced by a rewrite. Such a response must never seed predictions - the rewrite may map a
13
13
  // sibling URL somewhere else entirely, or vary on search params.
14
14
 
15
- import type { RouteParamValue } from '../../types';
15
+ import type { RouteParamValue } from '../../types'
16
16
 
17
17
  interface RouteState {
18
18
  // Bracket-free colon form: `:id` for a dynamic segment, `:slug*` for a
19
19
  // catch-all; `catchAllOptional` distinguishes `[[...slug]]` (matches zero
20
20
  // segments) from `[...slug]` (requires at least one).
21
- route: string;
22
- params: Record<string, RouteParamValue>;
23
- catchAllOptional?: boolean;
24
- staticChildren?: string[];
25
- staticChildrenBySegment?: Record<string, string[]>;
26
- prefetchKind?: 'shell' | 'eager';
21
+ route: string
22
+ params: Record<string, RouteParamValue>
23
+ catchAllOptional?: boolean
24
+ staticChildren?: string[]
25
+ staticChildrenBySegment?: Record<string, string[]>
26
+ prefetchKind?: 'shell' | 'eager'
27
27
  /** `prefetch = 'allow-runtime'`: the shell is request-sampled PER URL. */
28
- runtimePrefetch?: boolean;
28
+ runtimePrefetch?: boolean
29
29
  }
30
30
 
31
31
  interface PredictedShell {
32
- html: string;
33
- route: RouteState;
34
- prefetch?: 'shell' | 'eager';
32
+ html: string
33
+ route: RouteState
34
+ prefetch?: 'shell' | 'eager'
35
35
  /**
36
36
  * True when the predicted shell belongs to an `allow-runtime` route. Its content is derived from the
37
37
  * sampled request's params, so a cached shell of ONE param value says nothing about another - the
@@ -41,13 +41,13 @@ interface PredictedShell {
41
41
  * with its `params` HANGING, so the cached shell IS the route's shared App Shell and says the same
42
42
  * thing for every param. Revealing another link of the route then has nothing to fetch.
43
43
  */
44
- runtimePrefetch?: boolean;
44
+ runtimePrefetch?: boolean
45
45
  }
46
46
 
47
47
  /** `experimental.appShells`, stamped into the document by register-render. */
48
48
  function appShellsEnabled(): boolean {
49
- if (!process.browser && typeof window === 'undefined') return false;
50
- return (window as { __PNEXT_APP_SHELLS__?: boolean }).__PNEXT_APP_SHELLS__ === true;
49
+ if (!process.browser && typeof window === 'undefined') return false
50
+ return (window as { __PNEXT_APP_SHELLS__?: boolean }).__PNEXT_APP_SHELLS__ === true
51
51
  }
52
52
 
53
53
  export function predictNextLoadingShell(
@@ -56,13 +56,13 @@ export function predictNextLoadingShell(
56
56
  ): PredictedShell | undefined {
57
57
  // Most recently stored shells first (Map preserves insertion order).
58
58
  for (const [pathname, html] of [...shells.entries()].reverse()) {
59
- const state = routeStateFromShell(html);
60
- if (!state) continue;
59
+ const state = routeStateFromShell(html)
60
+ if (!state) continue
61
61
  // A shell's own URL must fit its route pattern before it can teach the
62
62
  // route trie. This catches rewrites, including a dynamic response served
63
63
  // for a known static sibling.
64
- if (!matchRoute(state, pathname)) continue;
65
- const params = matchRoute(state, url.pathname);
64
+ if (!matchRoute(state, pathname)) continue
65
+ const params = matchRoute(state, url.pathname)
66
66
  if (params) {
67
67
  return {
68
68
  html: reifyShellParams(html, state.params, params),
@@ -73,65 +73,69 @@ export function predictNextLoadingShell(
73
73
  },
74
74
  ...(state.prefetchKind ? { prefetch: state.prefetchKind } : {}),
75
75
  ...(state.runtimePrefetch && !appShellsEnabled() ? { runtimePrefetch: true } : {}),
76
- };
76
+ }
77
77
  }
78
78
  }
79
- return undefined;
79
+ return undefined
80
80
  }
81
81
 
82
82
  function routeStateFromShell(html: string): RouteState | undefined {
83
- const raw = /window\.__PNEXT_ROUTE__=(\{.*?\});<\/script>/.exec(html)?.[1];
84
- if (!raw) return undefined;
83
+ const raw = /window\.__PNEXT_ROUTE__=(\{.*?\});<\/script>/.exec(html)?.[1]
84
+ if (!raw) return undefined
85
85
  try {
86
- const state = JSON.parse(raw) as RouteState;
86
+ const state = JSON.parse(raw) as RouteState
87
87
  return typeof state.route === 'string' && state.params && typeof state.params === 'object'
88
88
  ? state
89
- : undefined;
89
+ : undefined
90
90
  } catch {
91
- return undefined;
91
+ return undefined
92
92
  }
93
93
  }
94
94
 
95
- function matchRoute(state: RouteState, pathname: string): Record<string, RouteParamValue> | undefined {
96
- const pattern = state.route.split('/').filter(Boolean);
97
- const target = pathname.split('/').filter(Boolean).map(decodeSegment);
98
- const params: Record<string, RouteParamValue> = {};
99
- let cursor = 0;
95
+ function matchRoute(
96
+ state: RouteState,
97
+ pathname: string,
98
+ ): Record<string, RouteParamValue> | undefined {
99
+ const pattern = state.route.split('/').filter(Boolean)
100
+ const target = pathname.split('/').filter(Boolean).map(decodeSegment)
101
+ const params: Record<string, RouteParamValue> = {}
102
+ let cursor = 0
100
103
  for (let index = 0; index < pattern.length; index++) {
101
- const segment = pattern[index]!;
104
+ const segment = pattern[index]!
102
105
  // Colon form: `:slug*` is a catch-all, `:id` a single dynamic segment.
103
- const catchAll = /^:([\w$]+)\*$/.exec(segment);
104
- const dynamic = catchAll ? null : /^:([\w$]+)$/.exec(segment);
105
- const siblingKey = String(index);
106
- const siblings = state.staticChildrenBySegment?.[siblingKey] ??
107
- (index === pattern.length - 1 ? state.staticChildren : undefined);
106
+ const catchAll = /^:([\w$]+)\*$/.exec(segment)
107
+ const dynamic = catchAll ? null : /^:([\w$]+)$/.exec(segment)
108
+ const siblingKey = String(index)
109
+ const siblings =
110
+ state.staticChildrenBySegment?.[siblingKey] ??
111
+ (index === pattern.length - 1 ? state.staticChildren : undefined)
108
112
  // A dynamic trie node is usable only after the server has said its static
109
113
  // siblings are complete. This is the production-only null-vs-empty rule.
110
- if ((dynamic || catchAll) && siblings === undefined) return undefined;
111
- if (siblings?.includes(target[cursor] ?? '')) return undefined;
114
+ if ((dynamic || catchAll) && siblings === undefined) return undefined
115
+ if (siblings?.includes(target[cursor] ?? '')) return undefined
112
116
  if (catchAll) {
113
- const name = catchAll[1]!;
117
+ const name = catchAll[1]!
114
118
  if (state.catchAllOptional) {
115
119
  // `[[...slug]]`: matches the base path plus any nested tail.
116
- const rest = target.slice(cursor);
117
- if (rest.length > 0) params[name] = rest;
118
- return params;
120
+ const rest = target.slice(cursor)
121
+ if (rest.length > 0) params[name] = rest
122
+ return params
119
123
  }
120
124
  // `[...slug]`: a catch-all learned from a parallel slot must not predict a
121
125
  // sibling URL for the primary route. Only reuse it when the source shell
122
126
  // itself was rendered through that catch-all, and require ≥1 segment.
123
- if (!Array.isArray(state.params[name])) return undefined;
124
- const rest = target.slice(cursor);
125
- if (rest.length === 0) return undefined;
126
- params[name] = rest;
127
- return params;
127
+ if (!Array.isArray(state.params[name])) return undefined
128
+ const rest = target.slice(cursor)
129
+ if (rest.length === 0) return undefined
130
+ params[name] = rest
131
+ return params
128
132
  }
129
- const value = target[cursor++];
130
- if (value === undefined) return undefined;
131
- if (dynamic) params[dynamic[1]!] = value;
132
- else if (segment !== value) return undefined;
133
+ const value = target[cursor++]
134
+ if (value === undefined) return undefined
135
+ if (dynamic) params[dynamic[1]!] = value
136
+ else if (segment !== value) return undefined
133
137
  }
134
- return cursor === target.length ? params : undefined;
138
+ return cursor === target.length ? params : undefined
135
139
  }
136
140
 
137
141
  function reifyShellParams(
@@ -139,45 +143,46 @@ function reifyShellParams(
139
143
  previous: Record<string, RouteParamValue>,
140
144
  params: Record<string, RouteParamValue>,
141
145
  ): string {
142
- if (typeof DOMParser === 'undefined') return html;
143
- const doc = new DOMParser().parseFromString(html, 'text/html');
144
- materializeClientMarkers(doc);
146
+ if (typeof DOMParser === 'undefined') return html
147
+ const doc = new DOMParser().parseFromString(html, 'text/html')
148
+ materializeClientMarkers(doc)
145
149
  for (const root of doc.querySelectorAll<HTMLElement>('[data-pnext-params]')) {
146
- const raw = root.getAttribute('data-pnext-params');
147
- if (!raw) continue;
150
+ const raw = root.getAttribute('data-pnext-params')
151
+ if (!raw) continue
148
152
  try {
149
- const scoped = JSON.parse(raw) as Record<string, RouteParamValue>;
150
- if (sameParams(scoped, previous)) root.setAttribute('data-pnext-params', JSON.stringify(params));
153
+ const scoped = JSON.parse(raw) as Record<string, RouteParamValue>
154
+ if (sameParams(scoped, previous))
155
+ root.setAttribute('data-pnext-params', JSON.stringify(params))
151
156
  } catch {
152
157
  // A malformed island scope cannot safely be reified.
153
158
  }
154
159
  }
155
- return `<!doctype html>${doc.documentElement.outerHTML}`;
160
+ return `<!doctype html>${doc.documentElement.outerHTML}`
156
161
  }
157
162
 
158
163
  function materializeClientMarkers(doc: Document): void {
159
- const comments: Comment[] = [];
160
- const walker = doc.createTreeWalker(doc, NodeFilter.SHOW_COMMENT);
161
- while (walker.nextNode()) comments.push(walker.currentNode as Comment);
164
+ const comments: Comment[] = []
165
+ const walker = doc.createTreeWalker(doc, NodeFilter.SHOW_COMMENT)
166
+ while (walker.nextNode()) comments.push(walker.currentNode as Comment)
162
167
  for (const start of comments.reverse()) {
163
- const match = /^(pnext-client|pnext-page):([^>]*)$/.exec(start.data);
164
- const kind = match?.[1];
165
- const encoded = match?.[2];
166
- if (!kind || !encoded || !start.parentNode) continue;
167
- const container = doc.createElement('div');
168
- const tag = kind === 'pnext-page' ? 'div' : 'pnext-client';
169
- container.innerHTML = `<${tag} ${encoded}></${tag}>`;
170
- const island = container.firstElementChild;
171
- if (!island) continue;
172
- let node = start.nextSibling;
168
+ const match = /^(pnext-client|pnext-page):([^>]*)$/.exec(start.data)
169
+ const kind = match?.[1]
170
+ const encoded = match?.[2]
171
+ if (!kind || !encoded || !start.parentNode) continue
172
+ const container = doc.createElement('div')
173
+ const tag = kind === 'pnext-page' ? 'div' : 'pnext-client'
174
+ container.innerHTML = `<${tag} ${encoded}></${tag}>`
175
+ const island = container.firstElementChild
176
+ if (!island) continue
177
+ let node = start.nextSibling
173
178
  while (node && !(node.nodeType === Node.COMMENT_NODE && node.nodeValue === `/${kind}`)) {
174
- const next = node.nextSibling;
175
- island.append(node);
176
- node = next;
179
+ const next = node.nextSibling
180
+ island.append(node)
181
+ node = next
177
182
  }
178
- if (!node) continue;
179
- start.replaceWith(island);
180
- node.remove();
183
+ if (!node) continue
184
+ start.replaceWith(island)
185
+ node.remove()
181
186
  }
182
187
  }
183
188
 
@@ -185,22 +190,22 @@ function sameParams(
185
190
  left: Record<string, RouteParamValue>,
186
191
  right: Record<string, RouteParamValue>,
187
192
  ): boolean {
188
- const leftKeys = Object.keys(left);
189
- const rightKeys = Object.keys(right);
190
- if (leftKeys.length !== rightKeys.length) return false;
193
+ const leftKeys = Object.keys(left)
194
+ const rightKeys = Object.keys(right)
195
+ if (leftKeys.length !== rightKeys.length) return false
191
196
  return leftKeys.every(key => {
192
- const a = left[key];
193
- const b = right[key];
197
+ const a = left[key]
198
+ const b = right[key]
194
199
  return Array.isArray(a)
195
200
  ? Array.isArray(b) && a.length === b.length && a.every((value, index) => value === b[index])
196
- : a === b;
197
- });
201
+ : a === b
202
+ })
198
203
  }
199
204
 
200
205
  function decodeSegment(segment: string) {
201
206
  try {
202
- return decodeURIComponent(segment);
207
+ return decodeURIComponent(segment)
203
208
  } catch {
204
- return segment;
209
+ return segment
205
210
  }
206
211
  }