@ubean/client 0.3.1 → 0.3.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.
@@ -98,30 +98,43 @@ function createLayoutWrapper(resolveLayoutComponent, defaultLayout) {
98
98
  layoutCache.set(name, raw);
99
99
  return raw;
100
100
  }
101
- return defineComponent({
102
- name: "UbeanLayoutView",
103
- setup() {
104
- const route = useRoute();
105
- watchEffect(async () => {
106
- const layoutField = route.meta.layout;
107
- const names = normalizeLayoutNames(layoutField === void 0 ? defaultLayout ?? void 0 : layoutField, defaultLayout);
108
- if (names.length === 0) {
109
- layoutComps.value = [];
110
- return;
111
- }
112
- const comps = await Promise.all(names.map((n) => loadLayout(n)));
113
- layoutComps.value = comps;
114
- });
115
- return () => {
116
- const comps = layoutComps.value;
117
- if (comps.length === 0) return h(PageView);
118
- return h(LayoutChainRenderer, {
119
- components: comps,
120
- depth: 0
121
- });
122
- };
101
+ /**
102
+ * Load the layout chain for a route into `layoutComps` (outer → inner).
103
+ * `route.meta.layout` is read synchronously, so calling this from a
104
+ * `watchEffect` still tracks the route dependency. The write happens after
105
+ * an `await`, so the first render only includes layouts when this was
106
+ * awaited beforehand (see `preloadLayouts` on the app instance).
107
+ */
108
+ async function loadLayoutsForRoute(route) {
109
+ const layoutField = route.meta.layout;
110
+ const names = normalizeLayoutNames(layoutField === void 0 ? defaultLayout ?? void 0 : layoutField, defaultLayout);
111
+ if (names.length === 0) {
112
+ layoutComps.value = [];
113
+ return;
123
114
  }
124
- });
115
+ const comps = await Promise.all(names.map((n) => loadLayout(n)));
116
+ layoutComps.value = comps;
117
+ }
118
+ return {
119
+ LayoutView: defineComponent({
120
+ name: "UbeanLayoutView",
121
+ setup() {
122
+ const route = useRoute();
123
+ watchEffect(() => {
124
+ loadLayoutsForRoute(route);
125
+ });
126
+ return () => {
127
+ const comps = layoutComps.value;
128
+ if (comps.length === 0) return h(PageView);
129
+ return h(LayoutChainRenderer, {
130
+ components: comps,
131
+ depth: 0
132
+ });
133
+ };
134
+ }
135
+ }),
136
+ loadLayoutsForRoute
137
+ };
125
138
  }
126
139
  /**
127
140
  * Resolve a component from either a direct `Component` or a
@@ -170,9 +183,9 @@ function createUbeanClientApp(options) {
170
183
  ssr: false,
171
184
  setup: options.routerSetup
172
185
  });
173
- const LayoutWrapper = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
186
+ const { LayoutView: ClientLayoutWrapper, loadLayoutsForRoute: loadClientLayouts } = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
174
187
  initCachedViewsFromRoutes(options.routes);
175
- const RootComponent = createRootComponent(LayoutWrapper, page, transitionOpts, false, resolveComp(options.loadingComponent), resolveComp(options.errorComponent));
188
+ const RootComponent = createRootComponent(ClientLayoutWrapper, page, transitionOpts, false, resolveComp(options.loadingComponent), resolveComp(options.errorComponent));
176
189
  const app = options.hydrate ? createSSRApp(RootComponent) : createApp(RootComponent);
177
190
  const i18n = options.i18n ?? createUbeanI18n();
178
191
  app.use(i18n);
@@ -193,7 +206,8 @@ function createUbeanClientApp(options) {
193
206
  app,
194
207
  router,
195
208
  head,
196
- page
209
+ page,
210
+ preloadLayouts: () => loadClientLayouts(router.currentRoute.value)
197
211
  };
198
212
  }
199
213
  function createUbeanSSRApp(initialPage, options) {
@@ -207,9 +221,9 @@ function createUbeanSSRApp(initialPage, options) {
207
221
  initialUrl: initialPage.url,
208
222
  setup: options.routerSetup
209
223
  });
210
- const LayoutWrapper = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
224
+ const { LayoutView: SsrLayoutWrapper, loadLayoutsForRoute: loadSsrLayouts } = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
211
225
  initCachedViewsFromRoutes(options.routes);
212
- const RootComponent = createRootComponent(LayoutWrapper, page, { enabled: false }, true, resolveComp(options.loadingComponent), resolveComp(options.errorComponent));
226
+ const RootComponent = createRootComponent(SsrLayoutWrapper, page, { enabled: false }, true, resolveComp(options.loadingComponent), resolveComp(options.errorComponent));
213
227
  const app = createSSRApp(RootComponent);
214
228
  const i18n = options.i18n ?? createUbeanI18n();
215
229
  app.use(i18n);
@@ -229,7 +243,8 @@ function createUbeanSSRApp(initialPage, options) {
229
243
  return {
230
244
  app,
231
245
  router,
232
- head
246
+ head,
247
+ preloadLayouts: () => loadSsrLayouts(router.currentRoute.value)
233
248
  };
234
249
  }
235
250
  const Head$1 = Head;
@@ -95,12 +95,20 @@ interface UbeanAppInstance {
95
95
  router: ReturnType<typeof createUbeanRouter>;
96
96
  head: VueHeadClient;
97
97
  page: PageObject;
98
+ /**
99
+ * 解析当前路由的布局链并写入 `UbeanLayoutView`。布局组件是异步加载的,
100
+ * 而 `renderToString` / 水合首帧不会等待组件内部的异步加载 —— 在首次渲染前
101
+ * await 该函数(SSR: `router.isReady()` 后;客户端水合: mount 前),
102
+ * 布局才会出现在初始输出中。
103
+ */
104
+ preloadLayouts: () => Promise<void>;
98
105
  }
