@ubean/runtime 0.1.2 → 0.1.3
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.
- package/dist/app-CDOvFfdJ.d.ts +210 -0
- package/dist/app-dx92OPRP.js +892 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.js +2 -0
- package/dist/define-app.d.ts +82 -0
- package/dist/define-app.js +44 -0
- package/dist/index.d.ts +393 -0
- package/dist/index.js +364 -0
- package/dist/view-transitions-DRrLaRHL.d.ts +12 -0
- package/package.json +6 -6
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
import { useHead as useUnheadHead, useSeoMeta } from "@unhead/vue";
|
|
2
|
+
import { LOCALE_DATA_ID } from "@ubean/pages";
|
|
3
|
+
import { KeepAlive, Transition, computed, createApp, createSSRApp, defineComponent, h, inject, markRaw, provide, reactive, ref, shallowRef, watchEffect } from "vue";
|
|
4
|
+
import { RouterLink, RouterView, createMemoryHistory, createRouter, createWebHistory, useRoute, useRouter } from "vue-router";
|
|
5
|
+
import { Head } from "@unhead/vue/components";
|
|
6
|
+
import { addLocale, clearLocales, defineLocale, detectBrowserLocale, detectLocale, extractLocaleFromPath, getDefaultLocale, getI18nConfig, getLocale, getLocaleDir, getLocaleName, getRegisteredLocales, localizePath, mergeLocale, onLocaleChange, setI18nConfig, setLocale, switchLocalePath, t, useI18n } from "@ubean/i18n";
|
|
7
|
+
//#region src/i18n.ts
|
|
8
|
+
const _global$1 = globalThis;
|
|
9
|
+
function hydrateLocale() {
|
|
10
|
+
if (typeof _global$1.document === "undefined") return {
|
|
11
|
+
locale: null,
|
|
12
|
+
dir: "ltr"
|
|
13
|
+
};
|
|
14
|
+
const el = _global$1.document.getElementById(LOCALE_DATA_ID);
|
|
15
|
+
if (!el) return {
|
|
16
|
+
locale: null,
|
|
17
|
+
dir: "ltr"
|
|
18
|
+
};
|
|
19
|
+
try {
|
|
20
|
+
const data = JSON.parse(el.textContent || "null");
|
|
21
|
+
if (data && typeof data.locale === "string") return {
|
|
22
|
+
locale: data.locale,
|
|
23
|
+
dir: data.dir === "rtl" ? "rtl" : "ltr",
|
|
24
|
+
messages: data.messages,
|
|
25
|
+
availableLocales: Array.isArray(data.availableLocales) ? data.availableLocales : void 0
|
|
26
|
+
};
|
|
27
|
+
} catch {
|
|
28
|
+
return {
|
|
29
|
+
locale: null,
|
|
30
|
+
dir: "ltr"
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
locale: null,
|
|
35
|
+
dir: "ltr"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function syncHtmlLang(locale, dir) {
|
|
39
|
+
if (typeof _global$1.document === "undefined") return;
|
|
40
|
+
const html = _global$1.document.documentElement;
|
|
41
|
+
if (html) {
|
|
42
|
+
html.setAttribute("lang", locale);
|
|
43
|
+
html.setAttribute("dir", dir);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const { locale: hydratedLocale, dir: hydratedDir, messages: hydratedMessages, availableLocales: hydratedAvailable } = hydrateLocale();
|
|
47
|
+
if (hydratedLocale) {
|
|
48
|
+
if (hydratedAvailable && hydratedAvailable.length > 0) {
|
|
49
|
+
const sorted = [...hydratedAvailable].sort((a, b) => (b.isDefault ? 1 : 0) - (a.isDefault ? 1 : 0));
|
|
50
|
+
for (const loc of sorted) {
|
|
51
|
+
const isCurrent = loc.code === hydratedLocale;
|
|
52
|
+
defineLocale({
|
|
53
|
+
code: loc.code,
|
|
54
|
+
messages: isCurrent && hydratedMessages ? hydratedMessages : {},
|
|
55
|
+
name: loc.name,
|
|
56
|
+
dir: loc.dir,
|
|
57
|
+
isDefault: loc.isDefault
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
} else if (hydratedMessages && typeof hydratedMessages === "object") defineLocale({
|
|
61
|
+
code: hydratedLocale,
|
|
62
|
+
messages: hydratedMessages,
|
|
63
|
+
dir: hydratedDir
|
|
64
|
+
});
|
|
65
|
+
setLocale(hydratedLocale);
|
|
66
|
+
syncHtmlLang(hydratedLocale, hydratedDir);
|
|
67
|
+
}
|
|
68
|
+
const localeRef = ref(getLocale());
|
|
69
|
+
onLocaleChange((newLocale) => {
|
|
70
|
+
localeRef.value = newLocale;
|
|
71
|
+
syncHtmlLang(newLocale, getLocaleDir(newLocale));
|
|
72
|
+
});
|
|
73
|
+
function useI18n$1() {
|
|
74
|
+
const core = useI18n();
|
|
75
|
+
const localeDir = computed(() => getLocaleDir(localeRef.value));
|
|
76
|
+
const localeName = computed(() => getLocaleName(localeRef.value));
|
|
77
|
+
function translate(key, params) {
|
|
78
|
+
localeRef.value;
|
|
79
|
+
return core.t(key, params);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
locale: localeRef,
|
|
83
|
+
get fallbackLocale() {
|
|
84
|
+
return core.fallbackLocale;
|
|
85
|
+
},
|
|
86
|
+
get availableLocales() {
|
|
87
|
+
return core.availableLocales;
|
|
88
|
+
},
|
|
89
|
+
t: translate,
|
|
90
|
+
setLocale(locale) {
|
|
91
|
+
core.setLocale(locale);
|
|
92
|
+
},
|
|
93
|
+
getLocale() {
|
|
94
|
+
return localeRef.value;
|
|
95
|
+
},
|
|
96
|
+
onLocaleChange(callback) {
|
|
97
|
+
return core.onLocaleChange(callback);
|
|
98
|
+
},
|
|
99
|
+
getLocaleDir(locale) {
|
|
100
|
+
return core.getLocaleDir(locale);
|
|
101
|
+
},
|
|
102
|
+
getLocaleName(locale) {
|
|
103
|
+
return core.getLocaleName(locale);
|
|
104
|
+
},
|
|
105
|
+
localeDir,
|
|
106
|
+
localeName
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function defineLocale$1(definition) {
|
|
110
|
+
const result = defineLocale(definition);
|
|
111
|
+
localeRef.value = getLocale();
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
function t$1(key, params) {
|
|
115
|
+
return t(key, params);
|
|
116
|
+
}
|
|
117
|
+
function setLocale$1(locale) {
|
|
118
|
+
setLocale(locale);
|
|
119
|
+
}
|
|
120
|
+
function getLocale$1() {
|
|
121
|
+
return localeRef.value;
|
|
122
|
+
}
|
|
123
|
+
function onLocaleChange$1(callback) {
|
|
124
|
+
return onLocaleChange(callback);
|
|
125
|
+
}
|
|
126
|
+
function getLocaleDir$1(locale) {
|
|
127
|
+
return getLocaleDir(locale);
|
|
128
|
+
}
|
|
129
|
+
function getLocaleName$1(locale) {
|
|
130
|
+
return getLocaleName(locale);
|
|
131
|
+
}
|
|
132
|
+
function getRegisteredLocales$1() {
|
|
133
|
+
return getRegisteredLocales();
|
|
134
|
+
}
|
|
135
|
+
function detectLocale$1(acceptLanguage) {
|
|
136
|
+
return detectLocale(acceptLanguage);
|
|
137
|
+
}
|
|
138
|
+
function detectBrowserLocale$1() {
|
|
139
|
+
return detectBrowserLocale();
|
|
140
|
+
}
|
|
141
|
+
function addLocale$1(code, messages, options) {
|
|
142
|
+
addLocale(code, messages, options);
|
|
143
|
+
}
|
|
144
|
+
function mergeLocale$1(code, messages) {
|
|
145
|
+
mergeLocale(code, messages);
|
|
146
|
+
}
|
|
147
|
+
function clearLocales$1() {
|
|
148
|
+
clearLocales();
|
|
149
|
+
localeRef.value = getLocale();
|
|
150
|
+
}
|
|
151
|
+
function getI18nConfig$1() {
|
|
152
|
+
return getI18nConfig();
|
|
153
|
+
}
|
|
154
|
+
function setI18nConfig$1(config) {
|
|
155
|
+
setI18nConfig(config);
|
|
156
|
+
}
|
|
157
|
+
function localizePath$1(path, locale) {
|
|
158
|
+
return localizePath(path, locale);
|
|
159
|
+
}
|
|
160
|
+
function switchLocalePath$1(newLocale, currentPath) {
|
|
161
|
+
return switchLocalePath(newLocale, currentPath);
|
|
162
|
+
}
|
|
163
|
+
function getDefaultLocale$1() {
|
|
164
|
+
return getDefaultLocale();
|
|
165
|
+
}
|
|
166
|
+
function extractLocaleFromPath$1(path) {
|
|
167
|
+
return extractLocaleFromPath(path);
|
|
168
|
+
}
|
|
169
|
+
function useSwitchLocalePath() {
|
|
170
|
+
return computed(() => (newLocale) => {
|
|
171
|
+
return switchLocalePath(newLocale, typeof _global$1.window !== "undefined" ? _global$1.window.location.pathname : "/");
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function useLocalePath() {
|
|
175
|
+
return computed(() => (path, locale) => {
|
|
176
|
+
return localizePath(path, locale || localeRef.value);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/router.ts
|
|
181
|
+
function createUbeanRouter(options) {
|
|
182
|
+
const base = options.base || "/";
|
|
183
|
+
const router = createRouter({
|
|
184
|
+
history: options.ssr ? createMemoryHistory(base) : createWebHistory(base),
|
|
185
|
+
routes: options.routes,
|
|
186
|
+
scrollBehavior(_to, _from, savedPosition) {
|
|
187
|
+
if (savedPosition) return savedPosition;
|
|
188
|
+
if (_to.hash) return {
|
|
189
|
+
el: _to.hash,
|
|
190
|
+
behavior: "smooth"
|
|
191
|
+
};
|
|
192
|
+
return { top: 0 };
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
if (options.setup) options.setup(router);
|
|
196
|
+
if (options.ssr && options.initialUrl) router.push(options.initialUrl);
|
|
197
|
+
return router;
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/cache-views.ts
|
|
201
|
+
/**
|
|
202
|
+
* Page cache (keep-alive) store — a module-level singleton.
|
|
203
|
+
*
|
|
204
|
+
* ubean uses flat single-layer layout, so all page components are direct
|
|
205
|
+
* children of a single layout's `<RouterView>`. A `<keep-alive :include="...">`
|
|
206
|
+
* wraps that `<RouterView>`; the `include` list is the reactive array exposed
|
|
207
|
+
* here. Caching is keyed by the page's **route name**, which is injected as the
|
|
208
|
+
* component `name` at render time (see `createLayoutWrapper` in `app.ts`).
|
|
209
|
+
*
|
|
210
|
+
* In addition to the `include` list, an `exclude` list is also maintained.
|
|
211
|
+
* `<keep-alive :exclude="...">` skips caching for matched names even if they
|
|
212
|
+
* appear in `include`. This is useful for the "reload current page" pattern:
|
|
213
|
+
* temporarily push a route name into `exclude`, wait a tick, then remove it —
|
|
214
|
+
* the cached instance is pruned and the page remounts fresh on next visit.
|
|
215
|
+
*
|
|
216
|
+
* Usage:
|
|
217
|
+
* // declarative (compile-time): enable caching for a page
|
|
218
|
+
* definePage({ cache: true })
|
|
219
|
+
*
|
|
220
|
+
* // runtime: toggle caching imperatively
|
|
221
|
+
* import { enablePageCache, disablePageCache } from '@ubean/runtime';
|
|
222
|
+
* enablePageCache('DashboardIndex');
|
|
223
|
+
* disablePageCache('DashboardIndex');
|
|
224
|
+
*
|
|
225
|
+
* // reload a cached page (clears its instance, forces remount)
|
|
226
|
+
* import { resetRouteCache } from '@ubean/runtime';
|
|
227
|
+
* await resetRouteCache('DashboardIndex');
|
|
228
|
+
*/
|
|
229
|
+
const _g = globalThis;
|
|
230
|
+
const _cachedViewNames = _g.__ubeanCachedViewNames ??= ref([]);
|
|
231
|
+
const _excludedViewNames = _g.__ubeanExcludedViewNames ??= ref([]);
|
|
232
|
+
const _cacheEnabled = _g.__ubeanCacheEnabled ??= ref(true);
|
|
233
|
+
/**
|
|
234
|
+
* Composable for reactive access to the page cache store.
|
|
235
|
+
*
|
|
236
|
+
* Safe to call inside any component `setup()`; the returned computeds are
|
|
237
|
+
* tracked by the rendering effect so `<keep-alive :include>` stays in sync.
|
|
238
|
+
*/
|
|
239
|
+
function useCacheViews() {
|
|
240
|
+
return {
|
|
241
|
+
cachedViews: computed(() => _cacheEnabled.value ? _cachedViewNames.value : []),
|
|
242
|
+
cachedViewNames: computed(() => _cachedViewNames.value),
|
|
243
|
+
excludedViews: computed(() => _excludedViewNames.value),
|
|
244
|
+
enabled: computed(() => _cacheEnabled.value),
|
|
245
|
+
enable: () => {
|
|
246
|
+
_cacheEnabled.value = true;
|
|
247
|
+
},
|
|
248
|
+
disable: () => {
|
|
249
|
+
_cacheEnabled.value = false;
|
|
250
|
+
},
|
|
251
|
+
add: (name) => {
|
|
252
|
+
if (name && !_cachedViewNames.value.includes(name)) _cachedViewNames.value = [..._cachedViewNames.value, name];
|
|
253
|
+
},
|
|
254
|
+
remove: (name) => {
|
|
255
|
+
_cachedViewNames.value = _cachedViewNames.value.filter((n) => n !== name);
|
|
256
|
+
},
|
|
257
|
+
has: (name) => _cachedViewNames.value.includes(name),
|
|
258
|
+
clear: () => {
|
|
259
|
+
_cachedViewNames.value = [];
|
|
260
|
+
},
|
|
261
|
+
addExclude: (name) => {
|
|
262
|
+
if (name && !_excludedViewNames.value.includes(name)) _excludedViewNames.value = [..._excludedViewNames.value, name];
|
|
263
|
+
},
|
|
264
|
+
removeExclude: (name) => {
|
|
265
|
+
_excludedViewNames.value = _excludedViewNames.value.filter((n) => n !== name);
|
|
266
|
+
},
|
|
267
|
+
hasExclude: (name) => _excludedViewNames.value.includes(name),
|
|
268
|
+
clearExclude: () => {
|
|
269
|
+
_excludedViewNames.value = [];
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/** Enable keep-alive caching for a specific page (by route name). */
|
|
274
|
+
function enablePageCache(name) {
|
|
275
|
+
if (name && !_cachedViewNames.value.includes(name)) _cachedViewNames.value = [..._cachedViewNames.value, name];
|
|
276
|
+
}
|
|
277
|
+
/** Disable keep-alive caching for a specific page (by route name). */
|
|
278
|
+
function disablePageCache(name) {
|
|
279
|
+
_cachedViewNames.value = _cachedViewNames.value.filter((n) => n !== name);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Temporarily exclude a page from keep-alive (forces its cached instance
|
|
283
|
+
* to be pruned on next render). Pair with `includePageCache()` to restore.
|
|
284
|
+
*
|
|
285
|
+
* Useful for the "reload current page" pattern: push the route name into
|
|
286
|
+
* the exclude list, wait a tick, then remove it — the cached instance is
|
|
287
|
+
* pruned and the page remounts fresh on next render.
|
|
288
|
+
*/
|
|
289
|
+
function excludePageCache(name) {
|
|
290
|
+
if (name && !_excludedViewNames.value.includes(name)) _excludedViewNames.value = [..._excludedViewNames.value, name];
|
|
291
|
+
}
|
|
292
|
+
/** Remove a route name from the cache exclude list (restores caching). */
|
|
293
|
+
function includePageCache(name) {
|
|
294
|
+
_excludedViewNames.value = _excludedViewNames.value.filter((n) => n !== name);
|
|
295
|
+
}
|
|
296
|
+
/** Whether a specific page is currently excluded from cache. */
|
|
297
|
+
function isPageExcluded(name) {
|
|
298
|
+
return _excludedViewNames.value.includes(name);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Reload a cached page by temporarily excluding it from keep-alive.
|
|
302
|
+
*
|
|
303
|
+
* Pattern (mirrors `routeStore.resetRouteCache` in soybean-unify):
|
|
304
|
+
* 1. Push the route name into the exclude list (prunes cached instance).
|
|
305
|
+
* 2. Wait one tick (let `<keep-alive>` reconcile).
|
|
306
|
+
* 3. Remove the route name from the exclude list.
|
|
307
|
+
*
|
|
308
|
+
* The page's `definePage({ cache: true })` declaration (or a prior
|
|
309
|
+
* `enablePageCache(name)`) is still in effect, so the page will be re-cached
|
|
310
|
+
* on the next visit.
|
|
311
|
+
*
|
|
312
|
+
* @param name Route name. If omitted, uses the current route's name
|
|
313
|
+
* (requires a Vue component setup context — fall back to
|
|
314
|
+
* passing the name explicitly from outside Vue).
|
|
315
|
+
* @param delay Milliseconds to wait between exclude and include. Defaults
|
|
316
|
+
* to 50ms (matches soybean-unify's pattern).
|
|
317
|
+
*/
|
|
318
|
+
async function resetRouteCache(name, delay = 50) {
|
|
319
|
+
const target = name;
|
|
320
|
+
if (!target) return;
|
|
321
|
+
if (!_cachedViewNames.value.includes(target)) return;
|
|
322
|
+
excludePageCache(target);
|
|
323
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
324
|
+
includePageCache(target);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Invalidate cached page instance(s).
|
|
328
|
+
*
|
|
329
|
+
* - With a `name`: removes that page from the cache (its instance is pruned
|
|
330
|
+
* on next navigation).
|
|
331
|
+
* - Without a `name`: clears all cached pages.
|
|
332
|
+
*
|
|
333
|
+
* Note: the page will be re-cached on next visit if its `definePage({ cache: true })`
|
|
334
|
+
* is still in effect or `enablePageCache(name)` is called again.
|
|
335
|
+
*/
|
|
336
|
+
function invalidatePageCache(name) {
|
|
337
|
+
if (name) disablePageCache(name);
|
|
338
|
+
else _cachedViewNames.value = [];
|
|
339
|
+
}
|
|
340
|
+
/** Whether a specific page is currently cached. */
|
|
341
|
+
function isPageCached(name) {
|
|
342
|
+
return _cachedViewNames.value.includes(name);
|
|
343
|
+
}
|
|
344
|
+
/** Whether page caching is globally enabled. */
|
|
345
|
+
function isCacheEnabled() {
|
|
346
|
+
return _cacheEnabled.value;
|
|
347
|
+
}
|
|
348
|
+
/** Reactive ref of cached route names — for advanced use cases. */
|
|
349
|
+
function getCachedViewNames() {
|
|
350
|
+
return _cachedViewNames;
|
|
351
|
+
}
|
|
352
|
+
/** Reactive ref of excluded route names — for advanced use cases. */
|
|
353
|
+
function getExcludedViewNames() {
|
|
354
|
+
return _excludedViewNames;
|
|
355
|
+
}
|
|
356
|
+
/** Reactive ref of the global cache-enabled flag. */
|
|
357
|
+
function getCacheEnabled() {
|
|
358
|
+
return _cacheEnabled;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Seed the cache include list from route metadata.
|
|
362
|
+
*
|
|
363
|
+
* Called once during app bootstrap (`createUbeanApp`) to honor pages that
|
|
364
|
+
* declared `definePage({ cache: true })`. Routes without `meta.cache` are
|
|
365
|
+
* left untouched so runtime toggling remains possible.
|
|
366
|
+
*/
|
|
367
|
+
function initCachedViewsFromRoutes(routes) {
|
|
368
|
+
const initial = [];
|
|
369
|
+
for (const route of routes) if (route.meta?.cache === true && typeof route.name === "string" && route.name) {
|
|
370
|
+
if (!initial.includes(route.name)) initial.push(route.name);
|
|
371
|
+
}
|
|
372
|
+
if (initial.length > 0) {
|
|
373
|
+
const existing = new Set(_cachedViewNames.value);
|
|
374
|
+
for (const name of initial) if (!existing.has(name)) existing.add(name);
|
|
375
|
+
_cachedViewNames.value = [...existing];
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
//#endregion
|
|
379
|
+
//#region src/page-runtime.ts
|
|
380
|
+
/**
|
|
381
|
+
* Global page runtime config — animation mode + reload signal.
|
|
382
|
+
*
|
|
383
|
+
* These module-level singletons mirror the patterns found in soybean-unify's
|
|
384
|
+
* `themeStore.pageAnimateMode` and `appStore.reloadSignal`:
|
|
385
|
+
*
|
|
386
|
+
* - `pageAnimateMode` is a global transition name applied to every
|
|
387
|
+
* `<PageView />` unless overridden by the `transition` prop or
|
|
388
|
+
* `route.meta.transition`. Set to `'none'` (or empty string) to disable
|
|
389
|
+
* transitions globally.
|
|
390
|
+
*
|
|
391
|
+
* - `reloadSignal` is a counter that increments each time `reloadPage()` is
|
|
392
|
+
* called. `<PageView />` watches this counter (via `:key`) and remounts
|
|
393
|
+
* the current page when it changes — combined with `resetRouteCache()` to
|
|
394
|
+
* prune the cached keep-alive instance so the remount is fresh.
|
|
395
|
+
*
|
|
396
|
+
* These are intentionally framework-provided singletons (not pinia stores)
|
|
397
|
+
* because ubean ships without a state management library and the values are
|
|
398
|
+
* globally unique by nature.
|
|
399
|
+
*/
|
|
400
|
+
const _pageTransitionName = ref("");
|
|
401
|
+
const _reloadCounter = ref(0);
|
|
402
|
+
/**
|
|
403
|
+
* Composable for reactive access to the global page transition name.
|
|
404
|
+
*
|
|
405
|
+
* Used by `<PageView />` as the fallback transition name when neither the
|
|
406
|
+
* `transition` prop nor `route.meta.transition` is set.
|
|
407
|
+
*
|
|
408
|
+
* Layout components can also read this to display a settings UI:
|
|
409
|
+
*
|
|
410
|
+
* ```ts
|
|
411
|
+
* const transition = usePageTransition();
|
|
412
|
+
* // transition.name.value === 'fade-slide'
|
|
413
|
+
* transition.set('zoom-fadein');
|
|
414
|
+
* transition.clear();
|
|
415
|
+
* ```
|
|
416
|
+
*/
|
|
417
|
+
function usePageTransition() {
|
|
418
|
+
return {
|
|
419
|
+
name: computed(() => _pageTransitionName.value),
|
|
420
|
+
set: (name) => {
|
|
421
|
+
_pageTransitionName.value = name === "none" ? "" : name;
|
|
422
|
+
},
|
|
423
|
+
clear: () => {
|
|
424
|
+
_pageTransitionName.value = "";
|
|
425
|
+
},
|
|
426
|
+
enabled: computed(() => _pageTransitionName.value !== "")
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/** Imperatively set the global page transition name. */
|
|
430
|
+
function setPageTransition(name) {
|
|
431
|
+
_pageTransitionName.value = name === "none" ? "" : name;
|
|
432
|
+
}
|
|
433
|
+
/** Imperatively clear the global page transition name (disables transitions). */
|
|
434
|
+
function clearPageTransition() {
|
|
435
|
+
_pageTransitionName.value = "";
|
|
436
|
+
}
|
|
437
|
+
/** Reactive ref of the global transition name — for advanced use cases. */
|
|
438
|
+
function getPageTransitionName() {
|
|
439
|
+
return _pageTransitionName;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Internal flag — set to `true` while a reload is in progress so consumers
|
|
443
|
+
* can show a loading indicator if they wish.
|
|
444
|
+
*/
|
|
445
|
+
const _reloading = ref(false);
|
|
446
|
+
/**
|
|
447
|
+
* Composable for reactive access to the page reload signal.
|
|
448
|
+
*
|
|
449
|
+
* `<PageView />` uses the returned `counter` as part of its render key, so
|
|
450
|
+
* each `reload()` call forces the current page to remount. Combined with
|
|
451
|
+
* `resetRouteCache()` (called internally), the cached keep-alive instance is
|
|
452
|
+
* pruned first, so the remount is fresh — equivalent to the
|
|
453
|
+
* `v-if="appStore.reloadSignal"` pattern in soybean-unify's layout-content.
|
|
454
|
+
*
|
|
455
|
+
* Usage from any component:
|
|
456
|
+
*
|
|
457
|
+
* ```ts
|
|
458
|
+
* const { reload } = useReloadSignal();
|
|
459
|
+
* async function onReloadClick() {
|
|
460
|
+
* await reload(); // reloads the current page
|
|
461
|
+
* }
|
|
462
|
+
* ```
|
|
463
|
+
*
|
|
464
|
+
* @param routeNameGetter Optional function returning the current route name.
|
|
465
|
+
* If provided, used to call `resetRouteCache(name)`.
|
|
466
|
+
* If omitted, `reload()` only bumps the counter.
|
|
467
|
+
*/
|
|
468
|
+
function useReloadSignal(routeNameGetter) {
|
|
469
|
+
return {
|
|
470
|
+
counter: computed(() => _reloadCounter.value),
|
|
471
|
+
reloading: computed(() => _reloading.value),
|
|
472
|
+
reload: async (routeName, duration = 300) => {
|
|
473
|
+
_reloading.value = true;
|
|
474
|
+
try {
|
|
475
|
+
const name = routeName ?? routeNameGetter?.();
|
|
476
|
+
if (name) await resetRouteCache(name, 50);
|
|
477
|
+
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
478
|
+
_reloadCounter.value++;
|
|
479
|
+
} finally {
|
|
480
|
+
_reloading.value = false;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Imperatively trigger a page reload.
|
|
487
|
+
*
|
|
488
|
+
* - `name`: route name to reload. If provided, the cached keep-alive instance
|
|
489
|
+
* is pruned first via `resetRouteCache(name)`. If omitted, only the reload
|
|
490
|
+
* counter is bumped (forces remount but does not prune cache).
|
|
491
|
+
* - `duration`: milliseconds to wait for transition/cleanup. Defaults to 300.
|
|
492
|
+
*/
|
|
493
|
+
async function reloadPage(name, duration = 300) {
|
|
494
|
+
_reloading.value = true;
|
|
495
|
+
try {
|
|
496
|
+
if (name) await resetRouteCache(name, 50);
|
|
497
|
+
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
498
|
+
_reloadCounter.value++;
|
|
499
|
+
} finally {
|
|
500
|
+
_reloading.value = false;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
/** Reactive ref of the reload counter — for advanced use cases. */
|
|
504
|
+
function getReloadCounter() {
|
|
505
|
+
return _reloadCounter;
|
|
506
|
+
}
|
|
507
|
+
/** Whether a reload is currently in progress. */
|
|
508
|
+
function isReloading() {
|
|
509
|
+
return _reloading.value;
|
|
510
|
+
}
|
|
511
|
+
//#endregion
|
|
512
|
+
//#region src/view-transitions.ts
|
|
513
|
+
const _global = globalThis;
|
|
514
|
+
let _typesSupported = null;
|
|
515
|
+
function supportsTransitionTypes() {
|
|
516
|
+
if (_typesSupported !== null) return _typesSupported;
|
|
517
|
+
if (!supportsViewTransitions()) {
|
|
518
|
+
_typesSupported = false;
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
try {
|
|
522
|
+
let calledWithObject = false;
|
|
523
|
+
const doc = _global.document;
|
|
524
|
+
const orig = doc.startViewTransition;
|
|
525
|
+
doc.startViewTransition = function(opts) {
|
|
526
|
+
if (opts && typeof opts === "object" && "update" in opts) calledWithObject = true;
|
|
527
|
+
return {
|
|
528
|
+
finished: Promise.resolve(),
|
|
529
|
+
ready: Promise.resolve(),
|
|
530
|
+
updateCallbackDone: Promise.resolve(),
|
|
531
|
+
skipTransition() {}
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
try {
|
|
535
|
+
doc.startViewTransition({
|
|
536
|
+
update: () => {},
|
|
537
|
+
types: ["test"]
|
|
538
|
+
});
|
|
539
|
+
} catch {}
|
|
540
|
+
doc.startViewTransition = orig;
|
|
541
|
+
_typesSupported = calledWithObject;
|
|
542
|
+
} catch {
|
|
543
|
+
_typesSupported = false;
|
|
544
|
+
}
|
|
545
|
+
return _typesSupported;
|
|
546
|
+
}
|
|
547
|
+
function supportsViewTransitions() {
|
|
548
|
+
if (typeof _global.document === "undefined") return false;
|
|
549
|
+
return typeof _global.document.startViewTransition === "function";
|
|
550
|
+
}
|
|
551
|
+
async function withViewTransition(callback, options = {}) {
|
|
552
|
+
const { enabled = true, types } = options;
|
|
553
|
+
if (!enabled || !supportsViewTransitions()) return callback();
|
|
554
|
+
const doc = _global.document;
|
|
555
|
+
const useTypesApi = types && types.length > 0 && supportsTransitionTypes();
|
|
556
|
+
let result;
|
|
557
|
+
let callbackError;
|
|
558
|
+
let callbackFailed = false;
|
|
559
|
+
const updateCallback = async () => {
|
|
560
|
+
try {
|
|
561
|
+
result = await callback();
|
|
562
|
+
} catch (e) {
|
|
563
|
+
callbackFailed = true;
|
|
564
|
+
callbackError = e;
|
|
565
|
+
throw e;
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
let transition;
|
|
569
|
+
if (useTypesApi) transition = doc.startViewTransition({
|
|
570
|
+
update: updateCallback,
|
|
571
|
+
types
|
|
572
|
+
});
|
|
573
|
+
else transition = doc.startViewTransition(updateCallback);
|
|
574
|
+
try {
|
|
575
|
+
await transition.finished;
|
|
576
|
+
} catch (err) {
|
|
577
|
+
if (callbackFailed) throw callbackError;
|
|
578
|
+
throw err;
|
|
579
|
+
}
|
|
580
|
+
if (callbackFailed) throw callbackError;
|
|
581
|
+
return result;
|
|
582
|
+
}
|
|
583
|
+
function getNavigationType() {
|
|
584
|
+
try {
|
|
585
|
+
const nav = _global.navigation;
|
|
586
|
+
if (nav?.currentEntry && nav?.transitionType) return nav.transitionType;
|
|
587
|
+
} catch {}
|
|
588
|
+
return "push";
|
|
589
|
+
}
|
|
590
|
+
function useViewTransitionState(name) {
|
|
591
|
+
return { style: `view-transition-name: ${name};` };
|
|
592
|
+
}
|
|
593
|
+
//#endregion
|
|
594
|
+
//#region src/app.ts
|
|
595
|
+
const PAGE_KEY = Symbol("ubean-page");
|
|
596
|
+
const TRANSITION_KEY = Symbol("ubean-transition");
|
|
597
|
+
const SSR_KEY = Symbol("ubean-ssr");
|
|
598
|
+
function createLayoutWrapper(resolveLayoutComponent, defaultLayout) {
|
|
599
|
+
const layoutCache = /* @__PURE__ */ new Map();
|
|
600
|
+
const layoutComp = shallowRef(null);
|
|
601
|
+
const currentLayoutName = ref(null);
|
|
602
|
+
async function loadLayout(name) {
|
|
603
|
+
const resolved = name === void 0 ? defaultLayout : name;
|
|
604
|
+
if (resolved === false || resolved == null) {
|
|
605
|
+
layoutComp.value = null;
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
if (layoutCache.has(resolved)) {
|
|
609
|
+
layoutComp.value = layoutCache.get(resolved) || null;
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
const comp = await resolveLayoutComponent(resolved);
|
|
613
|
+
if (comp) {
|
|
614
|
+
const raw = markRaw(comp);
|
|
615
|
+
layoutCache.set(resolved, raw);
|
|
616
|
+
layoutComp.value = raw;
|
|
617
|
+
} else {
|
|
618
|
+
layoutCache.set(resolved, null);
|
|
619
|
+
layoutComp.value = null;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return defineComponent({
|
|
623
|
+
name: "UbeanLayoutView",
|
|
624
|
+
setup() {
|
|
625
|
+
const route = useRoute();
|
|
626
|
+
watchEffect(() => {
|
|
627
|
+
const layoutName = route.meta.layout;
|
|
628
|
+
if (layoutName !== currentLayoutName.value) {
|
|
629
|
+
currentLayoutName.value = layoutName === void 0 ? defaultLayout : layoutName;
|
|
630
|
+
loadLayout(currentLayoutName.value);
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
return () => {
|
|
634
|
+
if (!layoutComp.value) return h(PageView);
|
|
635
|
+
return h(layoutComp.value);
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* PageView — a globally-registered component that renders the matched route
|
|
642
|
+
* page, wrapped with `<Transition>` and `<KeepAlive>`.
|
|
643
|
+
*
|
|
644
|
+
* Layouts use `<PageView />` (instead of `<slot />`) to render the matched
|
|
645
|
+
* page. This follows vue-router's v-slot pattern, mirroring soybean-unify's
|
|
646
|
+
* `layouts/modules/layout-content/index.vue`:
|
|
647
|
+
*
|
|
648
|
+
* ```html
|
|
649
|
+
* <RouterView v-slot="{ Component, route }">
|
|
650
|
+
* <Transition :name="pageAnimateMode" mode="out-in">
|
|
651
|
+
* <KeepAlive :include="cachedRoutes" :exclude="excludeCachedRoutes">
|
|
652
|
+
* <component :is="Component" v-if="reloadSignal" :key="tabId" />
|
|
653
|
+
* </KeepAlive>
|
|
654
|
+
* </Transition>
|
|
655
|
+
* </RouterView>
|
|
656
|
+
* ```
|
|
657
|
+
*
|
|
658
|
+
* In ubean, the equivalents are:
|
|
659
|
+
* - `pageAnimateMode` → global `usePageTransition()` ref + `transition` prop + `route.meta.transition`
|
|
660
|
+
* - `cachedRoutes` / `excludeCachedRoutes` → `useCacheViews().cachedViews` / `excludedViews`
|
|
661
|
+
* - `reloadSignal` → `useReloadSignal().counter` (incremented by `reloadPage()`)
|
|
662
|
+
* - `tabId` → `reloadKey` prop + reload counter (forces remount when changed)
|
|
663
|
+
*
|
|
664
|
+
* Props:
|
|
665
|
+
* - `transition`: transition name (string) or `false` to disable.
|
|
666
|
+
* Priority: prop > `route.meta.transition` > global `usePageTransition()`.
|
|
667
|
+
* - `reloadKey`: a reactive key — changing it forces remount (reload).
|
|
668
|
+
* When omitted, falls back to `route.fullPath` + global reload counter.
|
|
669
|
+
* - `mode`: Vue `<Transition>` mode. Defaults to `'out-in'`.
|
|
670
|
+
*
|
|
671
|
+
* On SSR, KeepAlive and Transition are skipped (client-only concepts).
|
|
672
|
+
*/
|
|
673
|
+
const PageView = defineComponent({
|
|
674
|
+
name: "PageView",
|
|
675
|
+
props: {
|
|
676
|
+
transition: {
|
|
677
|
+
type: [String, Boolean],
|
|
678
|
+
default: void 0
|
|
679
|
+
},
|
|
680
|
+
reloadKey: {
|
|
681
|
+
type: [String, Number],
|
|
682
|
+
default: void 0
|
|
683
|
+
},
|
|
684
|
+
mode: {
|
|
685
|
+
type: String,
|
|
686
|
+
default: "out-in"
|
|
687
|
+
}
|
|
688
|
+
},
|
|
689
|
+
setup(props) {
|
|
690
|
+
const { cachedViews, excludedViews } = useCacheViews();
|
|
691
|
+
const globalTransition = usePageTransition();
|
|
692
|
+
const { counter: reloadCounter } = useReloadSignal();
|
|
693
|
+
const ssr = inject(SSR_KEY, false);
|
|
694
|
+
return () => {
|
|
695
|
+
return h(RouterView, null, { default: ({ Component, route }) => {
|
|
696
|
+
if (!Component) return null;
|
|
697
|
+
if (ssr) return Component;
|
|
698
|
+
const comp = Component.type;
|
|
699
|
+
const componentProps = Component.props || {};
|
|
700
|
+
const routeTransition = route.meta?.transition;
|
|
701
|
+
const transitionName = props.transition === false ? void 0 : props.transition || routeTransition || globalTransition.name.value || void 0;
|
|
702
|
+
const pageVNode = h(comp, {
|
|
703
|
+
...componentProps,
|
|
704
|
+
key: props.reloadKey ?? `${route.fullPath}#${reloadCounter.value}`
|
|
705
|
+
});
|
|
706
|
+
const keepAliveProps = { include: cachedViews.value };
|
|
707
|
+
if (excludedViews.value.length > 0) keepAliveProps.exclude = excludedViews.value;
|
|
708
|
+
const keepAliveVNode = h(KeepAlive, keepAliveProps, { default: () => pageVNode });
|
|
709
|
+
if (transitionName) return h(Transition, {
|
|
710
|
+
name: transitionName,
|
|
711
|
+
mode: props.mode
|
|
712
|
+
}, { default: () => keepAliveVNode });
|
|
713
|
+
return keepAliveVNode;
|
|
714
|
+
} });
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
const Link = defineComponent({
|
|
719
|
+
name: "Link",
|
|
720
|
+
props: {
|
|
721
|
+
to: {
|
|
722
|
+
type: [String, Object],
|
|
723
|
+
default: void 0
|
|
724
|
+
},
|
|
725
|
+
href: {
|
|
726
|
+
type: String,
|
|
727
|
+
default: void 0
|
|
728
|
+
},
|
|
729
|
+
replace: {
|
|
730
|
+
type: Boolean,
|
|
731
|
+
default: false
|
|
732
|
+
},
|
|
733
|
+
prefetch: {
|
|
734
|
+
type: Boolean,
|
|
735
|
+
default: false
|
|
736
|
+
},
|
|
737
|
+
activeClass: {
|
|
738
|
+
type: String,
|
|
739
|
+
default: "router-link-active"
|
|
740
|
+
},
|
|
741
|
+
exactActiveClass: {
|
|
742
|
+
type: String,
|
|
743
|
+
default: "router-link-exact-active"
|
|
744
|
+
},
|
|
745
|
+
noActiveClass: {
|
|
746
|
+
type: Boolean,
|
|
747
|
+
default: false
|
|
748
|
+
}
|
|
749
|
+
},
|
|
750
|
+
setup(props, { slots, attrs }) {
|
|
751
|
+
const resolvedTo = computed(() => {
|
|
752
|
+
const path = props.to ?? props.href ?? "";
|
|
753
|
+
if (typeof path === "string" && (path.startsWith("http") || path.startsWith("//") || path.startsWith("#"))) return path;
|
|
754
|
+
return localizePath$1(path);
|
|
755
|
+
});
|
|
756
|
+
const isExternal = computed(() => {
|
|
757
|
+
const path = String(resolvedTo.value);
|
|
758
|
+
return path.startsWith("http") || path.startsWith("//") || path.startsWith("#");
|
|
759
|
+
});
|
|
760
|
+
return () => {
|
|
761
|
+
if (isExternal.value) return h("a", {
|
|
762
|
+
...attrs,
|
|
763
|
+
href: resolvedTo.value,
|
|
764
|
+
target: "_blank",
|
|
765
|
+
rel: "noopener noreferrer"
|
|
766
|
+
}, slots.default ? slots.default() : void 0);
|
|
767
|
+
return h(RouterLink, {
|
|
768
|
+
...attrs,
|
|
769
|
+
to: resolvedTo.value,
|
|
770
|
+
replace: props.replace,
|
|
771
|
+
activeClass: props.noActiveClass ? "" : props.activeClass,
|
|
772
|
+
exactActiveClass: props.noActiveClass ? "" : props.exactActiveClass
|
|
773
|
+
}, slots.default);
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
const Head$1 = Head;
|
|
778
|
+
function createRootComponent(LayoutWrapper, page, transitionOpts, isSSR) {
|
|
779
|
+
return defineComponent({
|
|
780
|
+
name: isSSR ? "UbeanSSRApp" : "UbeanAppRoot",
|
|
781
|
+
setup() {
|
|
782
|
+
provide(PAGE_KEY, page);
|
|
783
|
+
provide(TRANSITION_KEY, transitionOpts);
|
|
784
|
+
provide(SSR_KEY, isSSR);
|
|
785
|
+
return () => h(LayoutWrapper);
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
function createUbeanApp(options) {
|
|
790
|
+
if (!options.head) throw new Error("[ubean] createUbeanApp requires a head instance from @unhead/vue/client");
|
|
791
|
+
const initial = options.initialPage || {
|
|
792
|
+
component: "",
|
|
793
|
+
props: {},
|
|
794
|
+
params: {},
|
|
795
|
+
url: "/"
|
|
796
|
+
};
|
|
797
|
+
const head = options.head;
|
|
798
|
+
const transitionOpts = options.viewTransitions === false ? { enabled: false } : options.viewTransitions === true || options.viewTransitions == null ? { enabled: true } : options.viewTransitions;
|
|
799
|
+
const page = reactive({ ...initial });
|
|
800
|
+
const router = createUbeanRouter({
|
|
801
|
+
routes: options.routes,
|
|
802
|
+
ssr: false,
|
|
803
|
+
setup: options.routerSetup
|
|
804
|
+
});
|
|
805
|
+
const LayoutWrapper = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
|
|
806
|
+
initCachedViewsFromRoutes(options.routes);
|
|
807
|
+
const RootComponent = createRootComponent(LayoutWrapper, page, transitionOpts, false);
|
|
808
|
+
const app = options.hydrate ? createSSRApp(RootComponent) : createApp(RootComponent);
|
|
809
|
+
app.use(head);
|
|
810
|
+
app.use(router);
|
|
811
|
+
app.component("Link", Link);
|
|
812
|
+
app.component("PageView", PageView);
|
|
813
|
+
app.config.globalProperties.$ubean = {
|
|
814
|
+
page,
|
|
815
|
+
head,
|
|
816
|
+
router
|
|
817
|
+
};
|
|
818
|
+
return {
|
|
819
|
+
app,
|
|
820
|
+
router,
|
|
821
|
+
head,
|
|
822
|
+
page
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
function createUbeanSSRApp(initialPage, options) {
|
|
826
|
+
if (!options.head) throw new Error("[ubean] createUbeanSSRApp requires a head instance from @unhead/vue/server");
|
|
827
|
+
const head = options.head;
|
|
828
|
+
const page = reactive({ ...initialPage });
|
|
829
|
+
const router = createUbeanRouter({
|
|
830
|
+
routes: options.routes,
|
|
831
|
+
ssr: true,
|
|
832
|
+
initialUrl: initialPage.url,
|
|
833
|
+
setup: options.routerSetup
|
|
834
|
+
});
|
|
835
|
+
const LayoutWrapper = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
|
|
836
|
+
initCachedViewsFromRoutes(options.routes);
|
|
837
|
+
const app = createSSRApp(createRootComponent(LayoutWrapper, page, { enabled: false }, true));
|
|
838
|
+
app.use(head);
|
|
839
|
+
app.use(router);
|
|
840
|
+
app.component("Link", Link);
|
|
841
|
+
app.component("PageView", PageView);
|
|
842
|
+
app.config.globalProperties.$ubean = {
|
|
843
|
+
page,
|
|
844
|
+
head,
|
|
845
|
+
router
|
|
846
|
+
};
|
|
847
|
+
return {
|
|
848
|
+
app,
|
|
849
|
+
router,
|
|
850
|
+
head
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
function usePage() {
|
|
854
|
+
const route = useRoute();
|
|
855
|
+
const pageData = inject(PAGE_KEY, null);
|
|
856
|
+
return reactive({
|
|
857
|
+
url: computed(() => route.fullPath),
|
|
858
|
+
params: computed(() => route.params),
|
|
859
|
+
query: computed(() => route.query),
|
|
860
|
+
meta: computed(() => route.meta),
|
|
861
|
+
props: computed(() => pageData?.props || {}),
|
|
862
|
+
component: computed(() => route.meta.pageName || pageData?.component || ""),
|
|
863
|
+
errors: computed(() => pageData?.errors || null)
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
function useRouter$1() {
|
|
867
|
+
const router = useRouter();
|
|
868
|
+
return {
|
|
869
|
+
...router,
|
|
870
|
+
push: (url, opts) => opts?.replace ? router.replace(url) : router.push(url),
|
|
871
|
+
replace: (url) => router.replace(url),
|
|
872
|
+
back: () => router.back(),
|
|
873
|
+
forward: () => router.forward(),
|
|
874
|
+
refresh: () => router.go(0),
|
|
875
|
+
get current() {
|
|
876
|
+
return router.currentRoute.value;
|
|
877
|
+
},
|
|
878
|
+
get navigating() {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
function useViewTransition() {
|
|
884
|
+
const opts = inject(TRANSITION_KEY, { enabled: true });
|
|
885
|
+
return {
|
|
886
|
+
enabled: opts.enabled !== false && supportsViewTransitions(),
|
|
887
|
+
supports: supportsViewTransitions(),
|
|
888
|
+
options: opts
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
//#endregion
|
|
892
|
+
export { setI18nConfig$1 as $, initCachedViewsFromRoutes as A, defineLocale$1 as B, disablePageCache as C, getCachedViewNames as D, getCacheEnabled as E, resetRouteCache as F, getI18nConfig$1 as G, detectLocale$1 as H, useCacheViews as I, getLocaleName$1 as J, getLocale$1 as K, createUbeanRouter as L, isCacheEnabled as M, isPageCached as N, getExcludedViewNames as O, isPageExcluded as P, onLocaleChange$1 as Q, addLocale$1 as R, useReloadSignal as S, excludePageCache as T, extractLocaleFromPath$1 as U, detectBrowserLocale$1 as V, getDefaultLocale$1 as W, localizePath$1 as X, getRegisteredLocales$1 as Y, mergeLocale$1 as Z, getReloadCounter as _, createUbeanSSRApp as a, useSwitchLocalePath as at, setPageTransition as b, useSeoMeta as c, getNavigationType as d, setLocale$1 as et, supportsViewTransitions as f, getPageTransitionName as g, clearPageTransition as h, createUbeanApp as i, useLocalePath as it, invalidatePageCache as j, includePageCache as k, useUnheadHead as l, withViewTransition as m, Link as n, t$1 as nt, usePage as o, useViewTransitionState as p, getLocaleDir$1 as q, PageView as r, useI18n$1 as rt, useRouter$1 as s, Head$1 as t, switchLocalePath$1 as tt, useViewTransition as u, isReloading as v, enablePageCache as w, usePageTransition as x, reloadPage as y, clearLocales$1 as z };
|