@wular/pnext 0.0.4 → 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 -1992
  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 -1897
  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} +139 -139
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +318 -296
  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 +827 -815
  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
@@ -1,10 +1,10 @@
1
- import { existsSync, readdirSync, readFileSync, type Dirent } from 'node:fs';
2
- import path from 'node:path';
1
+ import { existsSync, readdirSync, readFileSync, type Dirent } from 'node:fs'
2
+ import path from 'node:path'
3
3
 
4
4
  /**
5
5
  * Build-time app facts that let compat drop code an app cannot reach. The fact here: whether any
6
6
  * first-party source can ask for a blurred image placeholder. `placeholder="blur"` on `next/image` (or
7
- * getImageProps) is the only route into image-props' inline blur-SVG builder, which otherwise ships on
7
+ * getImageProps) is the only route into image/props' inline blur-SVG builder, which otherwise ships on
8
8
  * every page that uses next/image.
9
9
  *
10
10
  * The gate is one-sided by construction: every unreadable case answers "yes". A wrong "no" would render
@@ -12,29 +12,29 @@ import path from 'node:path';
12
12
  */
13
13
 
14
14
  /** Skipped wholesale: not first-party source, or build output. */
15
- const skipDirs = new Set(['node_modules', 'dist', 'build', 'out', 'coverage', 'public', 'target']);
16
- const sourceFile = /\.(?:[cm]?[jt]sx?|mdx)$/;
15
+ const skipDirs = new Set(['node_modules', 'dist', 'build', 'out', 'coverage', 'public', 'target'])
16
+ const sourceFile = /\.(?:[cm]?[jt]sx?|mdx)$/
17
17
 
18
18
  /** Only these APIs reach the branch, so only files naming one can matter. */
19
- const imageApi = /next\/(?:legacy\/)?image|getImageProps|unstable_getImgProps/;
19
+ const imageApi = /next\/(?:legacy\/)?image|getImageProps|unstable_getImgProps/
20
20
 
21
21
  /** A literal `placeholder="blur"`, in JSX-prop or object-property form. */
