@depup/nuxt 4.2.2-depup.0

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 (233) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/app.d.ts +1 -0
  4. package/bin/nuxt.mjs +2 -0
  5. package/config.cjs +7 -0
  6. package/config.d.ts +8 -0
  7. package/config.js +5 -0
  8. package/dist/app/compat/capi.d.ts +4 -0
  9. package/dist/app/compat/capi.js +19 -0
  10. package/dist/app/compat/idle-callback.d.ts +2 -0
  11. package/dist/app/compat/idle-callback.js +15 -0
  12. package/dist/app/compat/interval.d.ts +1 -0
  13. package/dist/app/compat/interval.js +11 -0
  14. package/dist/app/compat/vue-demi.d.ts +4 -0
  15. package/dist/app/compat/vue-demi.js +4 -0
  16. package/dist/app/components/client-fallback.client.d.ts +50 -0
  17. package/dist/app/components/client-fallback.client.js +50 -0
  18. package/dist/app/components/client-fallback.server.d.ts +57 -0
  19. package/dist/app/components/client-fallback.server.js +80 -0
  20. package/dist/app/components/client-only.d.ts +26 -0
  21. package/dist/app/components/client-only.js +130 -0
  22. package/dist/app/components/dev-only.d.ts +11 -0
  23. package/dist/app/components/dev-only.js +14 -0
  24. package/dist/app/components/error-404.d.vue.ts +51 -0
  25. package/dist/app/components/error-404.vue +48 -0
  26. package/dist/app/components/error-404.vue.d.ts +51 -0
  27. package/dist/app/components/error-500.d.vue.ts +51 -0
  28. package/dist/app/components/error-500.vue +46 -0
  29. package/dist/app/components/error-500.vue.d.ts +51 -0
  30. package/dist/app/components/index.d.ts +3 -0
  31. package/dist/app/components/index.js +1 -0
  32. package/dist/app/components/injections.d.ts +7 -0
  33. package/dist/app/components/injections.js +2 -0
  34. package/dist/app/components/island-renderer.d.ts +20 -0
  35. package/dist/app/components/island-renderer.js +28 -0
  36. package/dist/app/components/nuxt-error-boundary.d.vue.ts +24 -0
  37. package/dist/app/components/nuxt-error-boundary.vue +46 -0
  38. package/dist/app/components/nuxt-error-boundary.vue.d.ts +24 -0
  39. package/dist/app/components/nuxt-error-page.d.vue.ts +7 -0
  40. package/dist/app/components/nuxt-error-page.vue +27 -0
  41. package/dist/app/components/nuxt-error-page.vue.d.ts +7 -0
  42. package/dist/app/components/nuxt-island.d.ts +70 -0
  43. package/dist/app/components/nuxt-island.js +331 -0
  44. package/dist/app/components/nuxt-layout.d.ts +14 -0
  45. package/dist/app/components/nuxt-layout.js +171 -0
  46. package/dist/app/components/nuxt-link.d.ts +101 -0
  47. package/dist/app/components/nuxt-link.js +409 -0
  48. package/dist/app/components/nuxt-loading-indicator.d.ts +78 -0
  49. package/dist/app/components/nuxt-loading-indicator.js +75 -0
  50. package/dist/app/components/nuxt-root.d.vue.ts +3 -0
  51. package/dist/app/components/nuxt-root.vue +60 -0
  52. package/dist/app/components/nuxt-root.vue.d.ts +3 -0
  53. package/dist/app/components/nuxt-route-announcer.d.ts +26 -0
  54. package/dist/app/components/nuxt-route-announcer.js +48 -0
  55. package/dist/app/components/nuxt-stubs.d.ts +6 -0
  56. package/dist/app/components/nuxt-stubs.js +14 -0
  57. package/dist/app/components/nuxt-teleport-island-component.d.ts +22 -0
  58. package/dist/app/components/nuxt-teleport-island-component.js +38 -0
  59. package/dist/app/components/nuxt-teleport-island-slot.d.ts +32 -0
  60. package/dist/app/components/nuxt-teleport-island-slot.js +53 -0
  61. package/dist/app/components/nuxt-time.d.vue.ts +37 -0
  62. package/dist/app/components/nuxt-time.vue +148 -0
  63. package/dist/app/components/nuxt-time.vue.d.ts +37 -0
  64. package/dist/app/components/route-provider.d.ts +48 -0
  65. package/dist/app/components/route-provider.js +49 -0
  66. package/dist/app/components/server-placeholder.d.ts +2 -0
  67. package/dist/app/components/server-placeholder.js +7 -0
  68. package/dist/app/components/test-component-wrapper.d.ts +4 -0
  69. package/dist/app/components/test-component-wrapper.js +27 -0
  70. package/dist/app/components/utils.d.ts +48 -0
  71. package/dist/app/components/utils.js +126 -0
  72. package/dist/app/components/welcome.d.vue.ts +24 -0
  73. package/dist/app/components/welcome.vue +34 -0
  74. package/dist/app/components/welcome.vue.d.ts +24 -0
  75. package/dist/app/composables/asyncContext.d.ts +2 -0
  76. package/dist/app/composables/asyncContext.js +7 -0
  77. package/dist/app/composables/asyncData.d.ts +146 -0
  78. package/dist/app/composables/asyncData.js +491 -0
  79. package/dist/app/composables/chunk.d.ts +25 -0
  80. package/dist/app/composables/chunk.js +30 -0
  81. package/dist/app/composables/component.d.ts +4 -0
  82. package/dist/app/composables/component.js +82 -0
  83. package/dist/app/composables/cookie.d.ts +22 -0
  84. package/dist/app/composables/cookie.js +205 -0
  85. package/dist/app/composables/error.d.ts +25 -0
  86. package/dist/app/composables/error.js +39 -0
  87. package/dist/app/composables/fetch.d.ts +37 -0
  88. package/dist/app/composables/fetch.js +123 -0
  89. package/dist/app/composables/head.d.ts +1 -0
  90. package/dist/app/composables/head.js +1 -0
  91. package/dist/app/composables/hydrate.d.ts +9 -0
  92. package/dist/app/composables/hydrate.js +14 -0
  93. package/dist/app/composables/id.d.ts +3 -0
  94. package/dist/app/composables/id.js +2 -0
  95. package/dist/app/composables/index.d.ts +29 -0
  96. package/dist/app/composables/index.js +21 -0
  97. package/dist/app/composables/lazy-hydration.d.ts +40 -0
  98. package/dist/app/composables/lazy-hydration.js +2 -0
  99. package/dist/app/composables/loading-indicator.d.ts +39 -0
  100. package/dist/app/composables/loading-indicator.js +142 -0
  101. package/dist/app/composables/manifest.d.ts +20 -0
  102. package/dist/app/composables/manifest.js +59 -0
  103. package/dist/app/composables/once.d.ts +14 -0
  104. package/dist/app/composables/once.js +49 -0
  105. package/dist/app/composables/payload.d.ts +27 -0
  106. package/dist/app/composables/payload.js +137 -0
  107. package/dist/app/composables/preload.d.ts +20 -0
  108. package/dist/app/composables/preload.js +55 -0
  109. package/dist/app/composables/preview.d.ts +38 -0
  110. package/dist/app/composables/preview.js +61 -0
  111. package/dist/app/composables/ready.d.ts +2 -0
  112. package/dist/app/composables/ready.js +15 -0
  113. package/dist/app/composables/route-announcer.d.ts +19 -0
  114. package/dist/app/composables/route-announcer.js +55 -0
  115. package/dist/app/composables/router.d.ts +96 -0
  116. package/dist/app/composables/router.js +197 -0
  117. package/dist/app/composables/runtime-hook.d.ts +9 -0
  118. package/dist/app/composables/runtime-hook.js +7 -0
  119. package/dist/app/composables/script-stubs.d.ts +32 -0
  120. package/dist/app/composables/script-stubs.js +104 -0
  121. package/dist/app/composables/ssr.d.ts +33 -0
  122. package/dist/app/composables/ssr.js +113 -0
  123. package/dist/app/composables/state.d.ts +11 -0
  124. package/dist/app/composables/state.js +40 -0
  125. package/dist/app/composables/url.d.ts +3 -0
  126. package/dist/app/composables/url.js +8 -0
  127. package/dist/app/config.d.ts +14 -0
  128. package/dist/app/config.js +72 -0
  129. package/dist/app/entry-spa.d.ts +2 -0
  130. package/dist/app/entry-spa.js +2 -0
  131. package/dist/app/entry.async.d.ts +3 -0
  132. package/dist/app/entry.async.js +5 -0
  133. package/dist/app/entry.d.ts +7 -0
  134. package/dist/app/entry.js +78 -0
  135. package/dist/app/index.d.ts +12 -0
  136. package/dist/app/index.js +8 -0
  137. package/dist/app/middleware/manifest-route-rule.d.ts +2 -0
  138. package/dist/app/middleware/manifest-route-rule.js +17 -0
  139. package/dist/app/nuxt.d.ts +271 -0
  140. package/dist/app/nuxt.js +279 -0
  141. package/dist/app/plugins/browser-devtools-timing.client.d.ts +2 -0
  142. package/dist/app/plugins/browser-devtools-timing.client.js +23 -0
  143. package/dist/app/plugins/check-if-layout-used.d.ts +2 -0
  144. package/dist/app/plugins/check-if-layout-used.js +28 -0
  145. package/dist/app/plugins/check-outdated-build.client.d.ts +2 -0
  146. package/dist/app/plugins/check-outdated-build.client.js +39 -0
  147. package/dist/app/plugins/chunk-reload-immediate.client.d.ts +2 -0
  148. package/dist/app/plugins/chunk-reload-immediate.client.js +20 -0
  149. package/dist/app/plugins/chunk-reload.client.d.ts +2 -0
  150. package/dist/app/plugins/chunk-reload.client.js +30 -0
  151. package/dist/app/plugins/cross-origin-prefetch.client.d.ts +2 -0
  152. package/dist/app/plugins/cross-origin-prefetch.client.js +37 -0
  153. package/dist/app/plugins/debug-hooks.d.ts +2 -0
  154. package/dist/app/plugins/debug-hooks.js +9 -0
  155. package/dist/app/plugins/dev-server-logs.d.ts +2 -0
  156. package/dist/app/plugins/dev-server-logs.js +60 -0
  157. package/dist/app/plugins/navigation-repaint.client.d.ts +2 -0
  158. package/dist/app/plugins/navigation-repaint.client.js +16 -0
  159. package/dist/app/plugins/payload.client.d.ts +2 -0
  160. package/dist/app/plugins/payload.client.js +50 -0
  161. package/dist/app/plugins/preload.server.d.ts +2 -0
  162. package/dist/app/plugins/preload.server.js +13 -0
  163. package/dist/app/plugins/restore-state.client.d.ts +2 -0
  164. package/dist/app/plugins/restore-state.client.js +18 -0
  165. package/dist/app/plugins/revive-payload.client.d.ts +2 -0
  166. package/dist/app/plugins/revive-payload.client.js +44 -0
  167. package/dist/app/plugins/revive-payload.server.d.ts +2 -0
  168. package/dist/app/plugins/revive-payload.server.js +26 -0
  169. package/dist/app/plugins/router.d.ts +59 -0
  170. package/dist/app/plugins/router.js +222 -0
  171. package/dist/app/plugins/utils.d.ts +1 -0
  172. package/dist/app/plugins/utils.js +4 -0
  173. package/dist/app/plugins/view-transitions.client.d.ts +2 -0
  174. package/dist/app/plugins/view-transitions.client.js +55 -0
  175. package/dist/app/plugins/warn.dev.server.d.ts +2 -0
  176. package/dist/app/plugins/warn.dev.server.js +6 -0
  177. package/dist/app/types/augments.d.ts +49 -0
  178. package/dist/app/types/augments.js +0 -0
  179. package/dist/app/types.d.ts +39 -0
  180. package/dist/app/types.js +0 -0
  181. package/dist/app/utils.d.ts +13 -0
  182. package/dist/app/utils.js +34 -0
  183. package/dist/components/runtime/client-component.d.ts +2 -0
  184. package/dist/components/runtime/client-component.js +59 -0
  185. package/dist/components/runtime/lazy-hydrated-component.d.ts +124 -0
  186. package/dist/components/runtime/lazy-hydrated-component.js +101 -0
  187. package/dist/components/runtime/server-component.d.ts +20 -0
  188. package/dist/components/runtime/server-component.js +69 -0
  189. package/dist/head/runtime/components.d.ts +1058 -0
  190. package/dist/head/runtime/components.js +297 -0
  191. package/dist/head/runtime/composables.d.ts +25 -0
  192. package/dist/head/runtime/composables.js +47 -0
  193. package/dist/head/runtime/plugins/unhead.d.ts +2 -0
  194. package/dist/head/runtime/plugins/unhead.js +31 -0
  195. package/dist/head/runtime/types.d.ts +7 -0
  196. package/dist/head/runtime/types.js +0 -0
  197. package/dist/index.d.mts +9 -0
  198. package/dist/index.d.ts +9 -0
  199. package/dist/index.mjs +6974 -0
  200. package/dist/pages/runtime/app.d.vue.ts +3 -0
  201. package/dist/pages/runtime/app.vue +6 -0
  202. package/dist/pages/runtime/app.vue.d.ts +3 -0
  203. package/dist/pages/runtime/component-stub.d.ts +2 -0
  204. package/dist/pages/runtime/component-stub.js +1 -0
  205. package/dist/pages/runtime/composables.d.ts +58 -0
  206. package/dist/pages/runtime/composables.js +24 -0
  207. package/dist/pages/runtime/index.d.ts +3 -0
  208. package/dist/pages/runtime/index.js +1 -0
  209. package/dist/pages/runtime/page-placeholder.d.ts +4 -0
  210. package/dist/pages/runtime/page-placeholder.js +11 -0
  211. package/dist/pages/runtime/page.d.ts +30 -0
  212. package/dist/pages/runtime/page.js +212 -0
  213. package/dist/pages/runtime/plugins/check-if-page-unused.d.ts +2 -0
  214. package/dist/pages/runtime/plugins/check-if-page-unused.js +29 -0
  215. package/dist/pages/runtime/plugins/prefetch.client.d.ts +2 -0
  216. package/dist/pages/runtime/plugins/prefetch.client.js +41 -0
  217. package/dist/pages/runtime/plugins/prerender.server.d.ts +2 -0
  218. package/dist/pages/runtime/plugins/prerender.server.js +47 -0
  219. package/dist/pages/runtime/plugins/router.d.ts +6 -0
  220. package/dist/pages/runtime/plugins/router.js +236 -0
  221. package/dist/pages/runtime/router.options.d.ts +3 -0
  222. package/dist/pages/runtime/router.options.js +60 -0
  223. package/dist/pages/runtime/utils.d.ts +11 -0
  224. package/dist/pages/runtime/utils.js +18 -0
  225. package/dist/pages/runtime/validate.d.ts +2 -0
  226. package/dist/pages/runtime/validate.js +23 -0
  227. package/kit.d.ts +1 -0
  228. package/kit.js +1 -0
  229. package/package.json +156 -0
  230. package/schema.d.ts +1 -0
  231. package/schema.js +1 -0
  232. package/types.d.mts +14 -0
  233. package/types.d.ts +14 -0
