Website Structure

This commit is contained in:
supalerk-ar66 2026-01-13 10:46:40 +07:00
parent 62812f2090
commit 71f0676a62
22365 changed files with 4265753 additions and 791 deletions

View file

@ -0,0 +1,2 @@
import type { AsyncComponentLoader } from 'vue';
export declare function createClientPage(loader: AsyncComponentLoader): Promise<any>;

View file

@ -0,0 +1,59 @@
import { getCurrentInstance, h, onMounted, provide, shallowRef } from "vue";
import { isPromise } from "@vue/shared";
import { useNuxtApp } from "#app/nuxt";
import ServerPlaceholder from "#app/components/server-placeholder";
import { clientOnlySymbol } from "#app/components/client-only";
// @__NO_SIDE_EFFECTS__
export async function createClientPage(loader) {
const m = await loader();
const c = m.default || m;
if (import.meta.dev) {
c.__clientOnlyPage = true;
}
return pageToClientOnly(c);
}
const cache = /* @__PURE__ */ new WeakMap();
function pageToClientOnly(component) {
if (import.meta.server) {
return ServerPlaceholder;
}
if (cache.has(component)) {
return cache.get(component);
}
const clone = { ...component };
if (clone.render) {
clone.render = (ctx, cache2, $props, $setup, $data, $options) => $setup.mounted$ ?? ctx.mounted$ ? h(component.render?.bind(ctx)(ctx, cache2, $props, $setup, $data, $options)) : h("div");
} else {
clone.template &&= `
<template v-if="mounted$">${component.template}</template>
<template v-else><div></div></template>
`;
}
clone.setup = (props, ctx) => {
const nuxtApp = useNuxtApp();
const mounted$ = shallowRef(nuxtApp.isHydrating === false);
provide(clientOnlySymbol, true);
const vm = getCurrentInstance();
if (vm) {
vm._nuxtClientOnly = true;
}
onMounted(() => {
mounted$.value = true;
});
const setupState = component.setup?.(props, ctx) || {};
if (isPromise(setupState)) {
return Promise.resolve(setupState).then((setupState2) => {
if (typeof setupState2 !== "function") {
setupState2 ||= {};
setupState2.mounted$ = mounted$;
return setupState2;
}
return (...args) => mounted$.value || !nuxtApp.isHydrating ? h(setupState2(...args)) : h("div");
});
} else {
return typeof setupState === "function" ? (...args) => mounted$.value || !nuxtApp.isHydrating ? h(setupState(...args)) : h("div") : Object.assign(setupState, { mounted$ });
}
};
cache.set(component, clone);
return clone;
}

View file

