@wular/pnext 0.0.19 → 0.0.20

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 (75) hide show
  1. package/README.md +2 -2
  2. package/package.json +1 -1
  3. package/reference/compat.md +2 -2
  4. package/reference/getting-started.md +2 -2
  5. package/src/cli/adapters/vercel.ts +27 -0
  6. package/src/cli/analyze.ts +8 -7
  7. package/src/cli/boot/trace.ts +9 -3
  8. package/src/cli/build.ts +23 -15
  9. package/src/cli/dev.ts +23 -0
  10. package/src/cli/migrate/report.ts +1 -1
  11. package/src/cli/migrate/run.ts +2 -2
  12. package/src/cli/migrate/scan.ts +128 -1
  13. package/src/cli/serve/pipeline.ts +42 -42
  14. package/src/cli/start.ts +4 -2
  15. package/src/client/build.ts +51 -25
  16. package/src/client/entry.ts +27 -4
  17. package/src/client/router/page-slot.ts +81 -0
  18. package/src/client/router/runtime.ts +107 -112
  19. package/src/compat/bundler/cjs-exports.ts +26 -20
  20. package/src/compat/client/css-order.ts +1 -1
  21. package/src/compat/client/navigation-scroll.ts +36 -40
  22. package/src/compat/css/modules.ts +6 -2
  23. package/src/compat/next/font/cache.ts +10 -22
  24. package/src/compat/next/font/runtime.ts +20 -0
  25. package/src/compat/next/legacy-request-apis.ts +41 -5
  26. package/src/compat/next/script.tsx +16 -24
  27. package/src/compat/react/client-lite.ts +1 -0
  28. package/src/compat/react/client.ts +11 -0
  29. package/src/compat/react/dom-client.ts +11 -2
  30. package/src/compat/react/dom-react-server.ts +4 -0
  31. package/src/compat/react/dom.ts +11 -2
  32. package/src/compat/react/internals.ts +65 -0
  33. package/src/compat/react/parity.ts +47 -0
  34. package/src/compat/react/preact.ts +31 -1
  35. package/src/compat/react/react-server.ts +7 -0
  36. package/src/compat/react/server.ts +16 -2
  37. package/src/compat/react/style-values.ts +68 -0
  38. package/src/compat/register/render.ts +14 -3
  39. package/src/compat/register/routing.ts +57 -7
  40. package/src/compat/tsconfig-defaults.ts +4 -0
  41. package/src/compat/typecheck/check.ts +26 -71
  42. package/src/compat/typecheck/worker.ts +3 -2
  43. package/src/compat-bootstrap.ts +4 -0
  44. package/src/css/build.ts +153 -14
  45. package/src/css/postcss.ts +32 -3
  46. package/src/dev/restart/client-key.ts +1 -1
  47. package/src/dev/restart/global-css.ts +12 -94
  48. package/src/dev/restart/record.ts +106 -0
  49. package/src/dev/restart/route-facts.ts +11 -90
  50. package/src/dev/server.ts +208 -41
  51. package/src/extensions.ts +69 -3
  52. package/src/render/hooks.ts +1 -1
  53. package/src/render/metadata.ts +89 -17
  54. package/src/render/renderer.ts +322 -136
  55. package/src/render/resource-hints.ts +62 -9
  56. package/src/render/slots.tsx +2 -1
  57. package/src/resolve/scan-facts.ts +13 -5
  58. package/src/routing/forwarded.ts +20 -7
  59. package/src/routing/handler.ts +6 -2
  60. package/src/routing/href.ts +11 -1
  61. package/src/routing/metadata-files.ts +16 -3
  62. package/src/routing/proxy.ts +6 -3
  63. package/src/routing/routes.ts +253 -34
  64. package/src/runtime/fetch-host.ts +42 -0
  65. package/src/runtime/fingerprint.ts +132 -0
  66. package/src/runtime/loader.ts +7 -5
  67. package/src/runtime/module-cache.ts +3 -36
  68. package/src/runtime/modules.ts +333 -77
  69. package/src/runtime/vendor-build.ts +34 -5
  70. package/src/runtime/vendor.ts +1 -18
  71. package/src/types.ts +6 -0
  72. package/src/utils/asset-hash.ts +22 -0
  73. package/src/utils/code.ts +41 -0
  74. package/src/utils/html.ts +4 -1
  75. package/src/utils/serialize.ts +66 -7