99
106
  declare function createUbeanClientApp(options: UbeanAppOptions): UbeanAppInstance;
100
107
  declare function createUbeanSSRApp(initialPage: PageObject, options: Omit<UbeanAppOptions, 'initialPage'>): {
101
108
  app: App<Element>;
102
109
  router: import("vue-router")._RouterClassic;
103
110
  head: VueHeadClient;
111
+ preloadLayouts: () => Promise<void>;
104
112
  };
105
113
  declare const Head: import("vue").DefineComponent;
106
114
  //#endregion
package/dist/app.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as CreateUbeanRouterOptions, C as useUnheadHead, D as definePage, E as defineMiddleware, O as UbeanVuePage, S as useSeoMeta, T as defineMeta, _ as VueHeadClient, a as LOCALIZE_PATH_KEY, b as ubeanVue, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, j as createUbeanRouter, k as usePage, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanClientApp, w as useViewTransition, x as useRouter, y as createUbeanSSRApp } from "./app-BP3eySMH.js";
1
+ import { A as CreateUbeanRouterOptions, C as useUnheadHead, D as definePage, E as defineMiddleware, O as UbeanVuePage, S as useSeoMeta, T as defineMeta, _ as VueHeadClient, a as LOCALIZE_PATH_KEY, b as ubeanVue, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, j as createUbeanRouter, k as usePage, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanClientApp, w as useViewTransition, x as useRouter, y as createUbeanSSRApp } from "./app-CsoTBXV5.js";
2
2
  export { type CreateUbeanRouterOptions, ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, type LayoutChainContext, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, UbeanAppInstance, UbeanAppOptions, type UbeanVueOptions, type UbeanVuePage, type VueHeadClient, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useRouter, useSeoMeta, useViewTransition };
package/dist/app.js CHANGED
@@ -1,2 +1,2 @@
1
- import { C as createUbeanRouter, S as definePage, _ as useSeoMeta, a as LOCALIZE_PATH_KEY, b as defineMeta, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useRouter, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useUnheadHead, w as usePage, x as defineMiddleware, y as useViewTransition } from "./app-B6vVB7hp.js";
1
+ import { C as createUbeanRouter, S as definePage, _ as useSeoMeta, a as LOCALIZE_PATH_KEY, b as defineMeta, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useRouter, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useUnheadHead, w as usePage, x as defineMiddleware, y as useViewTransition } from "./app-BU6ZpitN.js";
2
2
  export { ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useRouter, useSeoMeta, useViewTransition };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as CreateUbeanRouterOptions, C as useUnheadHead, D as definePage, E as defineMiddleware, O as UbeanVuePage, S as useSeoMeta, T as defineMeta, _ as VueHeadClient$1, h as UbeanAppOptions, j as createUbeanRouter, k as usePage, m as UbeanAppInstance, n as Head, v as createUbeanClientApp, y as createUbeanSSRApp } from "./app-BP3eySMH.js";
1
+ import { A as CreateUbeanRouterOptions, C as useUnheadHead, D as definePage, E as defineMiddleware, O as UbeanVuePage, S as useSeoMeta, T as defineMeta, _ as VueHeadClient$1, h as UbeanAppOptions, j as createUbeanRouter, k as usePage, m as UbeanAppInstance, n as Head, v as createUbeanClientApp, y as createUbeanSSRApp } from "./app-CsoTBXV5.js";
2
2
  import { AppPluginConfig, DefineAppOptions, ResolvedAppConfig, applyAppConfig, createDefaultAppConfig, defineApp, mergeAppConfig } from "./define-app.js";
3
3
  import { App, ComputedRef, Ref, ShallowRef } from "vue";
4
4
  import { useRouter } from "vue-router";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as createUbeanRouter, S as definePage, _ as useSeoMeta, b as defineMeta, m as createUbeanSSRApp, n as Head, p as createUbeanClientApp, v as useUnheadHead, w as usePage, x as defineMiddleware } from "./app-B6vVB7hp.js";