@ -0,0 +1,124 @@
import type { AsyncComponentLoader, ExtractPropTypes } from 'vue';
export declare const createLazyVisibleComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateOnVisible: {
type: () => true | IntersectionObserverInit;
required: false;
default: boolean;
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateOnVisible: {
type: () => true | IntersectionObserverInit;
required: false;
default: boolean;
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {
hydrateOnVisible: true | IntersectionObserverInit;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createLazyIdleComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateOnIdle: {
type: () => true | number;
required: false;
default: boolean;
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateOnIdle: {
type: () => true | number;
required: false;
default: boolean;
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {
hydrateOnIdle: number | true;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createLazyInteractionComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateOnInteraction: {
type: () => keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap> | true;
required: false;
default: ("click" | "focus" | "pointerenter")[];
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateOnInteraction: {
type: () => keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap> | true;
required: false;
default: ("click" | "focus" | "pointerenter")[];
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {
hydrateOnInteraction: true | keyof HTMLElementEventMap | (keyof HTMLElementEventMap)[];
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createLazyMediaQueryComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateOnMediaQuery: {
type: () => string;
required: true;
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateOnMediaQuery: {
type: () => string;
required: true;
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createLazyIfComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateWhen: {
type: BooleanConstructor;
default: boolean;
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateWhen: {
type: BooleanConstructor;
default: boolean;
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {
hydrateWhen: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createLazyTimeComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateAfter: {
type: NumberConstructor;
required: true;
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateAfter: {
type: NumberConstructor;
required: true;
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createLazyNeverComponent: (id: string, loader: AsyncComponentLoader) => import("vue").DefineComponent<ExtractPropTypes<{
hydrateNever: {
type: () => true;
required: false;
default: boolean;
};
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "hydrated"[], "hydrated", import("vue").PublicProps, Readonly<ExtractPropTypes<{
hydrateNever: {
type: () => true;
required: false;
default: boolean;
};
}>> & Readonly<{
onHydrated?: ((...args: any[]) => any) | undefined;
}>, {
hydrateNever: true;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;

View file

@ -0,0 +1,101 @@
import { defineAsyncComponent, defineComponent, h, hydrateOnIdle, hydrateOnInteraction, hydrateOnMediaQuery, hydrateOnVisible, mergeProps } from "vue";
import { useNuxtApp } from "#app/nuxt";
function defineLazyComponent(props, defineStrategy) {
return (id, loader) => defineComponent({
inheritAttrs: false,
props,
emits: ["hydrated"],
setup(props2, ctx) {
if (import.meta.server) {
const nuxtApp = useNuxtApp();
nuxtApp.hook("app:rendered", ({ ssrContext }) => {
ssrContext.modules.delete(id);
});
}
const child = defineAsyncComponent({ loader });
const comp = defineAsyncComponent({
hydrate: defineStrategy(props2),
loader: () => Promise.resolve(child)
});
const onVnodeMounted = () => {
ctx.emit("hydrated");
};
return () => h(comp, mergeProps(ctx.attrs, { onVnodeMounted }), ctx.slots);
}
});
}
export const createLazyVisibleComponent = defineLazyComponent(
{
hydrateOnVisible: {
type: [Object, Boolean],
required: false,
default: true
}
},
(props) => hydrateOnVisible(props.hydrateOnVisible === true ? void 0 : props.hydrateOnVisible)
);
export const createLazyIdleComponent = defineLazyComponent(
{
hydrateOnIdle: {
type: [Number, Boolean],
required: false,
default: true
}
},
(props) => props.hydrateOnIdle === 0 ? void 0 : hydrateOnIdle(props.hydrateOnIdle === true ? void 0 : props.hydrateOnIdle)
);
const defaultInteractionEvents = ["pointerenter", "click", "focus"];
export const createLazyInteractionComponent = defineLazyComponent(
{
hydrateOnInteraction: {
type: [String, Array],
required: false,
default: defaultInteractionEvents
}
},
(props) => hydrateOnInteraction(props.hydrateOnInteraction === true ? defaultInteractionEvents : props.hydrateOnInteraction || defaultInteractionEvents)
);
export const createLazyMediaQueryComponent = defineLazyComponent(
{
hydrateOnMediaQuery: {
type: String,
required: true
}
},
(props) => hydrateOnMediaQuery(props.hydrateOnMediaQuery)
);
export const createLazyIfComponent = defineLazyComponent(
{
hydrateWhen: {
type: Boolean,
default: true
}
},
(props) => props.hydrateWhen ? void 0 : () => {
}
/* Vue will trigger the hydration automatically when the prop changes */
);
export const createLazyTimeComponent = defineLazyComponent(
{
hydrateAfter: {
type: Number,
required: true
}
},
(props) => props.hydrateAfter === 0 ? void 0 : (hydrate) => {
const id = setTimeout(hydrate, props.hydrateAfter);
return () => clearTimeout(id);
}
);
const hydrateNever = /* @__NO_SIDE_EFFECTS__ */ () => {
};
export const createLazyNeverComponent = defineLazyComponent(
{
hydrateNever: {
type: Boolean,
required: false,
default: true
}
},
() => hydrateNever
);

View file

@ -0,0 +1,20 @@
export declare const createServerComponent: (name: string) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
lazy: BooleanConstructor;
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "error"[], "error", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
lazy: BooleanConstructor;
}>> & Readonly<{
onError?: ((...args: any[]) => any) | undefined;
}>, {
lazy: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export declare const createIslandPage: (name: string) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
lazy: BooleanConstructor;
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
lazy: BooleanConstructor;
}>> & Readonly<{}>, {
lazy: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;

View file

@ -0,0 +1,69 @@
import { defineComponent, getCurrentInstance, h, ref } from "vue";
import NuxtIsland from "#app/components/nuxt-island";
import { useRoute } from "#app/composables/router";
import { isPrerendered } from "#app/composables/payload";
import { createError, showError } from "#app/composables/error";
import { useNuxtApp } from "#app/nuxt";
export const createServerComponent = /* @__NO_SIDE_EFFECTS__ */ (name) => {
return defineComponent({
name,
inheritAttrs: false,
props: { lazy: Boolean },
emits: ["error"],
setup(props, { attrs, slots, expose, emit }) {
const vm = getCurrentInstance();
const islandRef = ref(null);
expose({
refresh: () => islandRef.value?.refresh()
});
return () => {
return h(NuxtIsland, {
name,
lazy: props.lazy,
props: attrs,
scopeId: vm?.vnode.scopeId,
ref: islandRef,
onError: (err) => {
emit("error", err);
}
}, slots);
};
}
});
};
export const createIslandPage = /* @__NO_SIDE_EFFECTS__ */ (name) => {
return defineComponent({
name,
inheritAttrs: false,
props: { lazy: Boolean },
async setup(props, { slots, expose }) {
const islandRef = ref(null);
expose({
refresh: () => islandRef.value?.refresh()
});
const nuxtApp = useNuxtApp();
const route = useRoute();
const path = import.meta.client && await isPrerendered(route.path) ? route.path : route.fullPath.replace(/#.*$/, "");
return () => {
return h("div", [
h(NuxtIsland, {
name: `page_${name}`,
lazy: props.lazy,
ref: islandRef,
context: { url: path },
onError: (e) => {
if (e.cause && e.cause instanceof Response) {
throw createError({
statusCode: e.cause.status,
statusText: e.cause.statusText,
status: e.cause.status
});
}
nuxtApp.runWithContext(() => showError(e));
}
}, slots)
]);
};
}
});
};