@@ -60,12 +60,23 @@ export function metadataContext(page: MetadataRenderPage): MetadataContext {
60
60
  }
61
61
  }
62
62
 
63
- export function headLinks(page: MetadataRenderPage, context: MetadataContext) {
64
- const canonical = coerceCanonical(page.metadata.alternates, context)
65
- const links: (MetadataLink | ResourceHint)[] = [
66
- ...page.fontPreloads,
67
- ...(page.resourceHints ?? []),
68
- ...stylesheetLinks(page.stylesheets),
63
+ // Links describing the render's own bytes, not metadata - so they stay in the
64
+ // head even when metadata streams into the body.
65
+ export function assetLinks(page: MetadataRenderPage) {
66
+ return assetLinkGroups(page).filter(Boolean).join('\n')
67
+ }
68
+
69
+ export function assetLinkGroups(page: MetadataRenderPage) {
70
+ const connects: ResourceHint[] = []
71
+ const preloads: ResourceHint[] = []
72
+ const lateHints: ResourceHint[] = []
73
+ for (const hint of page.resourceHints ?? []) {
74
+ if (hint.rel === 'preconnect' || hint.rel === 'dns-prefetch') connects.push(hint)
75
+ else if (hint.rel === 'preload' && (hint.as === 'font' || hint.as === 'image'))
76
+ preloads.push(hint)
77
+ else lateHints.push(hint)
78
+ }
79
+ const bulk: (MetadataLink | ResourceHint)[] = [
69
80
  ...(page.modulePreloads ?? []).map(url => ({ rel: 'modulepreload', url })),
70
81
  ...(page.dynamicScriptPreloads ?? []).map(url => ({
71
82
  rel: 'preload',
@@ -76,6 +87,20 @@ export function headLinks(page: MetadataRenderPage, context: MetadataContext) {
76
87
  crossOrigin: 'anonymous' as const,
77
88
  fetchPriority: 'low' as const,
78
89
  })),
90
+ ]
91
+ return [
92
+ renderLinks(connects),
93
+ renderLinks([...page.fontPreloads, ...preloads]),
94
+ renderLinks(stylesheetLinks(page.stylesheets)),
95
+ renderLinks(bulk),
96
+ renderLinks(lateHints),
97
+ ]
98
+ }
99
+
100
+ // Links derived from `metadata` - these travel with it into the body.
101
+ export function metadataOnlyLinks(page: MetadataRenderPage, context: MetadataContext) {
102
+ const canonical = coerceCanonical(page.metadata.alternates, context)
103
+ const links: (MetadataLink | ResourceHint)[] = [
79
104
  ...(canonical ? [{ rel: 'canonical', url: canonical }] : []),
80
105
  ...staticMetadataLinks(page),
81
106
  ...authorLinks(page.metadata.authors, context),
@@ -86,6 +111,14 @@ export function headLinks(page: MetadataRenderPage, context: MetadataContext) {
86
111
  ...coerceIcons(page.metadata.icons, context),
87
112
  ...(page.metadata.links ?? []),
88
113
  ]
114
+ return renderLinks(links)
115
+ }
116
+
117
+ export function headLinks(page: MetadataRenderPage, context: MetadataContext) {
118
+ return [assetLinks(page), metadataOnlyLinks(page, context)].filter(Boolean).join('\n')
119
+ }
120
+
121
+ function renderLinks(links: (MetadataLink | ResourceHint)[]) {
89
122
  return links.map(link => ` <link ${linkAttrs(link)}/>`).join('\n')
90
123
  }
91
124
 
@@ -122,11 +155,13 @@ function staticMetadataLinks(page: MetadataRenderPage): MetadataLink[] {
122
155
  ...(!hasExplicitManifest && metadata.manifest ? [staticMetadataLink(metadata.manifest)] : []),
123
156
  ...metadata.icons.map(staticMetadataLink),
124
157
  ...(metadata.dynamicIcons ?? []),
125
- ...metadata.appleIcons.map(staticMetadataLink),
126
- ...(metadata.dynamicAppleIcons ?? []),
158
+ // Root icons share the icon bucket. Keeping them after apple icons made
159
+ // the link order differ from Next whenever both conventions were present.
127
160
  ...(!hasExplicitIcons && metadata.icons.length === 0
128
161
  ? metadata.rootIcons.map(staticMetadataLink)
129
162
  : []),
163
+ ...metadata.appleIcons.map(staticMetadataLink),
164
+ ...(metadata.dynamicAppleIcons ?? []),
130
165
  ])
131
166
  }
132
167
 
@@ -233,8 +268,9 @@ export function metadataTags(metadata: Metadata, context: MetadataContext): stri
233
268
  }
234
269
  for (const [property, value] of appLinkTags(meta.appLinks)) pushProperty(property, value)
235
270
 
236
- tags.push(...openGraphTags(meta.openGraph, context))
237
- tags.push(...twitterTags(meta.twitter ?? twitterFromOpenGraph(meta.openGraph), context))
271
+ const social = resolveSocialMetadata(meta)
272
+ tags.push(...openGraphTags(social.openGraph, context))
273
+ tags.push(...twitterTags(social.twitter, context))
238
274
 
239
275
  return tags.join('\n ')
240
276
  }
