@nuxt/hints 0.0.0 → 1.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/client/200.html +1 -0
  4. package/dist/client/404.html +1 -0
  5. package/dist/client/_nuxt/2EtD6e53.js +1 -0
  6. package/dist/client/_nuxt/2GP93Pxi.js +1 -0
  7. package/dist/client/_nuxt/3e1v2bzS.js +1 -0
  8. package/dist/client/_nuxt/5i3qLPDT.js +1 -0
  9. package/dist/client/_nuxt/B0m2ddpp.js +1 -0
  10. package/dist/client/_nuxt/B1dDrJ26.js +1 -0
  11. package/dist/client/_nuxt/B6aJPvgy.js +1 -0
  12. package/dist/client/_nuxt/B7mTdjB0.js +1 -0
  13. package/dist/client/_nuxt/BEDo0Tqx.js +1 -0
  14. package/dist/client/_nuxt/BGJmEYvX.js +1 -0
  15. package/dist/client/_nuxt/BHrmToEH.js +1 -0
  16. package/dist/client/_nuxt/BIGW1oBm.js +1 -0
  17. package/dist/client/_nuxt/BLmx8bSh.js +1 -0
  18. package/dist/client/_nuxt/BLtJtn59.js +1 -0
  19. package/dist/client/_nuxt/BPQ3VLAy.js +1 -0
  20. package/dist/client/_nuxt/BXkSAIEj.js +1 -0
  21. package/dist/client/_nuxt/BfHTSMKl.js +1 -0
  22. package/dist/client/_nuxt/BfjtVDDH.js +1 -0
  23. package/dist/client/_nuxt/BgDCqdQA.js +1 -0
  24. package/dist/client/_nuxt/Bkuqu6BP.js +1 -0
  25. package/dist/client/_nuxt/Bp3cYrEr.js +1 -0
  26. package/dist/client/_nuxt/Br6cN0cg.js +1 -0
  27. package/dist/client/_nuxt/BthQWCQV.js +1 -0
  28. package/dist/client/_nuxt/Buea-lGh.js +1 -0
  29. package/dist/client/_nuxt/Bw305WKR.js +1 -0
  30. package/dist/client/_nuxt/BzJJZx-M.js +1 -0
  31. package/dist/client/_nuxt/C-Jbm3Hp.js +1 -0
  32. package/dist/client/_nuxt/C39BiMTA.js +1 -0
  33. package/dist/client/_nuxt/C8M2exoo.js +1 -0
  34. package/dist/client/_nuxt/C9dUb6Cb.js +1 -0
  35. package/dist/client/_nuxt/C9oPPf7i.js +1 -0
  36. package/dist/client/_nuxt/C9tS-k6U.js +1 -0
  37. package/dist/client/_nuxt/CDVJQ6XC.js +1 -0
  38. package/dist/client/_nuxt/CEG3Q07z.js +1 -0
  39. package/dist/client/_nuxt/CFHQjOhq.js +1 -0
  40. package/dist/client/_nuxt/CG6Dc4jp.js +1 -0
  41. package/dist/client/_nuxt/CGQlbfJh.js +6 -0
  42. package/dist/client/_nuxt/CH1njM8p.js +1 -0
  43. package/dist/client/_nuxt/CJC4nrSc.js +1 -0
  44. package/dist/client/_nuxt/CMFEf1DS.js +1 -0
  45. package/dist/client/_nuxt/COt5Ahok.js +1 -0
  46. package/dist/client/_nuxt/CS3Unz2-.js +1 -0
  47. package/dist/client/_nuxt/CTRr51gU.js +1 -0
  48. package/dist/client/_nuxt/CVO1_9PV.js +1 -0
  49. package/dist/client/_nuxt/CVdnzihN.js +1 -0
  50. package/dist/client/_nuxt/CXZktZb0.js +1 -0
  51. package/dist/client/_nuxt/CXtECtnM.js +1 -0
  52. package/dist/client/_nuxt/CYsAdtH9.js +1 -0
  53. package/dist/client/_nuxt/CafNBF8u.js +1 -0
  54. package/dist/client/_nuxt/CbfX1IO0.js +1 -0
  55. package/dist/client/_nuxt/CfQXZHmo.js +1 -0
  56. package/dist/client/_nuxt/CgjmDhmW.js +1 -0
  57. package/dist/client/_nuxt/Cj5Yp3dK.js +1 -0
  58. package/dist/client/_nuxt/CkXjmgJE.js +1 -0
  59. package/dist/client/_nuxt/Cl0AqbOI.js +1 -0
  60. package/dist/client/_nuxt/Cm3UrAx6.js +1 -0
  61. package/dist/client/_nuxt/CmIQRyeF.js +1 -0
  62. package/dist/client/_nuxt/Cmh6b_Ma.js +1 -0
  63. package/dist/client/_nuxt/CnK8MTSM.js +1 -0
  64. package/dist/client/_nuxt/CnnebwVN.js +1 -0
  65. package/dist/client/_nuxt/Cp-IABpG.js +1 -0
  66. package/dist/client/_nuxt/Csfq5Kiy.js +1 -0
  67. package/dist/client/_nuxt/CufHLc7y.js +1 -0
  68. package/dist/client/_nuxt/Cuk6v7N8.js +1 -0
  69. package/dist/client/_nuxt/Cv9koXgw.js +1 -0
  70. package/dist/client/_nuxt/Cvjx9yec.js +1 -0
  71. package/dist/client/_nuxt/Cw07ACep.js +1 -0
  72. package/dist/client/_nuxt/CxbxFI8M.js +1 -0
  73. package/dist/client/_nuxt/CyktbL80.js +1 -0
  74. package/dist/client/_nuxt/CylS5w8V.js +1 -0
  75. package/dist/client/_nuxt/D-2ljcwZ.js +1 -0
  76. package/dist/client/_nuxt/D0r3Knsf.js +1 -0
  77. package/dist/client/_nuxt/D4h5O-jR.js +1 -0
  78. package/dist/client/_nuxt/D5KoaKCx.js +1 -0
  79. package/dist/client/_nuxt/D7VJQ_DO.js +1 -0
  80. package/dist/client/_nuxt/D7oLnXFd.js +1 -0
  81. package/dist/client/_nuxt/D87Tk5Gz.js +1 -0
  82. package/dist/client/_nuxt/DAi9KRSo.js +1 -0
  83. package/dist/client/_nuxt/DDBovgxi.js +1 -0
  84. package/dist/client/_nuxt/DFWUc33u.js +1 -0
  85. package/dist/client/_nuxt/DGP4VlC8.js +1 -0
  86. package/dist/client/_nuxt/DGztddWO.js +1 -0
  87. package/dist/client/_nuxt/DH5Ifo-i.js +1 -0
  88. package/dist/client/_nuxt/DH652Aoo.js +6 -0
  89. package/dist/client/_nuxt/DHJKELXO.js +1 -0
  90. package/dist/client/_nuxt/DJJ7OUMB.js +1 -0
  91. package/dist/client/_nuxt/DNMeEaky.js +1 -0
  92. package/dist/client/_nuxt/DPfMkruS.js +1 -0
  93. package/dist/client/_nuxt/DQyhUUbL.js +1 -0
  94. package/dist/client/_nuxt/DRw_LuNl.js +1 -0
  95. package/dist/client/_nuxt/DU1UobuO.js +1 -0
  96. package/dist/client/_nuxt/DU4nAREn.js +9 -0
  97. package/dist/client/_nuxt/DUszq2jm.js +1 -0
  98. package/dist/client/_nuxt/DVMEJ2y_.js +1 -0
  99. package/dist/client/_nuxt/DWedfzmr.js +1 -0
  100. package/dist/client/_nuxt/DXbdFlpD.js +1 -0
  101. package/dist/client/_nuxt/DZxFcAj9.js +1 -0
  102. package/dist/client/_nuxt/DcaNXYhu.js +1 -0
  103. package/dist/client/_nuxt/Ddv68eIx.js +1 -0
  104. package/dist/client/_nuxt/Des-eS-w.js +1 -0
  105. package/dist/client/_nuxt/DiinP2Uv.js +1 -0
  106. package/dist/client/_nuxt/DnULxvSX.js +1 -0
  107. package/dist/client/_nuxt/Do-INFgi.js +1 -0
  108. package/dist/client/_nuxt/DqwNpetd.js +1 -0
  109. package/dist/client/_nuxt/Dx-B1_4e.js +1 -0
  110. package/dist/client/_nuxt/DxNHbxmM.js +1 -0
  111. package/dist/client/_nuxt/DxSwrfjg.js +1 -0
  112. package/dist/client/_nuxt/E3gJ1_iC.js +1 -0
  113. package/dist/client/_nuxt/GsRaNv29.js +1 -0
  114. package/dist/client/_nuxt/L9t79GZl.js +1 -0
  115. package/dist/client/_nuxt/MKoRwnMq.js +1 -0
  116. package/dist/client/_nuxt/MzD3tlZU.js +1 -0
  117. package/dist/client/_nuxt/NleAzG8P.js +1 -0
  118. package/dist/client/_nuxt/PoHY5YXO.js +1 -0
  119. package/dist/client/_nuxt/TsXTqZ29.js +1 -0
  120. package/dist/client/_nuxt/Xqf5ue2O.js +1 -0
  121. package/dist/client/_nuxt/Yzrsuije.js +1 -0
  122. package/dist/client/_nuxt/bN70gL4F.js +1 -0
  123. package/dist/client/_nuxt/builds/latest.json +1 -0
  124. package/dist/client/_nuxt/builds/meta/13453bb2-1adb-44c7-ac19-ec44784e7219.json +1 -0
  125. package/dist/client/_nuxt/eOWES_5F.js +1 -0
  126. package/dist/client/_nuxt/entry.CqH3PPiL.css +1 -0
  127. package/dist/client/_nuxt/error-404.CrTd3IxL.css +1 -0
  128. package/dist/client/_nuxt/error-500.evxQRSU6.css +1 -0
  129. package/dist/client/_nuxt/fuZLfV_i.js +1 -0
  130. package/dist/client/_nuxt/g9-lgVsj.js +1 -0
  131. package/dist/client/_nuxt/hJgmCMqR.js +1 -0
  132. package/dist/client/_nuxt/hegEt444.js +1 -0
  133. package/dist/client/_nuxt/hydration.B5wxUWyr.css +1 -0
  134. package/dist/client/_nuxt/m17aaUwq.js +1 -0
  135. package/dist/client/_nuxt/nO2mFgKf.js +1 -0
  136. package/dist/client/_nuxt/qj2RPQZX.js +1 -0
  137. package/dist/client/_nuxt/rlWm2Bc0.js +1 -0
  138. package/dist/client/_nuxt/sLvN_949.js +1 -0
  139. package/dist/client/_nuxt/tqtdBwhO.js +1 -0
  140. package/dist/client/_nuxt/umNIi3wV.js +21 -0
  141. package/dist/client/_nuxt/wDzz0qaB.js +1 -0
  142. package/dist/client/_nuxt/z9IIGYC-.js +1 -0
  143. package/dist/client/hydration/index.html +1 -0
  144. package/dist/client/index.html +1 -0
  145. package/dist/client/third-party-scripts/index.html +1 -0
  146. package/dist/client/web-vitals/index.html +1 -0
  147. package/dist/module.d.mts +9 -0
  148. package/dist/module.json +9 -0
  149. package/dist/module.mjs +115 -0
  150. package/dist/runtime/core/components/nuxt-island.d.ts +137 -0
  151. package/dist/runtime/core/components/nuxt-island.js +14 -0
  152. package/dist/runtime/core/plugins/vue-tracer-state.client.d.ts +2 -0
  153. package/dist/runtime/core/plugins/vue-tracer-state.client.js +7 -0
  154. package/dist/runtime/hydration/composables.d.ts +5 -0
  155. package/dist/runtime/hydration/composables.js +46 -0
  156. package/dist/runtime/hydration/plugin.client.d.ts +2 -0
  157. package/dist/runtime/hydration/plugin.client.js +11 -0
  158. package/dist/runtime/third-party-scripts/nitro.plugin.d.ts +2 -0
  159. package/dist/runtime/third-party-scripts/nitro.plugin.js +48 -0
  160. package/dist/runtime/third-party-scripts/plugin.client.d.ts +2 -0
  161. package/dist/runtime/third-party-scripts/plugin.client.js +88 -0
  162. package/dist/runtime/types.d.ts +48 -0
  163. package/dist/runtime/web-vitals/plugin.client.d.ts +13 -0
  164. package/dist/runtime/web-vitals/plugin.client.js +137 -0
  165. package/dist/runtime/web-vitals/utils.d.ts +35 -0
  166. package/dist/runtime/web-vitals/utils.js +13 -0
  167. package/dist/types.d.mts +3 -0
  168. package/package.json +61 -2
  169. /package/dist/{.gitkeep → client/_nuxt/third-party-scripts.tn0RQdqM.css} +0 -0