1
+ import { C as createUbeanRouter, S as definePage, _ as useSeoMeta, b as defineMeta, m as createUbeanSSRApp, n as Head, p as createUbeanClientApp, v as useUnheadHead, w as usePage, x as defineMiddleware } from "./app-BU6ZpitN.js";
2
2
  import { _ as useSwitchLocalePath, a as getI18nRuntimeConfig, c as installUbeanI18n, d as switchLocalePath, f as t, g as useLocaleRoute, h as useLocalePath, i as extractLocaleFromPath, l as localizePath, m as useLocaleHead, n as configureI18nRuntime, o as getLocale, p as useI18n, r as createUbeanI18n, s as initClientI18n, u as setLocale } from "./i18n-t0G3VyBs.js";
3
3
  import { applyAppConfig, createDefaultAppConfig, defineApp, mergeAppConfig } from "./define-app.js";
4
4
  import { computed, getCurrentInstance, markRaw, onMounted, onScopeDispose, onUnmounted, ref, shallowRef, watch } from "vue";
package/dist/server.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { A as CreateUbeanRouterOptions, C as useUnheadHead, D as definePage, E as defineMiddleware, O as UbeanVuePage, S as useSeoMeta, T as defineMeta, _ as VueHeadClient, a as LOCALIZE_PATH_KEY, b as ubeanVue, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, j as createUbeanRouter, k as usePage, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanClientApp, w as useViewTransition, x as useRouter, y as createUbeanSSRApp } from "./app-BP3eySMH.js";
1
+ import { A as CreateUbeanRouterOptions, C as useUnheadHead, D as definePage, E as defineMiddleware, O as UbeanVuePage, S as useSeoMeta, T as defineMeta, _ as VueHeadClient, a as LOCALIZE_PATH_KEY, b as ubeanVue, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, j as createUbeanRouter, k as usePage, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanClientApp, w as useViewTransition, x as useRouter, y as createUbeanSSRApp } from "./app-CsoTBXV5.js";
2
2
  import { createHead as createServerHead } from "@unhead/vue/server";
3
3
  export { type CreateUbeanRouterOptions, ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, type LayoutChainContext, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, UbeanAppInstance, UbeanAppOptions, type UbeanVueOptions, type UbeanVuePage, type VueHeadClient, createServerHead, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useRouter, useSeoMeta, useViewTransition };
package/dist/server.js CHANGED
@@ -1,3 +1,3 @@
1
- import { C as createUbeanRouter, S as definePage, _ as useSeoMeta, a as LOCALIZE_PATH_KEY, b as defineMeta, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useRouter, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useUnheadHead, w as usePage, x as defineMiddleware, y as useViewTransition } from "./app-B6vVB7hp.js";
1
+ import { C as createUbeanRouter, S as definePage, _ as useSeoMeta, a as LOCALIZE_PATH_KEY, b as defineMeta, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useRouter, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useUnheadHead, w as usePage, x as defineMiddleware, y as useViewTransition } from "./app-BU6ZpitN.js";
2
2
  import { createHead as createServerHead } from "@unhead/vue/server";
3
3
  export { ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, createServerHead, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useRouter, useSeoMeta, useViewTransition };
package/dist/ssr.js CHANGED
@@ -109,7 +109,7 @@ async function prepareRender(options, pageObj, renderContext) {
109
109
  renderApp = app;
110
110
  } else {
111
111
  const { createUbeanSSRApp } = await import("@ubean/client/app");
112
- const { app: createdApp, router } = createUbeanSSRApp(pageObj, {
112
+ const { app: createdApp, router, preloadLayouts } = createUbeanSSRApp(pageObj, {
113
113
  routes: options.routes,
114
114
  resolveLayoutComponent: options.resolveLayoutComponent,
115
115
  defaultLayout: options.defaultLayout,
@@ -118,6 +118,7 @@ async function prepareRender(options, pageObj, renderContext) {
118
118
  });
119
119
  if (appConfig) await applyServerAppConfig(createdApp, appConfig);
120
120
  await router.isReady();
121
+ await preloadLayouts();
121
122
  renderApp = createdApp;
122
123
  }
123
124
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/client",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Framework client runtime for ubean — layered over the lean @ubean/vue kernel, adding app factories, unhead, i18n, data layer, islands hydration and SSR state helpers",
5
5
  "files": [
6
6
  "dist"
@@ -32,11 +32,11 @@
32
32
  }
33
33
  },
34
34
  "dependencies": {
35
- "@ubean/i18n": "0.3.1",
36
- "@ubean/islands": "0.3.1",
37
- "@ubean/pages": "0.3.1",
38
- "@ubean/shared": "0.3.1",
39
- "@ubean/vue": "0.3.1",
35
+ "@ubean/i18n": "0.3.2",
36
+ "@ubean/islands": "0.3.2",
37
+ "@ubean/pages": "0.3.2",
38
+ "@ubean/shared": "0.3.2",
39
+ "@ubean/vue": "0.3.2",
40
40
  "@unhead/vue": "^3.4.0",
41
41
  "@vue/server-renderer": "^3.5.42",
42
42
  "vue": "^3.5.42",
@@ -49,7 +49,7 @@
49
49
  "vite-plus": "0.3.0"
50
50
  },
51
51
  "peerDependencies": {
52
- "@ubean/seo": "0.3.1"
52
+ "@ubean/seo": "0.3.2"
53
53
  },
54
54
  "peerDependenciesMeta": {
55
55
  "@ubean/seo": {