22
- const literalBlur = /\bplaceholder\s*[=:]\s*\{?\s*['"`]blur['"`]/;
22
+ const literalBlur = /\bplaceholder\s*[=:]\s*\{?\s*['"`]blur['"`]/
23
23
 
24
24
  /**
25
25
  * A `placeholder` whose value is not a string literal — `placeholder={value}`,
26
26
  * `placeholder: value`. Unreadable from source text, so it counts as usage.
27
27
  */
28
- const opaquePlaceholder = /\bplaceholder\s*[=:]\s*(?!\{?\s*['"`])/;
28
+ const opaquePlaceholder = /\bplaceholder\s*[=:]\s*(?!\{?\s*['"`])/
29
29
 
30
30
  /**
31
31
  * Props reaching the image from somewhere this scan cannot see: a spread into
32
32
  * any element in an image-using file, or a re-export that lets another file
33
33
  * render `<Image>` without ever naming `next/image`.
34
34
  */
35
- const opaqueProps = /\{\s*\.\.\.|export\s[^;]*from\s*['"]next\/(?:legacy\/)?image/;
35
+ const opaqueProps = /\{\s*\.\.\.|export\s[^;]*from\s*['"]next\/(?:legacy\/)?image/
36
36
 
37
- const cache = new Map<string, boolean>();
37
+ const cache = new Map<string, boolean>()
38
38
 
39
39
  /**
40
40
  * Roots to scan: the app, plus the workspace's own packages when the app sits in one - a linked
@@ -42,61 +42,92 @@ const cache = new Map<string, boolean>();
42
42
  * there must be seen.
43
43
  */
44
44
  function scanRoots(root: string) {
45
- const roots = [root];
45
+ const roots = [root]
46
46
  for (let dir = path.dirname(root); dir !== path.dirname(dir); dir = path.dirname(dir)) {
47
- if (!existsSync(path.join(dir, 'pnpm-workspace.yaml')) && !existsSync(path.join(dir, 'lerna.json'))) {
48
- continue;
47
+ if (
48
+ !existsSync(path.join(dir, 'pnpm-workspace.yaml')) &&
49
+ !existsSync(path.join(dir, 'lerna.json'))
50
+ ) {
51
+ continue
49
52
  }
50
- const packages = path.join(dir, 'packages');
51
- if (existsSync(packages)) roots.push(packages);
52
- break;
53
+ const packages = path.join(dir, 'packages')
54
+ if (existsSync(packages)) roots.push(packages)
55
+ break
53
56
  }
54
- return roots;
57
+ return roots
55
58
  }
56
59
 
57
60
  export function appUsesBlurPlaceholder(root: string) {
58
- const cached = cache.get(root);
59
- if (cached !== undefined) return cached;
60
- const used = scanFirstPartySource(root, blurSource);
61
- cache.set(root, used);
62
- return used;
61
+ const cached = cache.get(root)
62
+ if (cached !== undefined) return cached
63
+ const used = scanFirstPartySource(root, blurSource)
64
+ cache.set(root, used)
65
+ return used
63
66
  }
64
67
 
65
68
  function blurSource(source: string): boolean {
66
69
  // The common case is one `test` and out: almost no file in an app names an
67
70
  // image API, and only those that do pay for the rest.
68
- if (!imageApi.test(source)) return false;
69
- return literalBlur.test(source) || opaquePlaceholder.test(source) || opaqueProps.test(source);
71
+ if (!imageApi.test(source)) return false
72
+ return literalBlur.test(source) || opaquePlaceholder.test(source) || opaqueProps.test(source)
70
73
  }
71
74
 
72
75
  /** Walk the app's first-party source (plus workspace packages) until `match`. */
73
76
  export function scanFirstPartySource(root: string, match: (source: string) => boolean): boolean {
74
- return scanRoots(root).some(dir => scan(dir, match));
77
+ return scanRoots(root).some(dir => scan(dir, match))
75
78
  }
76
79
 
77
80
  function scan(dir: string, match: (source: string) => boolean): boolean {
78
- let entries: Dirent[];
81
+ let entries: Dirent[]
79
82
  try {
80
- entries = readdirSync(dir, { withFileTypes: true });
83
+ entries = readdirSync(dir, { withFileTypes: true })
81
84
  } catch {
82
- return false;
85
+ return false
83
86
  }
84
87
  for (const entry of entries) {
85
- if (entry.name.startsWith('.')) continue;
86
- const file = path.join(dir, entry.name);
88
+ if (entry.name.startsWith('.')) continue
89
+ const file = path.join(dir, entry.name)
87
90
  if (entry.isDirectory()) {
88
- if (skipDirs.has(entry.name)) continue;
89
- if (scan(file, match)) return true;
90
- continue;
91
+ if (skipDirs.has(entry.name)) continue
92
+ if (scan(file, match)) return true
93
+ continue
91
94
  }
92
- if (!sourceFile.test(entry.name)) continue;
93
- let source: string;
95
+ if (!sourceFile.test(entry.name)) continue
96
+ let source: string
94
97
  try {
95
- source = readFileSync(file, 'utf8');
98
+ source = readFileSync(file, 'utf8')
96
99
  } catch {
97
- continue;
100
+ continue
98
101
  }
99
- if (match(source)) return true;
102
+ if (match(source)) return true
100
103
  }
101
- return false;
104
+ return false
105
+ }
106
+
107
+ /**
108
+ * Build-time app fact: can any first-party source render `<Link legacyBehavior>`? The legacy child path
109
+ * (child validation, the deprecation notice, the server/lazy child diagnostics, cloneElement) is a
110
+ * meaningful slice of `next/link`, and next/link is initial on every page that links anywhere.
111
+ *
112
+ * One-sided like the blur gate: every unreadable case answers "yes". A wrong "no" renders the legacy
113
+ * child shape on the server and a plain anchor on the client - a hydration mismatch. The scan sees the
114
+ * app and its workspace packages, not registry dependencies.
115
+ */
116
+ const legacyProp = /\blegacyBehavior\b/
117
+
118
+ /** A Link re-exported from here can be rendered by a file this scan can't tie
119
+ * back to `next/link`, so treat the re-export itself as usage. */
120
+ const reexportedLink = /export\s[^;]*from\s*['"]next\/link['"]/
121
+
122
+ const legacyLinkCache = new Map<string, boolean>()
123
+
124
+ export function appUsesLegacyLink(root: string) {
125
+ const cached = legacyLinkCache.get(root)
126
+ if (cached !== undefined) return cached
127
+ const used = scanFirstPartySource(
128
+ root,
129
+ source => legacyProp.test(source) || reexportedLink.test(source),
130
+ )
131
+ legacyLinkCache.set(root, used)
132
+ return used
102
133
  }
@@ -7,23 +7,23 @@
7
7
  // (request/context, ppr, cache/revalidate) into the browser bundle.
8
8
 
9
9
  /** Native URLPattern when the runtime provides one (Bun/Node 23+/browsers). */
10
- export const URLPattern = (globalThis as { URLPattern?: unknown }).URLPattern;
10
+ export const URLPattern = (globalThis as { URLPattern?: unknown }).URLPattern
11
11
 
12
12
  export interface UserAgent {
13
- ua: string;
14
- browser: { name?: string; version?: string };
15
- os: { name?: string; version?: string };
16
- device: { type?: string; vendor?: string; model?: string };
17
- engine: { name?: string; version?: string };
18
- cpu: { architecture?: string };
19
- isBot: boolean;
13
+ ua: string
14
+ browser: { name?: string; version?: string }
15
+ os: { name?: string; version?: string }
16
+ device: { type?: string; vendor?: string; model?: string }
17
+ engine: { name?: string; version?: string }
18
+ cpu: { architecture?: string }
19
+ isBot: boolean
20
20
  }
21
21
 
22
22
  const botPattern =
23
- /bot|crawler|spider|crawling|slurp|bingpreview|facebookexternalhit|mediapartners|headless/i;
23
+ /bot|crawler|spider|crawling|slurp|bingpreview|facebookexternalhit|mediapartners|headless/i
24
24
 
25
25
  export function userAgentFromString(input: string | undefined): UserAgent {
26
- const ua = input ?? '';
26
+ const ua = input ?? ''
27
27
  return {
28
28
  ua,
29
29
  browser: parseBrowser(ua),
@@ -32,69 +32,73 @@ export function userAgentFromString(input: string | undefined): UserAgent {
32
32
  engine: parseEngine(ua),
33
33
  cpu: parseCpu(ua),
34
34
  isBot: botPattern.test(ua),
35
- };
35
+ }
36
36
  }
37
37
 
38
38
  export function userAgent({ headers }: { headers: Headers }): UserAgent {
39
- return userAgentFromString(headers.get('user-agent') ?? undefined);
39
+ return userAgentFromString(headers.get('user-agent') ?? undefined)
40
40
  }
41
41
 
42
42
  function parseBrowser(ua: string): UserAgent['browser'] {
43
- const edge = ua.match(/Edg(?:e|A|iOS)?\/([\d.]+)/);
44
- if (edge) return { name: 'Edge', version: edge[1] };
45
- const samsung = ua.match(/SamsungBrowser\/([\d.]+)/);
46
- if (samsung) return { name: 'Samsung Internet', version: samsung[1] };
47
- const chrome = ua.match(/(?:Chrome|CriOS)\/([\d.]+)/);
48
- if (chrome) return { name: 'Chrome', version: chrome[1] };
49
- const firefox = ua.match(/(?:Firefox|FxiOS)\/([\d.]+)/);
50
- if (firefox) return { name: 'Firefox', version: firefox[1] };
51
- if (ua.includes('Safari')) return { name: 'Safari', version: ua.match(/Version\/([\d.]+)/)?.[1] };
52
- return {};
43
+ const edge = ua.match(/Edg(?:e|A|iOS)?\/([\d.]+)/)
44
+ if (edge) return { name: 'Edge', version: edge[1] }
45
+ const samsung = ua.match(/SamsungBrowser\/([\d.]+)/)
46
+ if (samsung) return { name: 'Samsung Internet', version: samsung[1] }
47
+ const chrome = ua.match(/(?:Chrome|CriOS)\/([\d.]+)/)
48
+ if (chrome) return { name: 'Chrome', version: chrome[1] }
49
+ const firefox = ua.match(/(?:Firefox|FxiOS)\/([\d.]+)/)
50
+ if (firefox) return { name: 'Firefox', version: firefox[1] }
51
+ if (ua.includes('Safari')) return { name: 'Safari', version: ua.match(/Version\/([\d.]+)/)?.[1] }
52
+ return {}
53
53
  }
54
54
 
55
55
  function parseEngine(ua: string): UserAgent['engine'] {
56
- const gecko = ua.match(/rv:([\d.]+)\).*Gecko/);
57
- if (gecko) return { name: 'Gecko', version: gecko[1] };
58
- const webkit = ua.match(/AppleWebKit\/([\d.]+)/);
56
+ const gecko = ua.match(/rv:([\d.]+)\).*Gecko/)
57
+ if (gecko) return { name: 'Gecko', version: gecko[1] }
58
+ const webkit = ua.match(/AppleWebKit\/([\d.]+)/)
59
59
  if (webkit) {
60
- const chrome = ua.match(/(?:Chrome|CriOS|Edg(?:e|A|iOS)?|OPR)\/([\d.]+)/);
61
- if (chrome) return { name: 'Blink', version: chrome[1] };
62
- return { name: 'WebKit', version: webkit[1] };
60
+ const chrome = ua.match(/(?:Chrome|CriOS|Edg(?:e|A|iOS)?|OPR)\/([\d.]+)/)
61
+ if (chrome) return { name: 'Blink', version: chrome[1] }
62
+ return { name: 'WebKit', version: webkit[1] }
63
63
  }
64
- return {};
64
+ return {}
65
65
  }
66
66
 
67
67
  function parseCpu(ua: string): UserAgent['cpu'] {
68
- if (/arm64|aarch64/i.test(ua)) return { architecture: 'arm64' };
69
- if (/\barm\b/i.test(ua)) return { architecture: 'arm' };
70
- if (/x86_64|x64|Win64|WOW64/i.test(ua)) return { architecture: 'amd64' };
71
- if (/i686|\bx86\b/i.test(ua)) return { architecture: 'ia32' };
72
- return {};
68
+ if (/arm64|aarch64/i.test(ua)) return { architecture: 'arm64' }
69
+ if (/\barm\b/i.test(ua)) return { architecture: 'arm' }
70
+ if (/x86_64|x64|Win64|WOW64/i.test(ua)) return { architecture: 'amd64' }
71
+ if (/i686|\bx86\b/i.test(ua)) return { architecture: 'ia32' }
72
+ return {}
73
73
  }
74
74
 
75
75
  function parseOs(ua: string): UserAgent['os'] {
76
- if (ua.includes('Windows')) return { name: 'Windows', version: ua.match(/Windows NT ([\d.]+)/)?.[1] };
77
- if (ua.includes('Android')) return { name: 'Android', version: ua.match(/Android ([\d.]+)/)?.[1] };
76
+ if (ua.includes('Windows'))
77
+ return { name: 'Windows', version: ua.match(/Windows NT ([\d.]+)/)?.[1] }
78
+ if (ua.includes('Android')) return { name: 'Android', version: ua.match(/Android ([\d.]+)/)?.[1] }
78
79
  if (/iPhone|iPad|iPod/.test(ua)) {
79
- return { name: 'iOS', version: ua.match(/OS (\d+(?:[_.]\d+)*)/)?.[1]?.replace(/_/g, '.') };
80
+ return { name: 'iOS', version: ua.match(/OS (\d+(?:[_.]\d+)*)/)?.[1]?.replace(/_/g, '.') }
80
81
  }
81
82
  if (ua.includes('Mac OS X')) {
82
- return { name: 'Mac OS', version: ua.match(/Mac OS X (\d+(?:[_.]\d+)*)/)?.[1]?.replace(/_/g, '.') };
83
+ return {
84
+ name: 'Mac OS',
85
+ version: ua.match(/Mac OS X (\d+(?:[_.]\d+)*)/)?.[1]?.replace(/_/g, '.'),
86
+ }
83
87
  }
84
- if (ua.includes('Linux')) return { name: 'Linux' };
85
- return {};
88
+ if (ua.includes('Linux')) return { name: 'Linux' }
89
+ return {}
86
90
  }
87
91
 
88
92
  function parseDevice(ua: string): UserAgent['device'] {
89
- if (ua.includes('iPhone')) return { type: 'mobile', vendor: 'Apple', model: 'iPhone' };
90
- if (ua.includes('iPad')) return { type: 'tablet', vendor: 'Apple', model: 'iPad' };
93
+ if (ua.includes('iPhone')) return { type: 'mobile', vendor: 'Apple', model: 'iPhone' }
94
+ if (ua.includes('iPad')) return { type: 'tablet', vendor: 'Apple', model: 'iPad' }
91
95
  if (ua.includes('Android')) {
92
- const type = ua.includes('Mobile') ? 'mobile' : 'tablet';
93
- const samsung = ua.match(/\b(SM-[\w]+)\b/);
94
- if (samsung) return { type, vendor: 'Samsung', model: samsung[1] };
95
- const pixel = ua.match(/;\s*(Pixel[\w ]*?)\s*(?:Build|\))/);
96
- if (pixel) return { type, vendor: 'Google', model: pixel[1] };
97
- return { type };
96
+ const type = ua.includes('Mobile') ? 'mobile' : 'tablet'
97
+ const samsung = ua.match(/\b(SM-[\w]+)\b/)
98
+ if (samsung) return { type, vendor: 'Samsung', model: samsung[1] }
99
+ const pixel = ua.match(/;\s*(Pixel[\w ]*?)\s*(?:Build|\))/)
100
+ if (pixel) return { type, vendor: 'Google', model: pixel[1] }
101
+ return { type }
98
102
  }
99
- return ua.includes('Mobile') ? { type: 'mobile' } : {};
103
+ return ua.includes('Mobile') ? { type: 'mobile' } : {}
100
104
  }
@@ -1,30 +1,28 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
3
  // `next/web-vitals` compat surface. Next measures Core Web Vitals (plus its own Next.js-* custom
4
4
  // metrics) and invokes the reporter callback per registered hook instance. The Core Web Vitals are
5
5
  // backed by the `web-vitals` package - this is browser-bundled client code, so the import stays a plain
6
6
  // static import for the bundler to resolve. Next's own custom metrics are not emitted here.
7
- import { useEffect, useRef } from 'preact/hooks';
8
- import * as webVitals from 'web-vitals';
9
- import type { Metric } from 'web-vitals';
7
+ import { useEffect, useRef } from 'preact/hooks'
8
+ import * as webVitals from 'web-vitals'
9
+ import type { Metric } from 'web-vitals'
10
10
 
11
11
  export interface NextWebVitalsMetric {
12
- id: string;
13
- name: string;
14
- startTime: number;
15
- value: number;
16
- label: 'web-vital' | 'custom';
12
+ id: string
13
+ name: string
14
+ startTime: number
15
+ value: number
16
+ label: 'web-vital' | 'custom'
17
17
  }
18
18
 
19
- export function useReportWebVitals(
20
- reportWebVitalsFn: (metric: NextWebVitalsMetric) => void,
21
- ): void {
19
+ export function useReportWebVitals(reportWebVitalsFn: (metric: NextWebVitalsMetric) => void): void {
22
20
  // Route metrics through a ref so the latest reporter identity receives them
23
21
  // without resubscribing to web-vitals on every render.
24
- const reporterRef = useRef(reportWebVitalsFn);
22
+ const reporterRef = useRef(reportWebVitalsFn)
25
23
  useEffect(() => {
26
- reporterRef.current = reportWebVitalsFn;
27
- }, [reportWebVitalsFn]);
24
+ reporterRef.current = reportWebVitalsFn
25
+ }, [reportWebVitalsFn])
28
26
 
29
27
  useEffect(() => {
30
28
  const report = (metric: Metric): void => {
@@ -34,23 +32,23 @@ export function useReportWebVitals(
34
32
  startTime: metric.entries[0]?.startTime ?? 0,
35
33
  value: metric.value,
36
34
  label: 'web-vital',
37
- });
38
- };
35
+ })
36
+ }
39
37
 
40
- webVitals.onTTFB(report);
41
- webVitals.onFCP(report);
42
- webVitals.onLCP(report);
38
+ webVitals.onTTFB(report)
39
+ webVitals.onFCP(report)
40
+ webVitals.onLCP(report)
43
41
  // CLS and INP accumulate over the page lifetime and, by default, only settle
44
42
  // when the page is hidden. A page that is never hidden (or one torn down by a
45
43
  // navigation before the visibilitychange flush lands) therefore never reports
46
44
  // them at all. Both metrics are documented as multi-report: `reportAllChanges`
47
45
  // emits each new value as it is determined instead of a single deferred one,
48
46
  // so opting in makes delivery deterministic without dropping any information.
49
- webVitals.onCLS(report, { reportAllChanges: true });
50
- webVitals.onINP(report, { reportAllChanges: true });
47
+ webVitals.onCLS(report, { reportAllChanges: true })
48
+ webVitals.onINP(report, { reportAllChanges: true })
51
49
  // `onFID` is deprecated (removed in newer majors); subscribe only if present.
52
50
  if (typeof webVitals.onFID === 'function') {
53
- webVitals.onFID(report);
51
+ webVitals.onFID(report)
54
52
  }
55
- }, []);
53
+ }, [])
56
54
  }
@@ -10,31 +10,31 @@
10
10
  // share ONE api singleton - the same module instance the app's provider.register() mutated. A bare
11
11
  // import would resolve against pnext's location and never see the registered provider.
12
12
 
13
- import { createRequire } from 'node:module';
14
- import path from 'node:path';
13
+ import { createRequire } from 'node:module'
14
+ import path from 'node:path'
15
15
 
16
16
  // Structural subset of @opentelemetry/api we use. Kept local so pnext carries no
17
17
  // type dependency on the package (it may be absent).
18
18
  export interface OtelSpanContext {
19
- traceId: string;
20
- spanId: string;
21
- traceFlags: number;
19
+ traceId: string
20
+ spanId: string
21
+ traceFlags: number
22
22
  }
23
23
 
24
24
  export interface OtelSpan {
25
- setAttribute(key: string, value: unknown): OtelSpan;
26
- setAttributes(attrs: Record<string, unknown>): OtelSpan;
27
- setStatus(status: { code: number; message?: string }): OtelSpan;
28
- recordException(error: unknown): void;
29
- updateName(name: string): OtelSpan;
30
- end(endTime?: number): void;
31
- spanContext(): OtelSpanContext;
32
- isRecording(): boolean;
25
+ setAttribute(key: string, value: unknown): OtelSpan
26
+ setAttributes(attrs: Record<string, unknown>): OtelSpan
27
+ setStatus(status: { code: number; message?: string }): OtelSpan
28
+ recordException(error: unknown): void
29
+ updateName(name: string): OtelSpan
30
+ end(endTime?: number): void
31
+ spanContext(): OtelSpanContext
32
+ isRecording(): boolean
33
33
  }
34
34
 
35
35
  export interface OtelContext {
36
36
  // opaque
37
- readonly __brand?: 'otel-context';
37
+ readonly __brand?: 'otel-context'
38
38
  }
39
39
 
40
40
  export interface OtelTracer {
@@ -42,54 +42,54 @@ export interface OtelTracer {
42
42
  name: string,
43
43
  options?: { kind?: number; attributes?: Record<string, unknown>; startTime?: number },
44
44
  context?: OtelContext,
45
- ): OtelSpan;
45
+ ): OtelSpan
46
46
  }
47
47
 
48
48
  export interface OtelApi {
49
49
  trace: {
50
- getTracer(name: string, version?: string): OtelTracer;
51
- getSpan(context: OtelContext): OtelSpan | undefined;
52
- getSpanContext(context: OtelContext): OtelSpanContext | undefined;
53
- setSpan(context: OtelContext, span: OtelSpan): OtelContext;
54
- setSpanContext(context: OtelContext, sc: OtelSpanContext): OtelContext;
55
- };
50
+ getTracer(name: string, version?: string): OtelTracer
51
+ getSpan(context: OtelContext): OtelSpan | undefined
52
+ getSpanContext(context: OtelContext): OtelSpanContext | undefined
53
+ setSpan(context: OtelContext, span: OtelSpan): OtelContext
54
+ setSpanContext(context: OtelContext, sc: OtelSpanContext): OtelContext
55
+ }
56
56
  context: {
57
- active(): OtelContext;
58
- with<T>(context: OtelContext, fn: () => T): T;
59
- };
57
+ active(): OtelContext
58
+ with<T>(context: OtelContext, fn: () => T): T
59
+ }
60
60
  propagation: {
61
- extract(context: OtelContext, carrier: unknown, getter?: unknown): OtelContext;
62
- inject(context: OtelContext, carrier: unknown, setter?: unknown): void;
63
- fields(): string[];
64
- };
65
- ROOT_CONTEXT: OtelContext;
66
- SpanKind: { INTERNAL: number; SERVER: number; CLIENT: number; PRODUCER: number; CONSUMER: number };
67
- SpanStatusCode: { UNSET: number; OK: number; ERROR: number };
68
- TraceFlags: { NONE: number; SAMPLED: number };
61
+ extract(context: OtelContext, carrier: unknown, getter?: unknown): OtelContext
62
+ inject(context: OtelContext, carrier: unknown, setter?: unknown): void
63
+ fields(): string[]
64
+ }
65
+ ROOT_CONTEXT: OtelContext
66
+ SpanKind: { INTERNAL: number; SERVER: number; CLIENT: number; PRODUCER: number; CONSUMER: number }
67
+ SpanStatusCode: { UNSET: number; OK: number; ERROR: number }
68
+ TraceFlags: { NONE: number; SAMPLED: number }
69
69
  }
70
70
 
71
- let resolved: OtelApi | null | undefined;
71
+ let resolved: OtelApi | null | undefined
72
72
 
73
73
  /**
74
74
  * Load `@opentelemetry/api` from the app root (once). Returns null when the
75
75
  * package is not installed — callers then no-op. Never throws.
76
76
  */
77
77
  export function getOtelApi(appRoot: string): OtelApi | null {
78
- if (resolved !== undefined) return resolved;
79
- resolved = null;
78
+ if (resolved !== undefined) return resolved
79
+ resolved = null
80
80
  try {
81
81
  // Resolve against a file inside the app root so Node walks the app's
82
82
  // node_modules (where instrumentation.ts's @opentelemetry/api lives).
83
- const req = createRequire(path.join(appRoot, 'package.json'));
84
- const api = req('@opentelemetry/api') as OtelApi;
85
- if (api?.trace && api.context) resolved = api;
83
+ const req = createRequire(path.join(appRoot, 'package.json'))
84
+ const api = req('@opentelemetry/api') as OtelApi
85
+ if (api?.trace && api.context) resolved = api
86
86
  } catch {
87
- resolved = null;
87
+ resolved = null
88
88
  }
89
- return resolved;
89
+ return resolved
90
90
  }
91
91
 
92
92
  /** Test/bootstrap reset. */
93
93
  export function resetOtelApi(): void {
94
- resolved = undefined;
94
+ resolved = undefined
95
95
  }
@@ -10,8 +10,8 @@
10
10
  // nothing, while dev emits for static too. The tags are produced once per document render, so soft navs
11
11
  // never mutate them.
12
12
 
13
- import { getNextConfig } from '../next/config-loader';
14
- import { activeOtelContext, carrierSetter } from './tracer';
13
+ import { getNextConfig } from '../next/config-loader'
14
+ import { activeOtelContext, carrierSetter } from './tracer'
15
15
 
16
16
  /**
17
17
  * Return the clientTraceMetadata `<meta>` tag HTML for the current render, or ''
@@ -22,44 +22,42 @@ import { activeOtelContext, carrierSetter } from './tracer';
22
22
  * defensively.
23
23
  */
24
24
  export function clientTraceMetadataTags(input: {
25
- dynamic: boolean;
26
- isNextStart: boolean;
27
- rsc: boolean;
25
+ dynamic: boolean
26
+ isNextStart: boolean
27
+ rsc: boolean
28
28
  }): string {
29
- const keys = configuredKeys();
30
- if (keys.length === 0) return '';
31
- if (input.rsc) return '';
29
+ const keys = configuredKeys()
30
+ if (keys.length === 0) return ''
31
+ if (input.rsc) return ''
32
32
  // Prod + static → no injection. Dev injects for static too (handled by the
33
33
  // caller passing dynamic=true in dev, since a dev render is never prebuilt).
34
- if (input.isNextStart && !input.dynamic) return '';
34
+ if (input.isNextStart && !input.dynamic) return ''
35
35
 
36
- const active = activeOtelContext();
37
- if (!active) return '';
38
- const { api, context } = active;
36
+ const active = activeOtelContext()
37
+ if (!active) return ''
38
+ const { api, context } = active
39
39
 
40
- const carrier: Record<string, string> = {};
40
+ const carrier: Record<string, string> = {}
41
41
  try {
42
- api.propagation.inject(context, carrier, carrierSetter);
42
+ api.propagation.inject(context, carrier, carrierSetter)
43
43
  } catch {
44
- return '';
44
+ return ''
45
45
  }
46
46
 
47
- const tags: string[] = [];
47
+ const tags: string[] = []
48
48
  for (const key of keys) {
49
- const value = carrier[key];
50
- if (value === undefined || value === null) continue;
51
- tags.push(`<meta name="${escapeAttr(key)}" content="${escapeAttr(String(value))}"/>`);
49
+ const value = carrier[key]
50
+ if (value === undefined || value === null) continue
51
+ tags.push(`<meta name="${escapeAttr(key)}" content="${escapeAttr(String(value))}"/>`)
52
52
  }
53
- return tags.join('');
53
+ return tags.join('')
54
54
  }
55
55
 
56
56
  function configuredKeys(): string[] {
57
- const experimental = getNextConfig().experimental as
58
- | { clientTraceMetadata?: unknown }
59
- | undefined;
60
- const list = experimental?.clientTraceMetadata;
61
- if (!Array.isArray(list)) return [];
62
- return list.filter((k): k is string => typeof k === 'string');
57
+ const experimental = getNextConfig().experimental as { clientTraceMetadata?: unknown } | undefined
58
+ const list = experimental?.clientTraceMetadata
59
+ if (!Array.isArray(list)) return []
60
+ return list.filter((k): k is string => typeof k === 'string')
63
61
  }
64
62
 
65
63
  function escapeAttr(value: string): string {
@@ -67,5 +65,5 @@ function escapeAttr(value: string): string {
67
65
  .replace(/&/g, '&amp;')
68
66
  .replace(/"/g, '&quot;')
69
67
  .replace(/</g, '&lt;')
70
- .replace(/>/g, '&gt;');
68
+ .replace(/>/g, '&gt;')
71
69
  }