@@ -0,0 +1,115 @@
1
+ import { addDevServerHandler, defineNuxtModule, createResolver, addPlugin, addBuildPlugin, addComponent, addServerPlugin } from '@nuxt/kit';
2
+ import { existsSync } from 'node:fs';
3
+ import { eventHandler, proxyRequest } from 'h3';
4
+ import MagicString from 'magic-string';
5
+ import { createUnplugin } from 'unplugin';
6
+
7
+ const DEVTOOLS_UI_ROUTE = "/__nuxt-hints";
8
+ const DEVTOOLS_UI_LOCAL_PORT = 3300;
9
+ function setupDevToolsUI(nuxt, resolver) {
10
+ const clientPath = resolver.resolve("./client");
11
+ const isProductionBuild = existsSync(clientPath);
12
+ if (isProductionBuild) {
13
+ nuxt.hook("vite:serverCreated", async (server) => {
14
+ const sirv = await import('sirv').then((r) => r.default || r);
15
+ server.middlewares.use(
16
+ DEVTOOLS_UI_ROUTE,
17
+ sirv(clientPath, { dev: true, single: true })
18
+ );
19
+ });
20
+ } else {
21
+ addDevServerHandler({
22
+ route: DEVTOOLS_UI_ROUTE,
23
+ handler: eventHandler((e) => {
24
+ return proxyRequest(e, "http://localhost:" + DEVTOOLS_UI_LOCAL_PORT + DEVTOOLS_UI_ROUTE + e.path);
25
+ })
26
+ });
27
+ }
28
+ nuxt.hook("devtools:customTabs", (tabs) => {
29
+ tabs.push({
30
+ name: "hints",
31
+ title: "Hints",
32
+ icon: "carbon:idea",
33
+ category: "analyze",
34
+ view: {
35
+ type: "iframe",
36
+ src: DEVTOOLS_UI_ROUTE
37
+ }
38
+ });
39
+ });
40
+ }
41
+
42
+ const ID_INCLUDE = /\.vue$/;
43
+ const ID_EXCLUDE = /node_modules/;
44
+ const InjectHydrationPlugin = createUnplugin(() => {
45
+ return {
46
+ name: "@nuxt/hints:inject-hydration-check",
47
+ enforce: "pre",
48
+ transformInclude(id) {
49
+ return id.endsWith(".vue") && !id.includes("node_modules");
50
+ },
51
+ transform: {
52
+ filter: {
53
+ id: {
54
+ include: ID_INCLUDE,
55
+ exclude: ID_EXCLUDE
56
+ }
57
+ },
58
+ handler(code) {
59
+ const m = new MagicString(code);
60
+ const re = /<script\s+setup[^>]*>/g;
61
+ const match = re.exec(code);
62
+ if (!match) {
63
+ return code;
64
+ }
65
+ m.appendRight(
66
+ match.index + match[0].length,
67
+ `
68
+ import { useHydrationCheck } from '@nuxt/hints/runtime/hydration/composables'
69
+ useHydrationCheck();`
70
+ );
71
+ return {
72
+ code: m.toString(),
73
+ map: m.generateMap({ hires: true })
74
+ };
75
+ }
76
+ }
77
+ };
78
+ });
79
+
80
+ const module$1 = defineNuxtModule({
81
+ meta: {
82
+ name: "@nuxt/hints",
83
+ configKey: "hints"
84
+ },
85
+ defaults: {
86
+ devtools: true
87
+ },
88
+ setup(options, nuxt) {
89
+ if (!nuxt.options.dev) {
90
+ return;
91
+ }
92
+ const resolver = createResolver(import.meta.url);
93
+ addPlugin(resolver.resolve("./runtime/web-vitals/plugin.client"));
94
+ addPlugin(resolver.resolve("./runtime/hydration/plugin.client"));
95
+ addBuildPlugin(InjectHydrationPlugin);
96
+ addComponent({
97
+ name: "NuxtIsland",
98
+ filePath: resolver.resolve("./runtime/core/components/nuxt-island"),
99
+ priority: 1e3
100
+ });
101
+ addPlugin(resolver.resolve("./runtime/third-party-scripts/plugin.client"));
102
+ addServerPlugin(resolver.resolve("./runtime/third-party-scripts/nitro.plugin"));
103
+ nuxt.hook("prepare:types", ({ references }) => {
104
+ references.push({
105
+ types: resolver.resolve("./runtime/types.d.ts")
106
+ });
107
+ });
108
+ if (options.devtools) {
109
+ setupDevToolsUI(nuxt, resolver);
110
+ addPlugin(resolver.resolve("./runtime/core/plugins/vue-tracer-state.client"));
111
+ }
112
+ }
113
+ });
114
+
115
+ export { module$1 as default };
@@ -0,0 +1,137 @@
1
+ declare const HintsNuxtIsland: {
2
+ new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<import("vue").ExtractPropTypes<{
3
+ name: {
4
+ type: StringConstructor;
5
+ required: true;
6
+ };
7
+ lazy: BooleanConstructor;
8
+ props: {
9
+ type: ObjectConstructor;
10
+ default: () => undefined;
11
+ };
12
+ context: {
13
+ type: ObjectConstructor;
14
+ default: () => {};
15
+ };
16
+ scopeId: {
17
+ type: import("vue").PropType<string | undefined | null>;
18
+ default: () => undefined;
19
+ };
20
+ source: {
21
+ type: StringConstructor;
22
+ default: () => undefined;
23
+ };
24
+ dangerouslyLoadClientComponents: {
25
+ type: BooleanConstructor;
26
+ default: boolean;
27
+ };
28
+ }>> & Readonly<{
29
+ onError?: ((...args: any[]) => any) | undefined;
30
+ }>, (_ctx: any, _cache: any) => (import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
31
+ [key: string]: any;
32
+ }> | import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
33
+ [key: string]: any;
34
+ }>[])[] | import("vue").VNode<any, any, {
35
+ [key: string]: any;
36
+ }>[], {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "error"[], import("vue").PublicProps, {
37
+ props: Record<string, any>;
38
+ source: string;
39
+ scopeId: string | null | undefined;
40
+ lazy: boolean;
41
+ context: Record<string, any>;
42
+ dangerouslyLoadClientComponents: boolean;
43
+ }, true, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
44
+ P: {};
45
+ B: {};
46
+ D: {};
47
+ C: {};
48
+ M: {};
49
+ Defaults: {};
50
+ }, Readonly<import("vue").ExtractPropTypes<{
51
+ name: {
52
+ type: StringConstructor;
53
+ required: true;
54
+ };
55
+ lazy: BooleanConstructor;
56
+ props: {
57
+ type: ObjectConstructor;
58
+ default: () => undefined;
59
+ };
60
+ context: {
61
+ type: ObjectConstructor;
62
+ default: () => {};
63
+ };
64
+ scopeId: {
65
+ type: import("vue").PropType<string | undefined | null>;
66
+ default: () => undefined;
67
+ };
68
+ source: {
69
+ type: StringConstructor;
70
+ default: () => undefined;
71
+ };
72
+ dangerouslyLoadClientComponents: {
73
+ type: BooleanConstructor;
74
+ default: boolean;
75
+ };
76
+ }>> & Readonly<{
77
+ onError?: ((...args: any[]) => any) | undefined;
78
+ }>, (_ctx: any, _cache: any) => (import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
79
+ [key: string]: any;
80
+ }> | import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
81
+ [key: string]: any;
82
+ }>[])[] | import("vue").VNode<any, any, {
83
+ [key: string]: any;
84
+ }>[], {}, {}, {}, {
85
+ props: Record<string, any>;
86
+ source: string;
87
+ scopeId: string | null | undefined;
88
+ lazy: boolean;
89
+ context: Record<string, any>;
90
+ dangerouslyLoadClientComponents: boolean;
91
+ }>;
92
+ __isFragment?: never;
93
+ __isTeleport?: never;
94
+ __isSuspense?: never;
95
+ } & import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
96
+ name: {
97
+ type: StringConstructor;
98
+ required: true;
99
+ };
100
+ lazy: BooleanConstructor;
101
+ props: {
102
+ type: ObjectConstructor;
103
+ default: () => undefined;
104
+ };
105
+ context: {
106
+ type: ObjectConstructor;
107
+ default: () => {};
108
+ };
109
+ scopeId: {
110
+ type: import("vue").PropType<string | undefined | null>;
111
+ default: () => undefined;
112
+ };
113
+ source: {
114
+ type: StringConstructor;
115
+ default: () => undefined;
116
+ };
117
+ dangerouslyLoadClientComponents: {
118
+ type: BooleanConstructor;
119
+ default: boolean;
120
+ };
121
+ }>> & Readonly<{
122
+ onError?: ((...args: any[]) => any) | undefined;
123
+ }>, (_ctx: any, _cache: any) => (import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
124
+ [key: string]: any;
125
+ }> | import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
126
+ [key: string]: any;
127
+ }>[])[] | import("vue").VNode<any, any, {
128
+ [key: string]: any;
129
+ }>[], {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "error"[], "error", {
130
+ props: Record<string, any>;
131
+ source: string;
132
+ scopeId: string | null | undefined;
133
+ lazy: boolean;
134
+ context: Record<string, any>;
135
+ dangerouslyLoadClientComponents: boolean;
136
+ }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
137
+ export default HintsNuxtIsland;
@@ -0,0 +1,14 @@
1
+ import NuxtIsland from "#app/components/nuxt-island";
2
+ import { useNuxtApp } from "#imports";
3
+ const originalSetup = NuxtIsland.setup;
4
+ const HintsNuxtIsland = Object.assign({}, NuxtIsland, {
5
+ setup(props, ctx) {
6
+ if (useNuxtApp().ssrContext?.islandContext) {
7
+ console.warn(
8
+ `[@nuxt/hints] Nesting islands within islands is not recommanded for performance reasons. This leads to waterfall calls.`
9
+ );
10
+ }
11
+ return originalSetup(props, ctx);
12
+ }
13
+ });
14
+ export default HintsNuxtIsland;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import * as tracerOverlay from "vite-plugin-vue-tracer/client/overlay";
2
+ import * as tracerRecord from "vite-plugin-vue-tracer/client/record";
3
+ import { defineNuxtPlugin } from "#imports";
4
+ export default defineNuxtPlugin((nuxtApp) => {
5
+ nuxtApp.__tracerOverlay = tracerOverlay;
6
+ nuxtApp.__tracerRecord = tracerRecord;
7
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * prefer implementing onMismatch hook after vue 3.6
3
+ * compare element
4
+ */
5
+ export declare function useHydrationCheck(): void;
@@ -0,0 +1,46 @@
1
+ import { getCurrentInstance, onMounted } from "vue";
2
+ import { useNuxtApp } from "#imports";
3
+ function formatHTML(html) {
4
+ if (!html) return "";
5
+ let formatted = "";
6
+ let indent = 0;
7
+ const tags = html.split(/(<\/?[^>]+>)/g);
8
+ for (const tag of tags) {
9
+ if (!tag.trim()) continue;
10
+ if (tag.startsWith("</")) {
11
+ indent--;
12
+ formatted += "\n" + " ".repeat(Math.max(0, indent)) + tag;
13
+ } else if (tag.startsWith("<") && !tag.endsWith("/>") && !tag.includes("<!")) {
14
+ formatted += "\n" + " ".repeat(indent) + tag;
15
+ indent++;
16
+ } else if (tag.startsWith("<")) {
17
+ formatted += "\n" + " ".repeat(indent) + tag;
18
+ } else {
19
+ formatted += "\n" + " ".repeat(indent) + tag.trim();
20
+ }
21
+ }
22
+ return formatted.trim();
23
+ }
24
+ export function useHydrationCheck() {
25
+ if (import.meta.server) return;
26
+ const nuxtApp = useNuxtApp();
27
+ if (!nuxtApp.isHydrating) {
28
+ return;
29
+ }
30
+ const instance = getCurrentInstance();
31
+ if (!instance) return;
32
+ const htmlPrehydration = formatHTML(instance.vnode.el?.outerHTML);
33
+ const vnodePrehydration = instance.vnode;
34
+ onMounted(() => {
35
+ const htmlPostHydration = formatHTML(instance.vnode.el?.outerHTML);
36
+ if (htmlPrehydration !== htmlPostHydration) {
37
+ nuxtApp.__hints.hydration.push({
38
+ instance,
39
+ vnode: vnodePrehydration,
40
+ htmlPreHydration: htmlPrehydration,
41
+ htmlPostHydration
42
+ });
43
+ console.warn(`[nuxt/hints:hydration] Component ${instance.type.name ?? instance.type.displayName ?? instance.type.__name ?? instance.type.__file} seems to have different html pre and post-hydration. Please make sure you don't have any hydration issue.`);
44
+ }
45
+ });
46
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { defineNuxtPlugin, useNuxtApp } from "#imports";
2
+ import { defu } from "defu";
3
+ export default defineNuxtPlugin({
4
+ name: "@nuxt/hints:hydration",
5
+ setup() {
6
+ const nuxtApp = useNuxtApp();
7
+ nuxtApp.__hints = defu(nuxtApp.__hints, {
8
+ hydration: []
9
+ });
10
+ }
11
+ });
@@ -0,0 +1,2 @@
1
+ import type { NitroApp } from 'nitropack/types';
2
+ export default function (nitroApp: NitroApp): void;
@@ -0,0 +1,48 @@
1
+ export default function(nitroApp) {
2
+ nitroApp.hooks.hook("render:html", ({ head }) => {
3
+ head.unshift(`
4
+ <script>
5
+ window.__hints_TPC_start_time = Date.now();
6
+
7
+ function __hints_TPC_saveTime(script, startTime) {
8
+ script.__hints_TPC_end_time = Date.now();
9
+ const scriptStartTime = startTime || script.__hints_TPC_start_time || window.__hints_TPC_start_time;
10
+
11
+ const resourceEntries = performance.getEntriesByName(script.src)
12
+ const scriptEntry = resourceEntries.find(entry => entry.name === script.src)
13
+
14
+ if (scriptEntry) {
15
+ // Calculate parse + execute time using modern API
16
+ const navigationEntry = performance.getEntriesByType('navigation')[0]
17
+ const navigationStart = navigationEntry ? performance.timeOrigin : performance.timeOrigin
18
+
19
+ script.requestTime = (scriptEntry.responseStart - scriptEntry.requestStart);
20
+ script.downloadTime = (scriptEntry.responseEnd - scriptEntry.responseStart);
21
+ script.totalNetworkTime = (scriptEntry.responseEnd - scriptEntry.startTime);
22
+ script.parseExecuteTime = script.__hints_TPC_end_time - (navigationStart + scriptEntry.responseEnd);
23
+ script.loaded = true;
24
+ console.log('[@nuxt/hints]: \u{1F4CA} Detailed timing for', script.src, {
25
+ 'Request': script.requestTime.toFixed(2) + 'ms',
26
+ 'Download': script.downloadTime.toFixed(2) + 'ms',
27
+ 'Total Network': script.totalNetworkTime.toFixed(2) + 'ms',
28
+ 'Parse + Execute': script.parseExecuteTime.toFixed(2) + 'ms'
29
+ });
30
+ }
31
+ }
32
+ <\/script>
33
+ `);
34
+ head.push(`
35
+ <script>
36
+ for (const script of document.scripts) {
37
+ if (script.src && !script.src.startsWith(window.location.origin)) {
38
+ script.__hints_TPC_start_time = window.__hints_TPC_start_time || Date.now();
39
+ script.onload = function(_) {
40
+ __hints_TPC_saveTime(script, script.__hints_TPC_start_time);
41
+ }
42
+ __hints_TPC_saveTime(script, script.__hints_TPC_start_time);
43
+ }
44
+ }
45
+ <\/script>
46
+ `);
47
+ });
48
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,88 @@
1
+ import { defineNuxtPlugin, ref, useNuxtApp } from "#imports";
2
+ const EXTENSIONS_SCHEMES_RE = /^(chrome-extension|moz-extension|safari-extension|ms-browser-extension):/;
3
+ function isExtensionScript(src) {
4
+ try {
5
+ const url = new URL(src, window.location.origin);
6
+ return EXTENSIONS_SCHEMES_RE.test(url.protocol);
7
+ } catch {
8
+ return false;
9
+ }
10
+ }
11
+ function isSameOriginScript(src) {
12
+ try {
13
+ const url = new URL(src, window.location.origin);
14
+ return url.origin === window.location.origin;
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+ function isIgnoredScript(src) {
20
+ return isSameOriginScript(src) || isExtensionScript(src);
21
+ }
22
+ export default defineNuxtPlugin({
23
+ name: "nuxt-hints:third-party-scripts",
24
+ setup() {
25
+ const nuxtApp = useNuxtApp();
26
+ const scripts = nuxtApp.__hints_tpc = ref([]);
27
+ const isUsingNuxtScripts = !!nuxtApp.$scripts;
28
+ nuxtApp.hook("hints:scripts:added", (script) => {
29
+ scripts.value.push({ element: script, loaded: false });
30
+ });
31
+ nuxtApp.hook("hints:scripts:loaded", (script) => {
32
+ const existingScript = scripts.value.find((s) => s.element === script);
33
+ if (existingScript) {
34
+ existingScript.loaded = true;
35
+ } else {
36
+ console.warn(`[@nuxt/hints]: Script loaded event received for a script not tracked: ${script.src}. Please open an issue with a minimal reproduction if you think this is a bug.`);
37
+ scripts.value.push({ element: script, loaded: true });
38
+ }
39
+ });
40
+ nuxtApp.hooks.hookOnce("app:mounted", () => {
41
+ let hasThirdPartyScript = false;
42
+ for (const script of document.scripts) {
43
+ if (script.src && !isIgnoredScript(script.src)) {
44
+ hasThirdPartyScript = true;
45
+ onScriptAdded(script);
46
+ }
47
+ }
48
+ if (hasThirdPartyScript && !isUsingNuxtScripts) {
49
+ console.info("\u2139\uFE0F [@nuxt/hints]: Third-party scripts detected on page load: consider using @nuxt/scripts");
50
+ }
51
+ });
52
+ const observer = new MutationObserver((mutations) => {
53
+ for (const mutation of mutations) {
54
+ if (mutation.type === "childList") {
55
+ for (const node of mutation.addedNodes) {
56
+ if (isScript(node) && node.src && !isIgnoredScript(node.src)) {
57
+ onScriptAdded(node);
58
+ }
59
+ }
60
+ }
61
+ }
62
+ });
63
+ observer.observe(document.documentElement, {
64
+ childList: true,
65
+ subtree: true
66
+ });
67
+ function onScriptAdded(script) {
68
+ if (!script.crossOrigin) {
69
+ console.warn(`[@nuxt/hints]: Third-party script "${script.src}" is missing crossorigin attribute. Consider adding crossorigin="anonymous" for better security and error reporting.`);
70
+ }
71
+ nuxtApp.callHook("hints:scripts:added", script).then(() => {
72
+ if (!script.loaded) {
73
+ script.onload = () => {
74
+ window.__hints_TPC_saveTime(script, script.__hints_TPC_start_time);
75
+ nuxtApp.callHook("hints:scripts:loaded", script);
76
+ };
77
+ } else {
78
+ window.__hints_TPC_saveTime(script, script.__hints_TPC_start_time);
79
+ nuxtApp.callHook("hints:scripts:loaded", script);
80
+ }
81
+ });
82
+ console.info(`\u2139\uFE0F [@nuxt/hints]: Dynamically added third-party script detected: ${script.src}`);
83
+ }
84
+ }
85
+ });
86
+ function isScript(node) {
87
+ return node.nodeName === "SCRIPT";
88
+ }
@@ -0,0 +1,48 @@
1
+ import type { ComponentInternalInstance, VNode, Ref } from 'vue'
2
+ import type { LCPMetricWithAttribution, INPMetricWithAttribution, CLSMetricWithAttribution } from 'web-vitals/attribution'
3
+
4
+ declare global {
5
+ interface Window {
6
+ __hints_TPC_start_time: number
7
+ __hints_TPC_saveTime: (script: HTMLScriptElement, startTime?: number) => void
8
+ }
9
+ interface HTMLScriptElement {
10
+ __hints_TPC_start_time?: number
11
+ __hints_TPC_end_time?: number
12
+ requestTime?: number
13
+ downloadTime?: number
14
+ totalNetworkTime?: number
15
+ parseExecuteTime?: number
16
+ loaded?: boolean
17
+ }
18
+ interface Element {
19
+ __vnode?: VNode
20
+ }
21
+ }
22
+ declare module '#app' {
23
+ interface RuntimeNuxtHooks {
24
+ 'hints:scripts:added': (script: HTMLScriptElement) => void
25
+ 'hints:scripts:loaded': (script: HTMLScriptElement) => void
26
+
27
+ 'hints:webvitals:sync': (webvitals: NuxtApp['__hints']['webvitals']) => void
28
+ 'hints:webvitals:lcp': (metric: LCPMetricWithAttribution) => void
29
+ 'hints:webvitals:inp': (metric: INPMetricWithAttribution) => void
30
+ 'hints:webvitals:cls': (metric: CLSMetricWithAttribution) => void
31
+ }
32
+
33
+ interface NuxtApp {
34
+ __hints_tpc: Ref<{ element: HTMLScriptElement, loaded: boolean }[]>
35
+ __hints: {
36
+ hydration: { instance: ComponentInternalInstance, vnode: VNode, htmlPreHydration: string | undefined, htmlPostHydration: string | undefined }[]
37
+ webvitals: {
38
+ lcp: Ref<LCPMetricWithAttribution[]>
39
+ inp: Ref<INPMetricWithAttribution[]>
40
+ cls: Ref<CLSMetricWithAttribution[]>
41
+ }
42
+ }
43
+ __tracerOverlay: typeof import('vite-plugin-vue-tracer/client/overlay')
44
+ __tracerRecord: typeof import('vite-plugin-vue-tracer/client/record')
45
+ }
46
+ }
47
+
48
+ export {}
@@ -0,0 +1,13 @@
1
+ declare global {
2
+ interface PerformanceEntry {
3
+ element?: HTMLElement;
4
+ sources?: {
5
+ node: HTMLElement;
6
+ currentRect: DOMRect;
7
+ previousRect: DOMRect;
8
+ }[];
9
+ value?: number;
10
+ }
11
+ }
12
+ declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
13
+ export default _default;