@@ -831,17 +867,53 @@ function twitterCard(twitter: MetadataTwitter) {
831
867
  return twitter.images === undefined ? 'summary' : 'summary_large_image'
832
868
  }
833
869
 
834
- function twitterFromOpenGraph(
835
- openGraph: MetadataOpenGraph | undefined,
836
- ): MetadataTwitter | undefined {
837
- if (!openGraph) return undefined
870
+ // og/twitter resolve in one final pass over the merged chain: twitter auto-fills
871
+ // from openGraph, then whichever of the two exists inherits the page
872
+ // title/description it still lacks. Emission is that pass - nothing between the
873
+ // merge and here reads these fields, and the parent handed to generateMetadata
874
+ // is pre-merge by design.
875
+ function resolveSocialMetadata(meta: Metadata): {
876
+ openGraph?: MetadataOpenGraph
877
+ twitter?: MetadataTwitter
878
+ } {
879
+ const og = meta.openGraph
880
+ let twitter = meta.twitter
881
+ if (og) {
882
+ const ownImages = twitter && 'images' in twitter && twitter.images
883
+ twitter = {
884
+ ...twitter,
885
+ // card follows twitter's OWN images: an og image inherited below never
886
+ // upgrades a declared twitter block to summary_large_image.
887
+ card: twitterCard(twitter ?? { images: og.images }),
888
+ title: titleText(twitter?.title) === undefined ? og.title : twitter?.title,
889
+ description: twitter?.description || og.description,
890
+ images: ownImages ? twitter?.images : og.images,
891
+ }
892
+ }
893
+ return { openGraph: og && inherited(og, meta), twitter: twitter && inherited(twitter, meta) }
894
+ }
895
+
896
+ // A block that renders no title/description of its own falls back to the page's.
897
+ function inherited<T extends { title?: Metadata['title']; description?: string }>(
898
+ block: T,
899
+ meta: Metadata,
900
+ ): T {
901
+ const own = titleText(block.title)
902
+ if (own !== undefined && block.description) return block
838
903
  return {
839
- title: openGraph.title,
840
- description: openGraph.description,
841
- images: openGraph.images,
904
+ ...block,
905
+ title: own === undefined ? titleText(meta.title) : block.title,
906
+ description: block.description || meta.description,
842
907
  }
843
908
  }
844
909
 
910
+ // The title a chain entry actually renders, or undefined when it renders none
911
+ // (a bare `template`, an empty string) and so counts as missing for inheritance.
912
+ function titleText(title: Metadata['title']): string | undefined {
913
+ if (title === undefined) return undefined
914
+ return resolveTitleChain([{ title }]) || undefined
915
+ }
916
+
845
917
  export function mergeViewport(...items: Viewport[]) {
846
918
  return items.reduce<Viewport>(
847
919
  (viewport, item) => ({