@@ -0,0 +1,331 @@
1
+ import { Fragment, Teleport, computed, createStaticVNode, createVNode, defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, toRaw, watch, withMemo } from "vue";
2
+ import { debounce } from "perfect-debounce";
3
+ import { hash } from "ohash";
4
+ import { appendResponseHeader } from "h3";
5
+ import { randomUUID } from "uncrypto";
6
+ import { joinURL, withQuery } from "ufo";
7
+ import { useNuxtApp, useRuntimeConfig } from "../nuxt.js";
8
+ import { createError } from "../composables/error.js";
9
+ import { prerenderRoutes, useRequestEvent } from "../composables/ssr.js";
10
+ import { injectHead } from "../composables/head.js";
11
+ import { getFragmentHTML, isEndFragment, isStartFragment } from "./utils.js";
12
+ import { appBaseURL, remoteComponentIslands, selectiveClient } from "#build/nuxt.config.mjs";
13
+ const pKey = "_islandPromises";
14
+ const SSR_UID_RE = /data-island-uid="([^"]*)"/;
15
+ const DATA_ISLAND_UID_RE = /data-island-uid(="")?(?!="[^"])/g;
16
+ const SLOTNAME_RE = /data-island-slot="([^"]*)"/g;
17
+ const SLOT_FALLBACK_RE = / data-island-slot="([^"]*)"[^>]*>/g;
18
+ const ISLAND_SCOPE_ID_RE = /^<[^> ]*/;
19
+ let id = 1;
20
+ const getId = import.meta.client ? () => (id++).toString() : randomUUID;
21
+ const components = import.meta.client ? /* @__PURE__ */ new Map() : void 0;
22
+ async function loadComponents(source = appBaseURL, paths) {
23
+ if (!paths) {
24
+ return;
25
+ }
26
+ const promises = [];
27
+ for (const [component, item] of Object.entries(paths)) {
28
+ if (!components.has(component)) {
29
+ promises.push((async () => {
30
+ const chunkSource = joinURL(source, item.chunk);
31
+ const c = await import(
32
+ /* @vite-ignore */
33
+ chunkSource
34
+ ).then((m) => m.default || m);
35
+ components.set(component, c);
36
+ })());
37
+ }
38
+ }
39
+ await Promise.all(promises);
40
+ }
41
+ export default defineComponent({
42
+ name: "NuxtIsland",
43
+ inheritAttrs: false,
44
+ props: {
45
+ name: {
46
+ type: String,
47
+ required: true
48
+ },
49
+ lazy: Boolean,
50
+ props: {
51
+ type: Object,
52
+ default: () => void 0
53
+ },
54
+ context: {
55
+ type: Object,
56
+ default: () => ({})
57
+ },
58
+ scopeId: {
59
+ type: String,
60
+ default: () => void 0
61
+ },
62
+ source: {
63
+ type: String,
64
+ default: () => void 0
65
+ },
66
+ dangerouslyLoadClientComponents: {
67
+ type: Boolean,
68
+ default: false
69
+ }
70
+ },
71
+ emits: ["error"],
72
+ async setup(props, { slots, expose, emit }) {
73
+ let canTeleport = import.meta.server;
74
+ const teleportKey = shallowRef(0);
75
+ const key = shallowRef(0);
76
+ const canLoadClientComponent = computed(() => selectiveClient && (props.dangerouslyLoadClientComponents || !props.source));
77
+ const error = ref(null);
78
+ const config = useRuntimeConfig();
79
+ const nuxtApp = useNuxtApp();
80
+ const filteredProps = computed(() => props.props ? Object.fromEntries(Object.entries(props.props).filter(([key2]) => !key2.startsWith("data-v-"))) : {});
81
+ const hashId = computed(() => hash([props.name, filteredProps.value, props.context, props.source]).replace(/[-_]/g, ""));
82
+ const instance = getCurrentInstance();
83
+ const event = useRequestEvent();
84
+ let activeHead;
85
+ const eventFetch = import.meta.server ? event.fetch : globalThis.fetch;
86
+ const mounted = shallowRef(false);
87
+ onMounted(() => {
88
+ mounted.value = true;
89
+ teleportKey.value++;
90
+ });
91
+ onBeforeUnmount(() => {
92
+ if (activeHead) {
93
+ activeHead.dispose();
94
+ }
95
+ });
96
+ function setPayload(key2, result) {
97
+ const toRevive = {};
98
+ if (result.props) {
99
+ toRevive.props = result.props;
100
+ }
101
+ if (result.slots) {
102
+ toRevive.slots = result.slots;
103
+ }
104
+ if (result.components) {
105
+ toRevive.components = result.components;
106
+ }
107
+ if (result.head) {
108
+ toRevive.head = result.head;
109
+ }
110
+ nuxtApp.payload.data[key2] = {
111
+ __nuxt_island: {
112
+ key: key2,
113
+ ...import.meta.server && import.meta.prerender ? {} : { params: { ...props.context, props: props.props ? JSON.stringify(props.props) : void 0 } },
114
+ result: toRevive
115
+ },
116
+ ...result
117
+ };
118
+ }
119
+ const payloads = {};
120
+ if (instance.vnode.el) {
121
+ const slots2 = toRaw(nuxtApp.payload.data[`${props.name}_${hashId.value}`])?.slots;
122
+ if (slots2) {
123
+ payloads.slots = slots2;
124
+ }
125
+ if (selectiveClient) {
126
+ const components2 = toRaw(nuxtApp.payload.data[`${props.name}_${hashId.value}`])?.components;
127
+ if (components2) {
128
+ payloads.components = components2;
129
+ }
130
+ }
131
+ }
132
+ const ssrHTML = ref("");
133
+ if (import.meta.client && instance.vnode?.el) {
134
+ if (import.meta.dev) {
135
+ let currentEl = instance.vnode.el;
136
+ let startEl = null;
137
+ let isFirstElement = true;
138
+ while (currentEl) {
139
+ if (isEndFragment(currentEl)) {
140
+ if (startEl !== currentEl.previousSibling) {
141
+ console.warn(`[\`Server components(and islands)\`] "${props.name}" must have a single root element. (HTML comments are considered elements as well.)`);
142
+ }
143
+ break;
144
+ } else if (!isStartFragment(currentEl) && isFirstElement) {
145
+ isFirstElement = false;
146
+ if (currentEl.nodeType === 1) {
147
+ startEl = currentEl;
148
+ }
149
+ }
150
+ currentEl = currentEl.nextSibling;
151
+ }
152
+ }
153
+ ssrHTML.value = getFragmentHTML(instance.vnode.el, true)?.join("") || "";
154
+ const key2 = `${props.name}_${hashId.value}`;
155
+ nuxtApp.payload.data[key2] ||= {};
156
+ nuxtApp.payload.data[key2].html = ssrHTML.value.replaceAll(new RegExp(`data-island-uid="${ssrHTML.value.match(SSR_UID_RE)?.[1] || ""}"`, "g"), `data-island-uid=""`);
157
+ }
158
+ const uid = ref(ssrHTML.value.match(SSR_UID_RE)?.[1] || getId());
159
+ const currentSlots = new Set(Object.keys(slots));
160
+ const availableSlots = computed(() => new Set([...ssrHTML.value.matchAll(SLOTNAME_RE)].map((m) => m[1])));
161
+ const html = computed(() => {
162
+ let html2 = ssrHTML.value;
163
+ if (props.scopeId) {
164
+ html2 = html2.replace(ISLAND_SCOPE_ID_RE, (full) => full + " " + props.scopeId);
165
+ }
166
+ if (import.meta.client && !canLoadClientComponent.value) {
167
+ for (const [key2, value] of Object.entries(payloads.components || {})) {
168
+ html2 = html2.replace(new RegExp(` data-island-uid="${uid.value}" data-island-component="${key2}"[^>]*>`), (full) => {
169
+ return full + value.html;
170
+ });
171
+ }
172
+ }
173
+ if (payloads.slots) {
174
+ return html2.replaceAll(SLOT_FALLBACK_RE, (full, slotName) => {
175
+ if (!currentSlots.has(slotName)) {
176
+ return full + (payloads.slots?.[slotName]?.fallback || "");
177
+ }
178
+ return full;
179
+ });
180
+ }
181
+ return html2;
182
+ });
183
+ const head = injectHead();
184
+ async function _fetchComponent(force = false) {
185
+ const key2 = `${props.name}_${hashId.value}`;
186
+ if (!force && nuxtApp.payload.data[key2]?.html) {
187
+ return nuxtApp.payload.data[key2];
188
+ }
189
+ const url = remoteComponentIslands && props.source ? joinURL(props.source, `/__nuxt_island/${key2}.json`) : `/__nuxt_island/${key2}.json`;
190
+ if (import.meta.server && import.meta.prerender) {
191
+ nuxtApp.runWithContext(() => prerenderRoutes(url));
192
+ }
193
+ const r = await eventFetch(withQuery(import.meta.dev && import.meta.client || props.source ? url : joinURL(config.app.baseURL ?? "", url), {
194
+ ...props.context,
195
+ props: props.props ? JSON.stringify(props.props) : void 0
196
+ }));
197
+ if (!r.ok) {
198
+ throw createError({ statusCode: r.status, statusMessage: r.statusText });
199
+ }
200
+ try {
201
+ const result = await r.json();
202
+ if (import.meta.server && import.meta.prerender) {
203
+ const hints = r.headers.get("x-nitro-prerender");
204
+ if (hints) {
205
+ appendResponseHeader(event, "x-nitro-prerender", hints);
206
+ }
207
+ }
208
+ setPayload(key2, result);
209
+ return result;
210
+ } catch (e) {
211
+ if (r.status !== 200) {
212
+ throw new Error(e.toString(), { cause: r });
213
+ }
214
+ throw e;
215
+ }
216
+ }
217
+ async function fetchComponent(force = false) {
218
+ nuxtApp[pKey] ||= {};
219
+ nuxtApp[pKey][uid.value] ||= _fetchComponent(force).finally(() => {
220
+ delete nuxtApp[pKey][uid.value];
221
+ });
222
+ try {
223
+ const res = await nuxtApp[pKey][uid.value];
224
+ ssrHTML.value = res.html.replaceAll(DATA_ISLAND_UID_RE, `data-island-uid="${uid.value}"`);
225
+ key.value++;
226
+ error.value = null;
227
+ payloads.slots = res.slots || {};
228
+ payloads.components = res.components || {};
229
+ if (selectiveClient && import.meta.client) {
230
+ if (canLoadClientComponent.value && res.components) {
231
+ await loadComponents(props.source, res.components);
232
+ }
233
+ }
234
+ if (res?.head) {
235
+ if (activeHead) {
236
+ activeHead.patch(res.head);
237
+ } else {
238
+ activeHead = head.push(res.head);
239
+ }
240
+ }
241
+ if (import.meta.client) {
242
+ nextTick(() => {
243
+ canTeleport = true;
244
+ teleportKey.value++;
245
+ });
246
+ }
247
+ } catch (e) {
248
+ error.value = e;
249
+ emit("error", e);
250
+ }
251
+ }
252
+ expose({
253
+ refresh: () => fetchComponent(true)
254
+ });
255
+ if (import.meta.hot) {
256
+ import.meta.hot.on(`nuxt-server-component:${props.name}`, () => {
257
+ fetchComponent(true);
258
+ });
259
+ }
260
+ if (import.meta.client) {
261
+ watch(props, debounce(() => fetchComponent(), 100), { deep: true });
262
+ }
263
+ if (import.meta.client && !instance.vnode.el && props.lazy) {
264
+ fetchComponent();
265
+ } else if (import.meta.server || !instance.vnode.el || !nuxtApp.payload.serverRendered) {
266
+ await fetchComponent();
267
+ } else if (selectiveClient && canLoadClientComponent.value) {
268
+ await loadComponents(props.source, payloads.components);
269
+ }
270
+ return (_ctx, _cache) => {
271
+ if (!html.value || error.value) {
272
+ return [slots.fallback?.({ error: error.value }) ?? createVNode("div")];
273
+ }
274
+ return [
275
+ withMemo([key.value], () => {
276
+ return createVNode(Fragment, { key: key.value }, [h(createStaticVNode(html.value || "<div></div>", 1))]);
277
+ }, _cache, 0),
278
+ // should away be triggered ONE tick after re-rendering the static node
279
+ withMemo([teleportKey.value], () => {
280
+ const teleports = [];
281
+ const isKeyOdd = teleportKey.value === 0 || !!(teleportKey.value && !(teleportKey.value % 2));
282
+ if (uid.value && html.value && (import.meta.server || props.lazy ? canTeleport : mounted.value || instance.vnode?.el)) {
283
+ for (const slot in slots) {
284
+ if (availableSlots.value.has(slot)) {
285
+ teleports.push(
286
+ createVNode(
287
+ Teleport,
288
+ // use different selectors for even and odd teleportKey to force trigger the teleport
289
+ { to: import.meta.client ? `${isKeyOdd ? "div" : ""}[data-island-uid="${uid.value}"][data-island-slot="${slot}"]` : `uid=${uid.value};slot=${slot}` },
290
+ { default: () => (payloads.slots?.[slot]?.props?.length ? payloads.slots[slot].props : [{}]).map((data) => slots[slot]?.(data)) }
291
+ )
292
+ );
293
+ }
294
+ }
295
+ if (selectiveClient) {
296
+ if (import.meta.server) {
297
+ if (payloads.components) {
298
+ for (const [id2, info] of Object.entries(payloads.components)) {
299
+ const { html: html2, slots: slots2 } = info;
300
+ let replaced = html2.replaceAll("data-island-uid", `data-island-uid="${uid.value}"`);
301
+ for (const slot in slots2) {
302
+ replaced = replaced.replaceAll(`data-island-slot="${slot}">`, (full) => full + slots2[slot]);
303
+ }
304
+ teleports.push(createVNode(Teleport, { to: `uid=${uid.value};client=${id2}` }, {
305
+ default: () => [createStaticVNode(replaced, 1)]
306
+ }));
307
+ }
308
+ }
309
+ } else if (canLoadClientComponent.value && payloads.components) {
310
+ for (const [id2, info] of Object.entries(payloads.components)) {
311
+ const { props: props2, slots: slots2 } = info;
312
+ const component = components.get(id2);
313
+ const vnode = createVNode(Teleport, { to: `${isKeyOdd ? "div" : ""}[data-island-uid='${uid.value}'][data-island-component="${id2}"]` }, {
314
+ default: () => {
315
+ return [h(component, props2, Object.fromEntries(Object.entries(slots2 || {}).map(([k, v]) => [
316
+ k,
317
+ () => createStaticVNode(`<div style="display: contents" data-island-uid data-island-slot="${k}">${v}</div>`, 1)
318
+ ])))];
319
+ }
320
+ });
321
+ teleports.push(vnode);
322
+ }
323
+ }
324
+ }
325
+ }
326
+ return h(Fragment, teleports);
327
+ }, _cache, 1)
328
+ ];
329
+ };
330
+ }
331
+ });
@@ -0,0 +1,14 @@
1
+ import type { DefineComponent, ExtractPublicPropTypes, MaybeRef, PropType } from 'vue';
2
+ import type { PageMeta } from '../../pages/runtime/composables.js';
3
+ declare const nuxtLayoutProps: {
4
+ name: {
5
+ type: PropType<unknown extends PageMeta["layout"] ? MaybeRef<string | false> : PageMeta["layout"]>;
6
+ default: null;
7
+ };
8
+ fallback: {
9
+ type: PropType<unknown extends PageMeta["layout"] ? MaybeRef<string> : PageMeta["layout"]>;
10
+ default: null;
11
+ };
12
+ };
13
+ declare const _default: DefineComponent<ExtractPublicPropTypes<typeof nuxtLayoutProps>>;
14
+ export default _default;
@@ -0,0 +1,171 @@
1
+ import { Suspense, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, shallowReactive, shallowRef, unref } from "vue";
2
+ import { useRoute, useRouter } from "../composables/router.js";
3
+ import { useNuxtApp } from "../nuxt.js";
4
+ import { _wrapInTransition } from "./utils.js";
5
+ import { LayoutMetaSymbol, PageRouteSymbol } from "./injections.js";
6
+ import { useRoute as useVueRouterRoute } from "#build/pages";
7
+ import layouts from "#build/layouts";
8
+ import { appLayoutTransition as defaultLayoutTransition } from "#build/nuxt.config.mjs";
9
+ const LayoutLoader = defineComponent({
10
+ name: "LayoutLoader",
11
+ inheritAttrs: false,
12
+ props: {
13
+ name: String,
14
+ layoutProps: Object
15
+ },
16
+ setup(props, context) {
17
+ return () => h(layouts[props.name], props.layoutProps, context.slots);
18
+ }
19
+ });
20
+ const nuxtLayoutProps = {
21
+ name: {
22
+ type: [String, Boolean, Object],
23
+ default: null
24
+ },
25
+ fallback: {
26
+ type: [String, Object],
27
+ default: null
28
+ }
29
+ };
30
+ export default defineComponent({
31
+ name: "NuxtLayout",
32
+ inheritAttrs: false,
33
+ props: nuxtLayoutProps,
34
+ setup(props, context) {
35
+ const nuxtApp = useNuxtApp();
36
+ const injectedRoute = inject(PageRouteSymbol);
37
+ const shouldUseEagerRoute = !injectedRoute || injectedRoute === useRoute();
38
+ const route = shouldUseEagerRoute ? useVueRouterRoute() : injectedRoute;
39
+ const layout = computed(() => {
40
+ let layout2 = unref(props.name) ?? route?.meta.layout ?? "default";
41
+ if (layout2 && !(layout2 in layouts)) {
42
+ if (import.meta.dev && layout2 !== "default") {
43
+ console.warn(`Invalid layout \`${layout2}\` selected.`);
44
+ }
45
+ if (props.fallback) {
46
+ layout2 = unref(props.fallback);
47
+ }
48
+ }
49
+ return layout2;
50
+ });
51
+ const layoutRef = shallowRef();
52
+ context.expose({ layoutRef });
53
+ const done = nuxtApp.deferHydration();
54
+ if (import.meta.client && nuxtApp.isHydrating) {
55
+ const removeErrorHook = nuxtApp.hooks.hookOnce("app:error", done);
56
+ useRouter().beforeEach(removeErrorHook);
57
+ }
58
+ if (import.meta.dev) {
59
+ nuxtApp._isNuxtLayoutUsed = true;
60
+ }
61
+ let lastLayout;
62
+ return () => {
63
+ const hasLayout = layout.value && layout.value in layouts;
64
+ const transitionProps = route?.meta.layoutTransition ?? defaultLayoutTransition;
65
+ const previouslyRenderedLayout = lastLayout;
66
+ lastLayout = layout.value;
67
+ return _wrapInTransition(hasLayout && transitionProps, {
68
+ default: () => h(Suspense, { suspensible: true, onResolve: () => {
69
+ nextTick(done);
70
+ } }, {
71
+ default: () => h(
72
+ LayoutProvider,
73
+ {
74
+ layoutProps: mergeProps(context.attrs, { ref: layoutRef }),
75
+ key: layout.value || void 0,
76
+ name: layout.value,
77
+ shouldProvide: !props.name,
78
+ isRenderingNewLayout: (name) => {
79
+ return name !== previouslyRenderedLayout && name === layout.value;
80
+ },
81
+ hasTransition: !!transitionProps
82
+ },
83
+ context.slots
84
+ )
85
+ })
86
+ }).default();
87
+ };
88
+ }
89
+ });
90
+ const LayoutProvider = defineComponent({
91
+ name: "NuxtLayoutProvider",
92
+ inheritAttrs: false,
93
+ props: {
94
+ name: {
95
+ type: [String, Boolean]
96
+ },
97
+ layoutProps: {
98
+ type: Object
99
+ },
100
+ hasTransition: {
101
+ type: Boolean
102
+ },
103
+ shouldProvide: {
104
+ type: Boolean
105
+ },
106
+ isRenderingNewLayout: {
107
+ type: Function,
108
+ required: true
109
+ }
110
+ },
111
+ setup(props, context) {
112
+ const name = props.name;
113
+ if (props.shouldProvide) {
114
+ provide(LayoutMetaSymbol, {
115
+ isCurrent: (route) => name === (route.meta.layout ?? "default")
116
+ });
117
+ }
118
+ const injectedRoute = inject(PageRouteSymbol);
119
+ const isNotWithinNuxtPage = injectedRoute && injectedRoute === useRoute();
120
+ if (isNotWithinNuxtPage) {
121
+ const vueRouterRoute = useVueRouterRoute();
122
+ const reactiveChildRoute = {};
123
+ for (const _key in vueRouterRoute) {
124
+ const key = _key;
125
+ Object.defineProperty(reactiveChildRoute, key, {
126
+ enumerable: true,
127
+ get: () => {
128
+ return props.isRenderingNewLayout(props.name) ? vueRouterRoute[key] : injectedRoute[key];
129
+ }
130
+ });
131
+ }
132
+ provide(PageRouteSymbol, shallowReactive(reactiveChildRoute));
133
+ }
134
+ let vnode;
135
+ if (import.meta.dev && import.meta.client) {
136
+ onMounted(() => {
137
+ nextTick(() => {
138
+ if (["#comment", "#text"].includes(vnode?.el?.nodeName)) {
139
+ if (name) {
140
+ console.warn(`[nuxt] \`${name}\` layout does not have a single root node and will cause errors when navigating between routes.`);
141
+ } else {
142
+ console.warn("[nuxt] `<NuxtLayout>` needs to be passed a single root node in its default slot.");
143
+ }
144
+ }
145
+ });
146
+ });
147
+ }
148
+ return () => {
149
+ if (!name || typeof name === "string" && !(name in layouts)) {
150
+ if (import.meta.dev && import.meta.client && props.hasTransition) {
151
+ vnode = context.slots.default?.();
152
+ return vnode;
153
+ }
154
+ return context.slots.default?.();
155
+ }
156
+ if (import.meta.dev && import.meta.client && props.hasTransition) {
157
+ vnode = h(
158
+ LayoutLoader,
159
+ { key: name, layoutProps: props.layoutProps, name },
160
+ context.slots
161
+ );
162
+ return vnode;
163
+ }
164
+ return h(
165
+ LayoutLoader,
166
+ { key: name, layoutProps: props.layoutProps, name },
167
+ context.slots
168
+ );
169
+ };
170
+ }
171
+ });
@@ -0,0 +1,101 @@
1
+ import type { AllowedComponentProps, AnchorHTMLAttributes, DefineSetupFnComponent, SlotsType, UnwrapRef, VNode, VNodeProps } from 'vue';
2
+ import type { RouteLocation, RouteLocationRaw, RouterLinkProps, UseLinkReturn } from 'vue-router';
3
+ import type { NuxtApp } from '../nuxt.js';
4
+ /**
5
+ * `<NuxtLink>` is a drop-in replacement for both Vue Router's `<RouterLink>` component and HTML's `<a>` tag.
6
+ * @see https://nuxt.com/docs/4.x/api/components/nuxt-link
7
+ */
8
+ export interface NuxtLinkProps<CustomProp extends boolean = false> extends Omit<RouterLinkProps, 'to'> {
9
+ custom?: CustomProp;
10
+ /**
11
+ * Route Location the link should navigate to when clicked on.
12
+ */
13
+ to?: RouteLocationRaw;
14
+ /**
15
+ * An alias for `to`. If used with `to`, `href` will be ignored
16
+ */
17
+ href?: NuxtLinkProps['to'];
18
+ /**
19
+ * Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases
20
+ */
21
+ external?: boolean;
22
+ /**
23
+ * Where to display the linked URL, as the name for a browsing context.
24
+ */
25
+ target?: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null;
26
+ /**
27
+ * A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links.
28
+ */
29
+ rel?: 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | (string & {}) | null;
30
+ /**
31
+ * If set to true, no rel attribute will be added to the link
32
+ */
33
+ noRel?: boolean;
34
+ /**
35
+ * A class to apply to links that have been prefetched.
36
+ */
37
+ prefetchedClass?: string;
38
+ /**
39
+ * When enabled will prefetch middleware, layouts and payloads of links in the viewport.
40
+ */
41
+ prefetch?: boolean;
42
+ /**
43
+ * Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility.
44
+ */
45
+ prefetchOn?: 'visibility' | 'interaction' | Partial<{
46
+ visibility: boolean;
47
+ interaction: boolean;
48
+ }>;
49
+ /**
50
+ * Escape hatch to disable `prefetch` attribute.
51
+ */
52
+ noPrefetch?: boolean;
53
+ /**
54
+ * An option to either add or remove trailing slashes in the `href` for this specific link.
55
+ * Overrides the global `trailingSlash` option if provided.
56
+ */
57
+ trailingSlash?: 'append' | 'remove';
58
+ }
59
+ /**
60
+ * Create a NuxtLink component with given options as defaults.
61
+ * @see https://nuxt.com/docs/4.x/api/components/nuxt-link
62
+ */
63
+ export interface NuxtLinkOptions extends Partial<Pick<RouterLinkProps, 'activeClass' | 'exactActiveClass'>>, Partial<Pick<NuxtLinkProps, 'prefetch' | 'prefetchedClass'>> {
64
+ /**
65
+ * The name of the component.
66
+ * @default "NuxtLink"
67
+ */
68
+ componentName?: string;
69
+ /**
70
+ * A default `rel` attribute value applied on external links. Defaults to `"noopener noreferrer"`. Set it to `""` to disable.
71
+ */
72
+ externalRelAttribute?: string | null;
73
+ /**
74
+ * An option to either add or remove trailing slashes in the `href`.
75
+ * If unset or not matching the valid values `append` or `remove`, it will be ignored.
76
+ */
77
+ trailingSlash?: 'append' | 'remove';
78
+ /**
79
+ * Allows controlling default setting for when to prefetch links. By default, prefetch is triggered only on visibility.
80
+ */
81
+ prefetchOn?: Exclude<NuxtLinkProps['prefetchOn'], string>;
82
+ }
83
+ type NuxtLinkDefaultSlotProps<CustomProp extends boolean = false> = CustomProp extends true ? {
84
+ href: string;
85
+ navigate: (e?: MouseEvent) => Promise<void>;
86
+ prefetch: (nuxtApp?: NuxtApp) => Promise<void>;
87
+ route: (RouteLocation & {
88
+ href: string;
89
+ }) | undefined;
90
+ rel: string | null;
91
+ target: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null;
92
+ isExternal: boolean;
93
+ isActive: false;
94
+ isExactActive: false;
95
+ } : UnwrapRef<UseLinkReturn>;
96
+ type NuxtLinkSlots<CustomProp extends boolean = false> = {
97
+ default?: (props: NuxtLinkDefaultSlotProps<CustomProp>) => VNode[];
98
+ };
99
+ export declare function defineNuxtLink(options: NuxtLinkOptions): (new <CustomProp extends boolean = false>(props: NuxtLinkProps<CustomProp> & VNodeProps & AllowedComponentProps & Omit<AnchorHTMLAttributes, keyof NuxtLinkProps<CustomProp>>) => InstanceType<DefineSetupFnComponent<NuxtLinkProps<CustomProp> & VNodeProps & AllowedComponentProps & Omit<AnchorHTMLAttributes, keyof NuxtLinkProps<CustomProp>>, [], SlotsType<NuxtLinkSlots<CustomProp>>>>) & Record<string, any>;
100
+ declare const _default: (new <CustomProp extends boolean = false>(props: NuxtLinkProps<CustomProp> & VNodeProps & AllowedComponentProps & Omit<AnchorHTMLAttributes, keyof NuxtLinkProps<CustomProp>>) => InstanceType<DefineSetupFnComponent<NuxtLinkProps<CustomProp> & VNodeProps & AllowedComponentProps & Omit<AnchorHTMLAttributes, keyof NuxtLinkProps<CustomProp>>, [], SlotsType<NuxtLinkSlots<CustomProp>>>>) & Record<string, any>;
101
+ export default _default;