@kimesh/router-runtime 0.2.23 → 0.2.24
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/{index-9xJk3v3Z.d.mts → index-Bi0AaYQy.d.mts} +200 -8
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +330 -26
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/middleware/plugin.d.mts +1 -1
- package/dist/middleware/plugin.mjs +1 -1
- package/dist/{plugin-BfxCqV0B.mjs → plugin-0r5-meph.mjs} +20 -25
- package/package.json +1 -1
|
@@ -134,6 +134,63 @@ interface FullContext extends KimeshContext {
|
|
|
134
134
|
* Injection key for Kimesh context
|
|
135
135
|
*/
|
|
136
136
|
declare const KIMESH_CONTEXT_KEY: InjectionKey<FullContext>;
|
|
137
|
+
/**
|
|
138
|
+
* Context passed to beforeLoad function
|
|
139
|
+
*/
|
|
140
|
+
interface BeforeLoadContextFull<TParams = Record<string, string>> {
|
|
141
|
+
/** Route params extracted from URL */
|
|
142
|
+
params: TParams;
|
|
143
|
+
/** Validated search/query params */
|
|
144
|
+
search: Record<string, unknown>;
|
|
145
|
+
/** Current app context (built-in + user-defined) */
|
|
146
|
+
context: FullContext;
|
|
147
|
+
/** AbortSignal for cancellation */
|
|
148
|
+
signal: AbortSignal;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Before load function type
|
|
152
|
+
* Used to augment context for child routes
|
|
153
|
+
*/
|
|
154
|
+
type BeforeLoadFn<TParams = Record<string, string>, TReturn extends Record<string, unknown> = Record<string, unknown>> = (ctx: BeforeLoadContextFull<TParams>) => TReturn | Promise<TReturn>;
|
|
155
|
+
/**
|
|
156
|
+
* Pending component configuration for routes
|
|
157
|
+
*/
|
|
158
|
+
interface PendingConfig {
|
|
159
|
+
/**
|
|
160
|
+
* Component to show while route is loading
|
|
161
|
+
* @example
|
|
162
|
+
* pendingComponent: () => import('./DashboardSkeleton.vue')
|
|
163
|
+
*/
|
|
164
|
+
pendingComponent?: () => Promise<{
|
|
165
|
+
default: Component;
|
|
166
|
+
}>;
|
|
167
|
+
/**
|
|
168
|
+
* Milliseconds to wait before showing pending component
|
|
169
|
+
* Prevents flash of loading state for fast loads
|
|
170
|
+
* @default 200
|
|
171
|
+
*/
|
|
172
|
+
pendingMs?: number;
|
|
173
|
+
/**
|
|
174
|
+
* Minimum milliseconds to show pending component once visible
|
|
175
|
+
* Prevents jarring quick flash of loading state
|
|
176
|
+
* @default 500
|
|
177
|
+
*/
|
|
178
|
+
pendingMinMs?: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Context accumulated from parent routes' beforeLoad functions
|
|
182
|
+
* This is merged into FullContext during navigation
|
|
183
|
+
*/
|
|
184
|
+
interface RouteContext {
|
|
185
|
+
/** Marker to identify route-accumulated context */
|
|
186
|
+
__routeContext?: true;
|
|
187
|
+
/** Additional properties from beforeLoad functions */
|
|
188
|
+
[key: string]: unknown;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Augmented context with route-level additions
|
|
192
|
+
*/
|
|
193
|
+
type AugmentedContext<TBeforeLoad extends Record<string, unknown> = Record<string, unknown>> = FullContext & TBeforeLoad;
|
|
137
194
|
/**
|
|
138
195
|
* Param value types for route parameters
|
|
139
196
|
*/
|
|
@@ -223,13 +280,13 @@ interface KimeshApp {
|
|
|
223
280
|
/**
|
|
224
281
|
* Loader context passed to loader functions
|
|
225
282
|
*/
|
|
226
|
-
interface LoaderContext<TParams = Record<string, string>, TSearch = Record<string, unknown
|
|
283
|
+
interface LoaderContext<TParams = Record<string, string>, TSearch = Record<string, unknown>, TRouteContext extends Record<string, unknown> = {}> {
|
|
227
284
|
/** Route params (e.g., { postId: '123' }) */
|
|
228
285
|
params: TParams;
|
|
229
286
|
/** Validated search/query params */
|
|
230
287
|
search: TSearch;
|
|
231
|
-
/** App context (built-in + user-defined) */
|
|
232
|
-
context: FullContext;
|
|
288
|
+
/** App context (built-in + user-defined + route-accumulated) */
|
|
289
|
+
context: FullContext & TRouteContext;
|
|
233
290
|
/** AbortSignal for cancellation */
|
|
234
291
|
signal: AbortSignal;
|
|
235
292
|
}
|
|
@@ -349,7 +406,7 @@ type InlineRouteMiddleware<TParams = Record<string, string>> = (to: RouteLocatio
|
|
|
349
406
|
/**
|
|
350
407
|
* File route options
|
|
351
408
|
*/
|
|
352
|
-
interface FileRouteOptions<TMeta = unknown, TParams = Record<string, string>, TSearch = Record<string, unknown>, TLoaderData = unknown> {
|
|
409
|
+
interface FileRouteOptions<TMeta = unknown, TParams = Record<string, string>, TSearch = Record<string, unknown>, TLoaderData = unknown, TBeforeLoadReturn extends Record<string, unknown> = Record<string, unknown>> extends PendingConfig {
|
|
353
410
|
/** Route meta */
|
|
354
411
|
meta?: TMeta;
|
|
355
412
|
/** Loader function - runs before navigation completes */
|
|
@@ -379,7 +436,7 @@ interface FileRouteOptions<TMeta = unknown, TParams = Record<string, string>, TS
|
|
|
379
436
|
*/
|
|
380
437
|
middleware?: string | InlineRouteMiddleware<TParams> | Array<string | InlineRouteMiddleware<TParams>>;
|
|
381
438
|
/** Before load hook (runs after middleware) */
|
|
382
|
-
beforeLoad?:
|
|
439
|
+
beforeLoad?: BeforeLoadFn<TParams, TBeforeLoadReturn>;
|
|
383
440
|
/**
|
|
384
441
|
* Route-level head configuration
|
|
385
442
|
*
|
|
@@ -447,17 +504,19 @@ interface BeforeLoadContext {
|
|
|
447
504
|
/**
|
|
448
505
|
* Route definition returned by createFileRoute
|
|
449
506
|
*/
|
|
450
|
-
interface RouteDefinition<TPath extends string = string, TMeta = unknown, TParams = Record<string, string>, TSearch = Record<string, unknown>, TLoaderData = unknown> {
|
|
507
|
+
interface RouteDefinition<TPath extends string = string, TMeta = unknown, TParams = Record<string, string>, TSearch = Record<string, unknown>, TLoaderData = unknown> extends PendingConfig {
|
|
451
508
|
path: TPath;
|
|
452
509
|
meta?: TMeta;
|
|
453
510
|
loader?: LoaderFn<TParams, TSearch, TLoaderData>;
|
|
454
511
|
validateSearch?: SearchSchema<TSearch>;
|
|
455
512
|
middleware?: string | InlineRouteMiddleware<TParams> | Array<string | InlineRouteMiddleware<TParams>>;
|
|
456
|
-
beforeLoad?:
|
|
513
|
+
beforeLoad?: BeforeLoadFn<TParams>;
|
|
457
514
|
head?: RouteHeadFn<TParams, TLoaderData> | RouteHeadConfig;
|
|
458
515
|
transition?: boolean | TransitionProps;
|
|
459
516
|
viewTransition?: boolean | 'always';
|
|
460
517
|
keepalive?: boolean | KeepAliveProps;
|
|
518
|
+
/** Internal: marks this as a layout route */
|
|
519
|
+
__isLayout?: boolean;
|
|
461
520
|
}
|
|
462
521
|
declare module 'vue-router' {
|
|
463
522
|
interface RouteMeta {
|
|
@@ -467,6 +526,20 @@ declare module 'vue-router' {
|
|
|
467
526
|
__kimeshError?: unknown;
|
|
468
527
|
/** Source layer name for layer-aware features */
|
|
469
528
|
__kimeshLayer?: string;
|
|
529
|
+
/** Marks this route as a layout */
|
|
530
|
+
__kimeshIsLayout?: boolean;
|
|
531
|
+
/** Has pending component */
|
|
532
|
+
__kimeshHasPending?: boolean;
|
|
533
|
+
/** Pending delay in ms */
|
|
534
|
+
__kimeshPendingMs?: number;
|
|
535
|
+
/** Minimum pending duration in ms */
|
|
536
|
+
__kimeshPendingMinMs?: number;
|
|
537
|
+
/** Has beforeLoad function */
|
|
538
|
+
__kimeshHasBeforeLoad?: boolean;
|
|
539
|
+
/** Has head configuration */
|
|
540
|
+
__kimeshHasHead?: boolean;
|
|
541
|
+
/** Head is a function (vs static) */
|
|
542
|
+
__kimeshHeadIsFunction?: boolean;
|
|
470
543
|
}
|
|
471
544
|
}
|
|
472
545
|
//#endregion
|
|
@@ -646,6 +719,52 @@ declare const queryPlugin: KimeshRuntimePlugin<QueryPluginOptions>;
|
|
|
646
719
|
*/
|
|
647
720
|
declare function getCorePlugins(): KimeshRuntimePlugin<Record<string, unknown>>[];
|
|
648
721
|
//#endregion
|
|
722
|
+
//#region src/plugins/head.d.ts
|
|
723
|
+
/**
|
|
724
|
+
* Head plugin options
|
|
725
|
+
*/
|
|
726
|
+
interface HeadPluginOptions {
|
|
727
|
+
/** Default title when no route title is set */
|
|
728
|
+
defaultTitle?: string;
|
|
729
|
+
/** Global title template (can be overridden by routes) */
|
|
730
|
+
titleTemplate?: string | ((title: string) => string);
|
|
731
|
+
/** Whether to merge layout head with page head */
|
|
732
|
+
mergeLayoutHead?: boolean;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Merge two head configurations
|
|
736
|
+
* Page head takes priority over layout head
|
|
737
|
+
*/
|
|
738
|
+
declare function mergeHeadConfigs(layoutHead: RouteHeadConfig | undefined, pageHead: RouteHeadConfig | undefined): RouteHeadConfig;
|
|
739
|
+
/**
|
|
740
|
+
* Apply title template to title
|
|
741
|
+
*/
|
|
742
|
+
declare function applyTitleTemplate(title: string | undefined, template: string | ((title: string) => string) | undefined, defaultTitle?: string): string;
|
|
743
|
+
/**
|
|
744
|
+
* Collect head configurations from matched routes
|
|
745
|
+
*/
|
|
746
|
+
declare function collectRouteHeads(route: RouteLocationNormalizedLoaded, kimeshApp: KimeshAppContext): RouteHeadConfig[];
|
|
747
|
+
/**
|
|
748
|
+
* Merge all route heads into final config
|
|
749
|
+
*/
|
|
750
|
+
declare function mergeAllRouteHeads(heads: RouteHeadConfig[]): RouteHeadConfig;
|
|
751
|
+
/**
|
|
752
|
+
* Apply head config to document (native DOM)
|
|
753
|
+
*/
|
|
754
|
+
declare function applyHeadConfigNative(config: RouteHeadConfig, options?: HeadPluginOptions): void;
|
|
755
|
+
/**
|
|
756
|
+
* Create the head plugin
|
|
757
|
+
*/
|
|
758
|
+
declare function createHeadPlugin(options?: HeadPluginOptions): {
|
|
759
|
+
install(app: App, {
|
|
760
|
+
router,
|
|
761
|
+
kimeshApp
|
|
762
|
+
}: {
|
|
763
|
+
router: Router;
|
|
764
|
+
kimeshApp: KimeshAppContext;
|
|
765
|
+
}): void;
|
|
766
|
+
};
|
|
767
|
+
//#endregion
|
|
649
768
|
//#region src/components/KmOutlet.d.ts
|
|
650
769
|
/**
|
|
651
770
|
* KmOutlet - Router view wrapper component
|
|
@@ -896,6 +1015,8 @@ declare const KmDeferred: vue13.DefineComponent<vue13.ExtractPropTypes<{
|
|
|
896
1015
|
//#region src/guards/loader-guard.d.ts
|
|
897
1016
|
interface LoaderGuardOptions {
|
|
898
1017
|
onError?: (error: Error, to: RouteLocationNormalized) => void;
|
|
1018
|
+
/** Kimesh app context for storing loader data */
|
|
1019
|
+
appContext?: KimeshAppContext;
|
|
899
1020
|
}
|
|
900
1021
|
/**
|
|
901
1022
|
* Create the loader navigation guard
|
|
@@ -906,6 +1027,7 @@ declare function createLoaderGuard(context: FullContext, options?: LoaderGuardOp
|
|
|
906
1027
|
*/
|
|
907
1028
|
declare function installLoaderGuard(router: Router, context: FullContext, options?: {
|
|
908
1029
|
onError?: (error: Error, to: RouteLocationNormalized) => void;
|
|
1030
|
+
appContext?: KimeshAppContext;
|
|
909
1031
|
}): () => void;
|
|
910
1032
|
//#endregion
|
|
911
1033
|
//#region src/composables/use-search.d.ts
|
|
@@ -1201,6 +1323,76 @@ declare function useNavigationGuard(guard: BeforeNavigationHandler): () => void;
|
|
|
1201
1323
|
*/
|
|
1202
1324
|
declare function useAfterNavigation(callback: AfterNavigationHandler): () => void;
|
|
1203
1325
|
//#endregion
|
|
1326
|
+
//#region src/composables/use-loader-data.d.ts
|
|
1327
|
+
/**
|
|
1328
|
+
* Get loader data for the current route
|
|
1329
|
+
*/
|
|
1330
|
+
declare function useLoaderData<T = unknown>(): ComputedRef<T>;
|
|
1331
|
+
/**
|
|
1332
|
+
* Get loader data from a specific route by path
|
|
1333
|
+
*/
|
|
1334
|
+
declare function useMatchLoaderData<T = unknown>(routePath: string): ComputedRef<T | undefined>;
|
|
1335
|
+
/**
|
|
1336
|
+
* Get loader data from parent layout(s)
|
|
1337
|
+
*/
|
|
1338
|
+
declare function useLayoutData<T = unknown>(): ComputedRef<T | undefined>;
|
|
1339
|
+
/**
|
|
1340
|
+
* Get all loader data from the route hierarchy
|
|
1341
|
+
*/
|
|
1342
|
+
declare function useRouteLoaderData(): ComputedRef<Record<string, unknown>>;
|
|
1343
|
+
//#endregion
|
|
1344
|
+
//#region src/types/layout.d.ts
|
|
1345
|
+
/**
|
|
1346
|
+
* Layout loader data access result
|
|
1347
|
+
*/
|
|
1348
|
+
interface LayoutLoaderData<T = unknown> {
|
|
1349
|
+
/** Loader data from the layout */
|
|
1350
|
+
data: T;
|
|
1351
|
+
/** Whether data is still loading */
|
|
1352
|
+
isLoading: boolean;
|
|
1353
|
+
/** Error if loader failed */
|
|
1354
|
+
error: Error | null;
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Match loader data access options
|
|
1358
|
+
*/
|
|
1359
|
+
interface UseMatchLoaderDataOptions {
|
|
1360
|
+
/**
|
|
1361
|
+
* Route path to get loader data from
|
|
1362
|
+
* @example '/_dashboard' or '/posts'
|
|
1363
|
+
*/
|
|
1364
|
+
routePath: string;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Layout route metadata for internal use
|
|
1368
|
+
*/
|
|
1369
|
+
interface LayoutRouteMeta {
|
|
1370
|
+
/** This route is a layout */
|
|
1371
|
+
__isLayout: true;
|
|
1372
|
+
/** Pending component for this layout */
|
|
1373
|
+
__pendingComponent?: () => Promise<{
|
|
1374
|
+
default: Component;
|
|
1375
|
+
}>;
|
|
1376
|
+
/** Pending delay in ms */
|
|
1377
|
+
__pendingMs?: number;
|
|
1378
|
+
/** Minimum pending duration in ms */
|
|
1379
|
+
__pendingMinMs?: number;
|
|
1380
|
+
/** Context additions from beforeLoad */
|
|
1381
|
+
__contextAdditions?: Record<string, unknown>;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Loader data storage key format
|
|
1385
|
+
*/
|
|
1386
|
+
type LoaderDataKey = `__loaderData:${string}`;
|
|
1387
|
+
/**
|
|
1388
|
+
* Create a loader data storage key
|
|
1389
|
+
*/
|
|
1390
|
+
declare function createLoaderDataKey(routePath: string): LoaderDataKey;
|
|
1391
|
+
/**
|
|
1392
|
+
* Type guard for layout route meta
|
|
1393
|
+
*/
|
|
1394
|
+
declare function isLayoutRouteMeta(meta: unknown): meta is LayoutRouteMeta;
|
|
1395
|
+
//#endregion
|
|
1204
1396
|
//#region src/middleware/types.d.ts
|
|
1205
1397
|
/**
|
|
1206
1398
|
* Navigation redirect configuration
|
|
@@ -1459,4 +1651,4 @@ declare function createMiddlewareExecutor(appContext: KimeshAppContext): {
|
|
|
1459
1651
|
executeChain(middlewares: RouteMiddleware[], context: MiddlewareContext): Promise<void | false | NavigationRedirect>;
|
|
1460
1652
|
};
|
|
1461
1653
|
//#endregion
|
|
1462
|
-
export {
|
|
1654
|
+
export { hasKmState as $, HasParams as $t, NavigateToOptions as A, KimeshRuntimePluginMeta as An, applyPlugins as At, useLayoutData as B, createFileRoute as Bt, KnownMiddleware as C, RoutePath as Cn, mergeAllRouteHeads as Ct, MiddlewareRegistry as D, KimeshRuntimeHooks as Dn, queryPlugin as Dt, MiddlewareOption as E, KimeshAppContext as En, getCorePlugins as Et, LayoutRouteMeta as F, RuntimeConfigPublic as Fn, getPluginMeta as Ft, NavigationErrorContext as G, AugmentedContext as Gt, useMatchLoaderData as H, CreateKimeshAppOptionsExtended as Ht, LoaderDataKey as I, getPluginName as It, useNavigationGuard as J, BeforeLoadFn as Jt, NavigationMiddlewareOptions as K, BeforeLoadContext as Kt, UseMatchLoaderDataOptions as L, isKimeshRuntimePlugin as Lt, RouteMiddleware as M, NavigationAfterHookContext as Mn, KIMESH_PLUGIN_INDICATOR as Mt, TypedRouteMiddleware as N, NavigationErrorHookContext as Nn, defineKimeshRuntimePlugin as Nt, MiddlewareRegistryEntry as O, KimeshRuntimePlugin as On, routerPlugin as Ot, LayoutLoaderData as P, NavigationHookContext as Pn, getPluginHooks as Pt, getKmStateKeys as Q, FullContext as Qt, createLoaderDataKey as R, defineContext as Rt, KimeshMiddlewareNames as S, RouteParamsRaw as Sn, createHeadPlugin as St, MiddlewareDefinition as T, SearchSchema as Tn, QueryPluginOptions as Tt, useRouteLoaderData as U, KIMESH_APP_CONTEXT_KEY as Ut, useLoaderData as V, defineRoute as Vt, NavigationContext as W, createKimeshApp as Wt, STATE_KEY_PREFIX as X, ExtractRouteParams as Xt, useNavigationMiddleware as Y, CreateKimeshAppOptions as Yt, clearKmState as Z, FileRouteOptions as Zt, createMiddlewarePlugin as _, RouteInfoByName as _n, KmOutlet as _t, RouteRecordRaw$1 as a, LoaderContext as an, NavigateOptions as at, defineKimeshMiddleware as b, RouteNames as bn, applyTitleTemplate as bt, onBeforeRouteUpdate as c, ParamValueOneOrMore as cn, useReactiveParams as ct, useRouter$1 as d, PendingConfig as dn, LoaderGuardOptions as dt, InlineMiddlewareContext as en, useState as et, createMiddlewareExecutor as f, RouteContext as fn, createLoaderGuard as ft, MiddlewarePluginOptions as g, RouteHeadFn as gn, KmLinkProps as gt, createMiddlewareContext as h, RouteHeadContext as hn, KmLink as ht, RouteLocationNormalizedLoaded$1 as i, KimeshContext as in, useRuntimeConfig as it, NavigationRedirect as j, KimeshRuntimePluginResult as jn, applyPluginsWithParallel as jt, MiddlewareResult as k, KimeshRuntimePluginDefinition as kn, applyPlugin as kt, useLink as l, ParamValueZeroOrMore as ln, UseSearchReturn as lt, executeMiddlewareChain as m, RouteHeadConfig as mn, KmDeferred as mt, NavigationHookAfter as n, KIMESH_CONTEXT_KEY as nn, useKimeshApp as nt, Router$1 as o, LoaderFn as on, useNavigate as ot, executeMiddleware as p, RouteDefinition as pn, installLoaderGuard as pt, useAfterNavigation as q, BeforeLoadContextFull as qt, RouteLocationNormalized$1 as r, KimeshApp as rn, RuntimeConfig as rt, onBeforeRouteLeave as s, ParamValue as sn, useParams as st, NavigationGuard as t, InlineRouteMiddleware as tn, tryUseKimeshApp as tt, useRoute$1 as u, ParamValueZeroOrOne as un, useSearch as ut, middlewarePlugin as v, RouteLocationRaw as vn, HeadPluginOptions as vt, MiddlewareContext as w, RouteRecordInfo as wn, mergeHeadConfigs as wt, navigateTo as x, RouteParams as xn, collectRouteHeads as xt, abortNavigation as y, RouteNamedMap as yn, applyHeadConfigNative as yt, isLayoutRouteMeta as z, useKimeshContext as zt };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
export { BeforeLoadContext, CreateKimeshAppOptions, CreateKimeshAppOptionsExtended, ExtractRouteParams, FileRouteOptions, FullContext, HasParams, InlineMiddlewareContext, InlineRouteMiddleware, KIMESH_APP_CONTEXT_KEY, KIMESH_CONTEXT_KEY, KIMESH_PLUGIN_INDICATOR, KimeshApp, KimeshAppContext, KimeshContext, KimeshMiddlewareNames, KimeshRuntimeHooks, KimeshRuntimePlugin, KimeshRuntimePluginDefinition, KimeshRuntimePluginMeta, KimeshRuntimePluginResult, KmDeferred, KmLink, KmLinkProps, KmOutlet, KnownMiddleware, LoaderContext, LoaderFn, LoaderGuardOptions, MiddlewareContext, MiddlewareDefinition, MiddlewareOption, MiddlewarePluginOptions, MiddlewareResult, NavigateOptions, NavigateToOptions, NavigationAfterHookContext, NavigationContext, NavigationErrorContext, NavigationErrorHookContext, NavigationGuard, NavigationHookAfter, NavigationHookContext, NavigationMiddlewareOptions, NavigationRedirect, ParamValue, ParamValueOneOrMore, ParamValueZeroOrMore, ParamValueZeroOrOne, QueryPluginOptions, RouteDefinition, RouteHeadConfig, RouteHeadContext, RouteHeadFn, RouteInfoByName, RouteLocationNormalized, RouteLocationNormalizedLoaded, RouteLocationRaw, RouteMiddleware, RouteNamedMap, RouteNames, RouteParams, RouteParamsRaw, RoutePath, RouteRecordInfo, RouteRecordRaw, Router, RuntimeConfig, RuntimeConfigPublic, STATE_KEY_PREFIX, SearchSchema, TypedRouteMiddleware, UseSearchReturn, abortNavigation, applyPlugin, applyPlugins, applyPluginsWithParallel, clearKmState, createFileRoute, createKimeshApp, createLoaderGuard, createMiddlewareContext, createMiddlewareExecutor, createMiddlewarePlugin, defineContext, defineKimeshMiddleware, defineKimeshRuntimePlugin, defineRoute, getCorePlugins, getKmStateKeys, getPluginHooks, getPluginMeta, getPluginName, hasKmState, installLoaderGuard, isKimeshRuntimePlugin, middlewarePlugin, navigateTo, onBeforeRouteLeave, onBeforeRouteUpdate, queryPlugin, routerPlugin, tryUseKimeshApp, useAfterNavigation, useKimeshApp, useKimeshContext, useLink, useNavigate, useNavigationGuard, useNavigationMiddleware, useParams, useReactiveParams, useRoute, useRouter, useRuntimeConfig, useSearch, useState };
|
|
1
|
+
import { $ as hasKmState, $t as HasParams, A as NavigateToOptions, An as KimeshRuntimePluginMeta, At as applyPlugins, B as useLayoutData, Bt as createFileRoute, C as KnownMiddleware, Cn as RoutePath, Ct as mergeAllRouteHeads, Dn as KimeshRuntimeHooks, Dt as queryPlugin, E as MiddlewareOption, En as KimeshAppContext, Et as getCorePlugins, F as LayoutRouteMeta, Fn as RuntimeConfigPublic, Ft as getPluginMeta, G as NavigationErrorContext, Gt as AugmentedContext, H as useMatchLoaderData, Ht as CreateKimeshAppOptionsExtended, I as LoaderDataKey, It as getPluginName, J as useNavigationGuard, Jt as BeforeLoadFn, K as NavigationMiddlewareOptions, Kt as BeforeLoadContext, L as UseMatchLoaderDataOptions, Lt as isKimeshRuntimePlugin, M as RouteMiddleware, Mn as NavigationAfterHookContext, Mt as KIMESH_PLUGIN_INDICATOR, N as TypedRouteMiddleware, Nn as NavigationErrorHookContext, Nt as defineKimeshRuntimePlugin, On as KimeshRuntimePlugin, Ot as routerPlugin, P as LayoutLoaderData, Pn as NavigationHookContext, Pt as getPluginHooks, Q as getKmStateKeys, Qt as FullContext, R as createLoaderDataKey, Rt as defineContext, S as KimeshMiddlewareNames, Sn as RouteParamsRaw, St as createHeadPlugin, T as MiddlewareDefinition, Tn as SearchSchema, Tt as QueryPluginOptions, U as useRouteLoaderData, Ut as KIMESH_APP_CONTEXT_KEY, V as useLoaderData, Vt as defineRoute, W as NavigationContext, Wt as createKimeshApp, X as STATE_KEY_PREFIX, Xt as ExtractRouteParams, Y as useNavigationMiddleware, Yt as CreateKimeshAppOptions, Z as clearKmState, Zt as FileRouteOptions, _ as createMiddlewarePlugin, _n as RouteInfoByName, _t as KmOutlet, a as RouteRecordRaw, an as LoaderContext, at as NavigateOptions, b as defineKimeshMiddleware, bn as RouteNames, bt as applyTitleTemplate, c as onBeforeRouteUpdate, cn as ParamValueOneOrMore, ct as useReactiveParams, d as useRouter, dn as PendingConfig, dt as LoaderGuardOptions, en as InlineMiddlewareContext, et as useState, f as createMiddlewareExecutor, fn as RouteContext, ft as createLoaderGuard, g as MiddlewarePluginOptions, gn as RouteHeadFn, gt as KmLinkProps, h as createMiddlewareContext, hn as RouteHeadContext, ht as KmLink, i as RouteLocationNormalizedLoaded, in as KimeshContext, it as useRuntimeConfig, j as NavigationRedirect, jn as KimeshRuntimePluginResult, jt as applyPluginsWithParallel, k as MiddlewareResult, kn as KimeshRuntimePluginDefinition, kt as applyPlugin, l as useLink, ln as ParamValueZeroOrMore, lt as UseSearchReturn, mn as RouteHeadConfig, mt as KmDeferred, n as NavigationHookAfter, nn as KIMESH_CONTEXT_KEY, nt as useKimeshApp, o as Router, on as LoaderFn, ot as useNavigate, pn as RouteDefinition, pt as installLoaderGuard, q as useAfterNavigation, qt as BeforeLoadContextFull, r as RouteLocationNormalized, rn as KimeshApp, rt as RuntimeConfig, s as onBeforeRouteLeave, sn as ParamValue, st as useParams, t as NavigationGuard, tn as InlineRouteMiddleware, tt as tryUseKimeshApp, u as useRoute, un as ParamValueZeroOrOne, ut as useSearch, v as middlewarePlugin, vn as RouteLocationRaw, vt as HeadPluginOptions, w as MiddlewareContext, wn as RouteRecordInfo, wt as mergeHeadConfigs, x as navigateTo, xn as RouteParams, xt as collectRouteHeads, y as abortNavigation, yn as RouteNamedMap, yt as applyHeadConfigNative, z as isLayoutRouteMeta, zt as useKimeshContext } from "./index-Bi0AaYQy.mjs";
|
|
2
|
+
export { AugmentedContext, BeforeLoadContext, BeforeLoadContextFull, BeforeLoadFn, CreateKimeshAppOptions, CreateKimeshAppOptionsExtended, ExtractRouteParams, FileRouteOptions, FullContext, HasParams, HeadPluginOptions, InlineMiddlewareContext, InlineRouteMiddleware, KIMESH_APP_CONTEXT_KEY, KIMESH_CONTEXT_KEY, KIMESH_PLUGIN_INDICATOR, KimeshApp, KimeshAppContext, KimeshContext, KimeshMiddlewareNames, KimeshRuntimeHooks, KimeshRuntimePlugin, KimeshRuntimePluginDefinition, KimeshRuntimePluginMeta, KimeshRuntimePluginResult, KmDeferred, KmLink, KmLinkProps, KmOutlet, KnownMiddleware, LayoutLoaderData, LayoutRouteMeta, LoaderContext, LoaderDataKey, LoaderFn, LoaderGuardOptions, MiddlewareContext, MiddlewareDefinition, MiddlewareOption, MiddlewarePluginOptions, MiddlewareResult, NavigateOptions, NavigateToOptions, NavigationAfterHookContext, NavigationContext, NavigationErrorContext, NavigationErrorHookContext, NavigationGuard, NavigationHookAfter, NavigationHookContext, NavigationMiddlewareOptions, NavigationRedirect, ParamValue, ParamValueOneOrMore, ParamValueZeroOrMore, ParamValueZeroOrOne, PendingConfig, QueryPluginOptions, RouteContext, RouteDefinition, RouteHeadConfig, RouteHeadContext, RouteHeadFn, RouteInfoByName, RouteLocationNormalized, RouteLocationNormalizedLoaded, RouteLocationRaw, RouteMiddleware, RouteNamedMap, RouteNames, RouteParams, RouteParamsRaw, RoutePath, RouteRecordInfo, RouteRecordRaw, Router, RuntimeConfig, RuntimeConfigPublic, STATE_KEY_PREFIX, SearchSchema, TypedRouteMiddleware, UseMatchLoaderDataOptions, UseSearchReturn, abortNavigation, applyHeadConfigNative, applyPlugin, applyPlugins, applyPluginsWithParallel, applyTitleTemplate, clearKmState, collectRouteHeads, createFileRoute, createHeadPlugin, createKimeshApp, createLoaderDataKey, createLoaderGuard, createMiddlewareContext, createMiddlewareExecutor, createMiddlewarePlugin, defineContext, defineKimeshMiddleware, defineKimeshRuntimePlugin, defineRoute, getCorePlugins, getKmStateKeys, getPluginHooks, getPluginMeta, getPluginName, hasKmState, installLoaderGuard, isKimeshRuntimePlugin, isLayoutRouteMeta, mergeAllRouteHeads, mergeHeadConfigs, middlewarePlugin, navigateTo, onBeforeRouteLeave, onBeforeRouteUpdate, queryPlugin, routerPlugin, tryUseKimeshApp, useAfterNavigation, useKimeshApp, useKimeshContext, useLayoutData, useLink, useLoaderData, useMatchLoaderData, useNavigate, useNavigationGuard, useNavigationMiddleware, useParams, useReactiveParams, useRoute, useRouteLoaderData, useRouter, useRuntimeConfig, useSearch, useState };
|
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,121 @@
|
|
|
1
|
-
import { a as KIMESH_PLUGIN_INDICATOR, c as getPluginMeta, i as createMiddlewareContext, l as getPluginName, n as middlewarePlugin, o as defineKimeshRuntimePlugin, s as getPluginHooks, t as createMiddlewarePlugin, u as isKimeshRuntimePlugin } from "./plugin-
|
|
1
|
+
import { a as KIMESH_PLUGIN_INDICATOR, c as getPluginMeta, i as createMiddlewareContext, l as getPluginName, n as middlewarePlugin, o as defineKimeshRuntimePlugin, s as getPluginHooks, t as createMiddlewarePlugin, u as isKimeshRuntimePlugin } from "./plugin-0r5-meph.mjs";
|
|
2
2
|
import { a as defineKimeshMiddleware, i as abortNavigation, o as navigateTo, t as createMiddlewareExecutor } from "./middleware-DdlzhfiB.mjs";
|
|
3
3
|
import { KeepAlive, Suspense, Transition, computed, createApp, defineComponent, h, inject, isRef, nextTick, onErrorCaptured, reactive, ref, toRef } from "vue";
|
|
4
4
|
import { RouterLink, RouterView, createRouter, createWebHashHistory, createWebHistory, onBeforeRouteLeave, onBeforeRouteUpdate, useLink, useRoute, useRoute as useRoute$1, useRouter, useRouter as useRouter$1 } from "vue-router";
|
|
5
5
|
import { QueryClient, VueQueryPlugin } from "@tanstack/vue-query";
|
|
6
6
|
import { createHooks } from "hookable";
|
|
7
7
|
|
|
8
|
-
//#region src/
|
|
8
|
+
//#region src/types/layout.ts
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Create a loader data storage key
|
|
11
11
|
*/
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
function createLoaderDataKey(routePath) {
|
|
13
|
+
return `__loaderData:${routePath}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Type guard for layout route meta
|
|
17
|
+
*/
|
|
18
|
+
function isLayoutRouteMeta(meta) {
|
|
19
|
+
return typeof meta === "object" && meta !== null && "__isLayout" in meta;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/composables/use-loader-data.ts
|
|
24
|
+
/**
|
|
25
|
+
* @kimesh/router-runtime - useLoaderData composable
|
|
26
|
+
*
|
|
27
|
+
* Access loader data from the current route or parent layouts.
|
|
28
|
+
*/
|
|
29
|
+
const LOADER_DATA_PREFIX = "__loaderData:";
|
|
30
|
+
function useKimeshAppRequired(composableName) {
|
|
31
|
+
const kimeshApp = inject(KIMESH_APP_CONTEXT_KEY);
|
|
32
|
+
if (!kimeshApp) throw new Error(`[kimesh] ${composableName} must be used within a Kimesh app`);
|
|
33
|
+
return kimeshApp;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get loader data for the current route
|
|
37
|
+
*/
|
|
38
|
+
function useLoaderData() {
|
|
39
|
+
const route = useRoute$1();
|
|
40
|
+
const kimeshApp = useKimeshAppRequired("useLoaderData");
|
|
41
|
+
return computed(() => {
|
|
42
|
+
const key = createLoaderDataKey(route.path);
|
|
43
|
+
return kimeshApp._state[key];
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get loader data from a specific route by path
|
|
48
|
+
*/
|
|
49
|
+
function useMatchLoaderData(routePath) {
|
|
50
|
+
const kimeshApp = useKimeshAppRequired("useMatchLoaderData");
|
|
51
|
+
return computed(() => {
|
|
52
|
+
const key = createLoaderDataKey(routePath);
|
|
53
|
+
return kimeshApp._state[key];
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get loader data from parent layout(s)
|
|
58
|
+
*/
|
|
59
|
+
function useLayoutData() {
|
|
60
|
+
const route = useRoute$1();
|
|
61
|
+
const kimeshApp = useKimeshAppRequired("useLayoutData");
|
|
62
|
+
return computed(() => {
|
|
63
|
+
const parentLayout = findParentLayout(route);
|
|
64
|
+
if (!parentLayout) return void 0;
|
|
65
|
+
const key = createLoaderDataKey(parentLayout.path);
|
|
66
|
+
return kimeshApp._state[key];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get all loader data from the route hierarchy
|
|
71
|
+
*/
|
|
72
|
+
function useRouteLoaderData() {
|
|
73
|
+
const route = useRoute$1();
|
|
74
|
+
const kimeshApp = useKimeshAppRequired("useRouteLoaderData");
|
|
75
|
+
return computed(() => {
|
|
76
|
+
const result = {};
|
|
77
|
+
for (const matched of route.matched) {
|
|
78
|
+
const key = createLoaderDataKey(matched.path);
|
|
79
|
+
if (kimeshApp._state[key] !== void 0) result[matched.path] = kimeshApp._state[key];
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find the parent layout route in matched routes
|
|
86
|
+
*/
|
|
87
|
+
function findParentLayout(route) {
|
|
88
|
+
const currentIndex = route.matched.length - 1;
|
|
89
|
+
for (let i = currentIndex - 1; i >= 0; i--) {
|
|
90
|
+
const matched = route.matched[i];
|
|
91
|
+
if (matched.meta?.__kimeshIsLayout) return matched;
|
|
17
92
|
}
|
|
93
|
+
return null;
|
|
18
94
|
}
|
|
19
95
|
/**
|
|
96
|
+
* Store loader data for a route
|
|
97
|
+
* Used internally by loader guard
|
|
98
|
+
*/
|
|
99
|
+
function storeLoaderData(kimeshApp, routePath, data) {
|
|
100
|
+
const key = createLoaderDataKey(routePath);
|
|
101
|
+
kimeshApp._state[key] = data;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Clear loader data for routes not in the new matched routes
|
|
105
|
+
* Used internally during navigation
|
|
106
|
+
*/
|
|
107
|
+
function clearStaleLoaderData(kimeshApp, newMatchedPaths) {
|
|
108
|
+
const keysToDelete = [];
|
|
109
|
+
for (const key of Object.keys(kimeshApp._state)) if (key.startsWith(LOADER_DATA_PREFIX)) {
|
|
110
|
+
const routePath = key.slice(13);
|
|
111
|
+
if (!newMatchedPaths.has(routePath)) keysToDelete.push(key);
|
|
112
|
+
}
|
|
113
|
+
for (const key of keysToDelete) delete kimeshApp._state[key];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/guards/loader-guard.ts
|
|
118
|
+
/**
|
|
20
119
|
* Validate search params using the provided schema
|
|
21
120
|
*/
|
|
22
121
|
function validateSearchParams(query, schema) {
|
|
@@ -24,12 +123,16 @@ function validateSearchParams(query, schema) {
|
|
|
24
123
|
if (schema.safeParse) {
|
|
25
124
|
const result = schema.safeParse(query);
|
|
26
125
|
if (result.success && result.data !== void 0) return result.data;
|
|
27
|
-
return safeParse(schema, {});
|
|
28
126
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
127
|
+
try {
|
|
128
|
+
return schema.parse(query);
|
|
129
|
+
} catch {
|
|
130
|
+
try {
|
|
131
|
+
return schema.parse({});
|
|
132
|
+
} catch {
|
|
133
|
+
return query;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
33
136
|
}
|
|
34
137
|
/**
|
|
35
138
|
* Collect loaders from matched route records
|
|
@@ -40,12 +143,28 @@ function collectLoaders(to) {
|
|
|
40
143
|
const routeDef = record.meta?.__kimesh;
|
|
41
144
|
if (routeDef?.loader) loaders.push({
|
|
42
145
|
loader: routeDef.loader,
|
|
43
|
-
routeDef
|
|
146
|
+
routeDef,
|
|
147
|
+
routeRecord: record
|
|
44
148
|
});
|
|
45
149
|
}
|
|
46
150
|
return loaders;
|
|
47
151
|
}
|
|
48
152
|
/**
|
|
153
|
+
* Collect beforeLoad functions from matched route records (in order)
|
|
154
|
+
*/
|
|
155
|
+
function collectBeforeLoads(to) {
|
|
156
|
+
const beforeLoads = [];
|
|
157
|
+
for (const record of to.matched) {
|
|
158
|
+
const routeDef = record.meta?.__kimesh;
|
|
159
|
+
if (routeDef?.beforeLoad) beforeLoads.push({
|
|
160
|
+
beforeLoad: routeDef.beforeLoad,
|
|
161
|
+
routeDef,
|
|
162
|
+
routeRecord: record
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return beforeLoads;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
49
168
|
* Check if error is an AbortError
|
|
50
169
|
*/
|
|
51
170
|
function isAbortError(error) {
|
|
@@ -55,20 +174,45 @@ function isAbortError(error) {
|
|
|
55
174
|
* Create the loader navigation guard
|
|
56
175
|
*/
|
|
57
176
|
function createLoaderGuard(context, options = {}) {
|
|
58
|
-
const { onError } = options;
|
|
177
|
+
const { onError, appContext } = options;
|
|
59
178
|
return async function loaderGuard(to, _from, abortController) {
|
|
179
|
+
const beforeLoads = collectBeforeLoads(to);
|
|
60
180
|
const loaders = collectLoaders(to);
|
|
61
|
-
if (
|
|
62
|
-
|
|
181
|
+
if (appContext) clearStaleLoaderData(appContext, new Set(to.matched.map((r) => r.path)));
|
|
182
|
+
if (beforeLoads.length === 0 && loaders.length === 0) return;
|
|
183
|
+
let accumulatedContext = { ...context };
|
|
184
|
+
for (const { beforeLoad, routeDef } of beforeLoads) {
|
|
185
|
+
const search = validateSearchParams(to.query, routeDef.validateSearch);
|
|
186
|
+
try {
|
|
187
|
+
const result = await beforeLoad({
|
|
188
|
+
params: to.params,
|
|
189
|
+
search,
|
|
190
|
+
context: accumulatedContext,
|
|
191
|
+
signal: abortController.signal
|
|
192
|
+
});
|
|
193
|
+
if (result && typeof result === "object") accumulatedContext = {
|
|
194
|
+
...accumulatedContext,
|
|
195
|
+
...result
|
|
196
|
+
};
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (isAbortError(error)) throw error;
|
|
199
|
+
console.error("[kimesh] beforeLoad error:", error);
|
|
200
|
+
onError?.(error, to);
|
|
201
|
+
to.meta.__kimeshError = error;
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
await Promise.all(loaders.map(async ({ loader, routeDef, routeRecord }) => {
|
|
63
206
|
const search = validateSearchParams(to.query, routeDef.validateSearch);
|
|
64
207
|
const loaderContext = {
|
|
65
208
|
params: to.params,
|
|
66
209
|
search,
|
|
67
|
-
context,
|
|
210
|
+
context: accumulatedContext,
|
|
68
211
|
signal: abortController.signal
|
|
69
212
|
};
|
|
70
213
|
try {
|
|
71
|
-
await loader(loaderContext);
|
|
214
|
+
const data = await loader(loaderContext);
|
|
215
|
+
if (appContext && data !== void 0) storeLoaderData(appContext, routeRecord.path, data);
|
|
72
216
|
} catch (error) {
|
|
73
217
|
if (isAbortError(error)) throw error;
|
|
74
218
|
console.error("[kimesh] Loader error:", error);
|
|
@@ -89,7 +233,10 @@ function installLoaderGuard(router, context, options) {
|
|
|
89
233
|
});
|
|
90
234
|
const removeBeforeResolve = router.beforeResolve(async (to, from) => {
|
|
91
235
|
if (!abortController) abortController = new AbortController();
|
|
92
|
-
const guard = createLoaderGuard(context, {
|
|
236
|
+
const guard = createLoaderGuard(context, {
|
|
237
|
+
onError: options?.onError,
|
|
238
|
+
appContext: options?.appContext
|
|
239
|
+
});
|
|
93
240
|
try {
|
|
94
241
|
await guard(to, from, abortController);
|
|
95
242
|
} catch (error) {
|
|
@@ -247,7 +394,6 @@ async function createKimeshApp(options) {
|
|
|
247
394
|
routes,
|
|
248
395
|
scrollBehavior
|
|
249
396
|
});
|
|
250
|
-
const removeLoaderGuard = installLoaderGuard(router, fullContext, { onError: (error, to) => console.error(`[Kimesh] Loader error for ${to.path}:`, error) });
|
|
251
397
|
const vueApp = createApp({ render: () => h(rootComponent) });
|
|
252
398
|
const hooks = createHooks();
|
|
253
399
|
const appContext = {
|
|
@@ -271,6 +417,10 @@ async function createKimeshApp(options) {
|
|
|
271
417
|
return vueApp.runWithContext(fn);
|
|
272
418
|
}
|
|
273
419
|
};
|
|
420
|
+
const removeLoaderGuard = installLoaderGuard(router, fullContext, {
|
|
421
|
+
onError: (error, to) => console.error(`[Kimesh] Loader error for ${to.path}:`, error),
|
|
422
|
+
appContext
|
|
423
|
+
});
|
|
274
424
|
if (plugins.length > 0) await applyPlugins(appContext, plugins);
|
|
275
425
|
await hooks.callHook("app:created", vueApp);
|
|
276
426
|
vueApp.provide(KIMESH_CONTEXT_KEY, fullContext);
|
|
@@ -589,11 +739,161 @@ const viewTransitionsPlugin = defineKimeshRuntimePlugin({
|
|
|
589
739
|
});
|
|
590
740
|
|
|
591
741
|
//#endregion
|
|
592
|
-
//#region src/
|
|
742
|
+
//#region src/plugins/head.ts
|
|
743
|
+
/**
|
|
744
|
+
* Merge two head configurations
|
|
745
|
+
* Page head takes priority over layout head
|
|
746
|
+
*/
|
|
747
|
+
function mergeHeadConfigs(layoutHead, pageHead) {
|
|
748
|
+
if (!layoutHead && !pageHead) return {};
|
|
749
|
+
if (!layoutHead) return pageHead;
|
|
750
|
+
if (!pageHead) return layoutHead;
|
|
751
|
+
return {
|
|
752
|
+
title: pageHead.title ?? layoutHead.title,
|
|
753
|
+
titleTemplate: pageHead.titleTemplate ?? layoutHead.titleTemplate,
|
|
754
|
+
meta: mergeMetaTags(layoutHead.meta, pageHead.meta),
|
|
755
|
+
link: mergeLinkTags(layoutHead.link, pageHead.link),
|
|
756
|
+
script: [...layoutHead.script || [], ...pageHead.script || []],
|
|
757
|
+
style: [...layoutHead.style || [], ...pageHead.style || []],
|
|
758
|
+
htmlAttrs: {
|
|
759
|
+
...layoutHead.htmlAttrs,
|
|
760
|
+
...pageHead.htmlAttrs
|
|
761
|
+
},
|
|
762
|
+
bodyAttrs: {
|
|
763
|
+
...layoutHead.bodyAttrs,
|
|
764
|
+
...pageHead.bodyAttrs
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Generic tag merger with deduplication
|
|
770
|
+
*/
|
|
771
|
+
function mergeTagsWithDedup(layoutTags, pageTags, getKey) {
|
|
772
|
+
if (!layoutTags && !pageTags) return void 0;
|
|
773
|
+
if (!layoutTags) return pageTags;
|
|
774
|
+
if (!pageTags) return layoutTags;
|
|
775
|
+
const tagMap = /* @__PURE__ */ new Map();
|
|
776
|
+
for (const tag of layoutTags) tagMap.set(getKey(tag), tag);
|
|
777
|
+
for (const tag of pageTags) tagMap.set(getKey(tag), tag);
|
|
778
|
+
return Array.from(tagMap.values());
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Merge meta tags with deduplication
|
|
782
|
+
*/
|
|
783
|
+
function mergeMetaTags(layoutMeta, pageMeta) {
|
|
784
|
+
return mergeTagsWithDedup(layoutMeta, pageMeta, getMetaKey);
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Get unique key for a meta tag
|
|
788
|
+
*/
|
|
789
|
+
function getMetaKey(tag) {
|
|
790
|
+
if (tag.name) return `name:${tag.name}`;
|
|
791
|
+
if (tag.property) return `property:${tag.property}`;
|
|
792
|
+
if (tag.charset) return "charset";
|
|
793
|
+
if (tag["http-equiv"]) return `http-equiv:${tag["http-equiv"]}`;
|
|
794
|
+
return JSON.stringify(tag);
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Merge link tags with deduplication
|
|
798
|
+
*/
|
|
799
|
+
function mergeLinkTags(layoutLink, pageLink) {
|
|
800
|
+
return mergeTagsWithDedup(layoutLink, pageLink, getLinkKey);
|
|
801
|
+
}
|
|
593
802
|
/**
|
|
594
|
-
*
|
|
803
|
+
* Get unique key for a link tag
|
|
595
804
|
*/
|
|
596
|
-
|
|
805
|
+
function getLinkKey(tag) {
|
|
806
|
+
if (tag.rel === "canonical") return "canonical";
|
|
807
|
+
if (tag.rel === "icon" && tag.sizes) return `icon:${tag.sizes}`;
|
|
808
|
+
if (tag.hreflang) return `alternate:${tag.hreflang}`;
|
|
809
|
+
return `${tag.rel}:${tag.href}`;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Apply title template to title
|
|
813
|
+
*/
|
|
814
|
+
function applyTitleTemplate(title, template, defaultTitle) {
|
|
815
|
+
const resolvedTitle = title ?? defaultTitle ?? "";
|
|
816
|
+
if (!template) return resolvedTitle;
|
|
817
|
+
if (typeof template === "function") return template(resolvedTitle);
|
|
818
|
+
return template.replace(/%s/g, resolvedTitle);
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Collect head configurations from matched routes
|
|
822
|
+
*/
|
|
823
|
+
function collectRouteHeads(route, kimeshApp) {
|
|
824
|
+
const heads = [];
|
|
825
|
+
for (const matched of route.matched) {
|
|
826
|
+
const routeDef = matched.meta?.__kimesh;
|
|
827
|
+
if (!routeDef?.head) continue;
|
|
828
|
+
const loaderDataKey = createLoaderDataKey(matched.path);
|
|
829
|
+
const loaderData = kimeshApp._state[loaderDataKey];
|
|
830
|
+
const headContext = {
|
|
831
|
+
params: route.params,
|
|
832
|
+
loaderData,
|
|
833
|
+
route
|
|
834
|
+
};
|
|
835
|
+
let headConfig;
|
|
836
|
+
if (typeof routeDef.head === "function") headConfig = routeDef.head(headContext);
|
|
837
|
+
else headConfig = routeDef.head;
|
|
838
|
+
heads.push(headConfig);
|
|
839
|
+
}
|
|
840
|
+
return heads;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Merge all route heads into final config
|
|
844
|
+
*/
|
|
845
|
+
function mergeAllRouteHeads(heads) {
|
|
846
|
+
if (heads.length === 0) return {};
|
|
847
|
+
if (heads.length === 1) return heads[0];
|
|
848
|
+
return heads.reduce((merged, current) => mergeHeadConfigs(merged, current), {});
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Apply head config to document (native DOM)
|
|
852
|
+
*/
|
|
853
|
+
function applyHeadConfigNative(config, options = {}) {
|
|
854
|
+
const finalTitle = applyTitleTemplate(config.title, config.titleTemplate ?? options.titleTemplate, options.defaultTitle);
|
|
855
|
+
if (finalTitle) document.title = finalTitle;
|
|
856
|
+
if (config.meta) for (const meta of config.meta) updateMetaTag(meta);
|
|
857
|
+
if (config.htmlAttrs) {
|
|
858
|
+
for (const [key, value] of Object.entries(config.htmlAttrs)) if (value !== void 0) document.documentElement.setAttribute(key, value);
|
|
859
|
+
}
|
|
860
|
+
if (config.bodyAttrs) {
|
|
861
|
+
for (const [key, value] of Object.entries(config.bodyAttrs)) if (value !== void 0) document.body.setAttribute(key, value);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Update or create a meta tag
|
|
866
|
+
*/
|
|
867
|
+
function updateMetaTag(meta) {
|
|
868
|
+
let selector;
|
|
869
|
+
if (meta.name) selector = `meta[name="${meta.name}"]`;
|
|
870
|
+
else if (meta.property) selector = `meta[property="${meta.property}"]`;
|
|
871
|
+
else if (meta.charset) selector = "meta[charset]";
|
|
872
|
+
else if (meta["http-equiv"]) selector = `meta[http-equiv="${meta["http-equiv"]}"]`;
|
|
873
|
+
else return;
|
|
874
|
+
let element = document.head.querySelector(selector);
|
|
875
|
+
if (!element) {
|
|
876
|
+
element = document.createElement("meta");
|
|
877
|
+
document.head.appendChild(element);
|
|
878
|
+
}
|
|
879
|
+
for (const [key, value] of Object.entries(meta)) if (value !== void 0) element.setAttribute(key, value);
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Create the head plugin
|
|
883
|
+
*/
|
|
884
|
+
function createHeadPlugin(options = {}) {
|
|
885
|
+
return { install(app, { router, kimeshApp }) {
|
|
886
|
+
router.afterEach((to) => {
|
|
887
|
+
applyHeadConfigNative(mergeAllRouteHeads(collectRouteHeads(to, kimeshApp)), options);
|
|
888
|
+
});
|
|
889
|
+
} };
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
//#endregion
|
|
893
|
+
//#region src/components/KmOutlet.ts
|
|
894
|
+
function supportsViewTransitions() {
|
|
895
|
+
return typeof document !== "undefined" && "startViewTransition" in document;
|
|
896
|
+
}
|
|
597
897
|
/**
|
|
598
898
|
* KmOutlet - Router view wrapper component
|
|
599
899
|
* Renders the matched route component with optional transitions and keepalive
|
|
@@ -1138,7 +1438,11 @@ function clearKmState(keys) {
|
|
|
1138
1438
|
const app = tryUseKimeshApp();
|
|
1139
1439
|
if (!app?._state) return;
|
|
1140
1440
|
const allStateKeys = getKmStateKeys();
|
|
1141
|
-
|
|
1441
|
+
let keysToDelete;
|
|
1442
|
+
if (keys === void 0) keysToDelete = allStateKeys;
|
|
1443
|
+
else if (typeof keys === "function") keysToDelete = allStateKeys.filter(keys);
|
|
1444
|
+
else if (Array.isArray(keys)) keysToDelete = keys;
|
|
1445
|
+
else keysToDelete = [keys];
|
|
1142
1446
|
for (const key of keysToDelete) {
|
|
1143
1447
|
const prefixedKey = STATE_KEY_PREFIX + key;
|
|
1144
1448
|
if (prefixedKey in app._state) delete app._state[prefixedKey];
|
|
@@ -1239,4 +1543,4 @@ function useAfterNavigation(callback) {
|
|
|
1239
1543
|
}
|
|
1240
1544
|
|
|
1241
1545
|
//#endregion
|
|
1242
|
-
export { KIMESH_APP_CONTEXT_KEY, KIMESH_CONTEXT_KEY, KIMESH_PLUGIN_INDICATOR, KmDeferred, KmLink, KmOutlet, STATE_KEY_PREFIX, abortNavigation, applyPlugin, applyPlugins, applyPluginsWithParallel, clearKmState, createFileRoute, createKimeshApp, createLoaderGuard, createMiddlewareContext, createMiddlewareExecutor, createMiddlewarePlugin, defineContext, defineKimeshMiddleware, defineKimeshRuntimePlugin, defineRoute, getCorePlugins, getKmStateKeys, getPluginHooks, getPluginMeta, getPluginName, hasKmState, installLoaderGuard, isKimeshRuntimePlugin, middlewarePlugin, navigateTo, onBeforeRouteLeave, onBeforeRouteUpdate, queryPlugin, routerPlugin, tryUseKimeshApp, useAfterNavigation, useKimeshApp, useKimeshContext, useLink, useNavigate, useNavigationGuard, useNavigationMiddleware, useParams, useReactiveParams, useRoute, useRouter, useRuntimeConfig, useSearch, useState };
|
|
1546
|
+
export { KIMESH_APP_CONTEXT_KEY, KIMESH_CONTEXT_KEY, KIMESH_PLUGIN_INDICATOR, KmDeferred, KmLink, KmOutlet, STATE_KEY_PREFIX, abortNavigation, applyHeadConfigNative, applyPlugin, applyPlugins, applyPluginsWithParallel, applyTitleTemplate, clearKmState, collectRouteHeads, createFileRoute, createHeadPlugin, createKimeshApp, createLoaderDataKey, createLoaderGuard, createMiddlewareContext, createMiddlewareExecutor, createMiddlewarePlugin, defineContext, defineKimeshMiddleware, defineKimeshRuntimePlugin, defineRoute, getCorePlugins, getKmStateKeys, getPluginHooks, getPluginMeta, getPluginName, hasKmState, installLoaderGuard, isKimeshRuntimePlugin, isLayoutRouteMeta, mergeAllRouteHeads, mergeHeadConfigs, middlewarePlugin, navigateTo, onBeforeRouteLeave, onBeforeRouteUpdate, queryPlugin, routerPlugin, tryUseKimeshApp, useAfterNavigation, useKimeshApp, useKimeshContext, useLayoutData, useLink, useLoaderData, useMatchLoaderData, useNavigate, useNavigationGuard, useNavigationMiddleware, useParams, useReactiveParams, useRoute, useRouteLoaderData, useRouter, useRuntimeConfig, useSearch, useState };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as NavigateToOptions, C as KnownMiddleware, D as MiddlewareRegistry, E as MiddlewareOption, M as RouteMiddleware, N as TypedRouteMiddleware, O as MiddlewareRegistryEntry, S as KimeshMiddlewareNames, T as MiddlewareDefinition, _ as createMiddlewarePlugin, b as defineKimeshMiddleware, f as createMiddlewareExecutor, g as MiddlewarePluginOptions, h as createMiddlewareContext, j as NavigationRedirect, k as MiddlewareResult, m as executeMiddlewareChain, p as executeMiddleware, v as middlewarePlugin, w as MiddlewareContext, x as navigateTo, y as abortNavigation } from "../index-
|
|
1
|
+
import { A as NavigateToOptions, C as KnownMiddleware, D as MiddlewareRegistry, E as MiddlewareOption, M as RouteMiddleware, N as TypedRouteMiddleware, O as MiddlewareRegistryEntry, S as KimeshMiddlewareNames, T as MiddlewareDefinition, _ as createMiddlewarePlugin, b as defineKimeshMiddleware, f as createMiddlewareExecutor, g as MiddlewarePluginOptions, h as createMiddlewareContext, j as NavigationRedirect, k as MiddlewareResult, m as executeMiddlewareChain, p as executeMiddleware, v as middlewarePlugin, w as MiddlewareContext, x as navigateTo, y as abortNavigation } from "../index-Bi0AaYQy.mjs";
|
|
2
2
|
export { KimeshMiddlewareNames, KnownMiddleware, MiddlewareContext, MiddlewareDefinition, MiddlewareOption, MiddlewarePluginOptions, MiddlewareRegistry, MiddlewareRegistryEntry, MiddlewareResult, NavigateToOptions, NavigationRedirect, RouteMiddleware, TypedRouteMiddleware, abortNavigation, createMiddlewareContext, createMiddlewareExecutor, createMiddlewarePlugin, defineKimeshMiddleware, executeMiddleware, executeMiddlewareChain, middlewarePlugin, navigateTo };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as createMiddlewareContext, n as middlewarePlugin, t as createMiddlewarePlugin } from "../plugin-
|
|
1
|
+
import { i as createMiddlewareContext, n as middlewarePlugin, t as createMiddlewarePlugin } from "../plugin-0r5-meph.mjs";
|
|
2
2
|
import { a as defineKimeshMiddleware, i as abortNavigation, n as executeMiddleware, o as navigateTo, r as executeMiddlewareChain, t as createMiddlewareExecutor } from "../middleware-DdlzhfiB.mjs";
|
|
3
3
|
|
|
4
4
|
export { abortNavigation, createMiddlewareContext, createMiddlewareExecutor, createMiddlewarePlugin, defineKimeshMiddleware, executeMiddleware, executeMiddlewareChain, middlewarePlugin, navigateTo };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as createMiddlewarePlugin, g as MiddlewarePluginOptions, v as middlewarePlugin } from "../index-
|
|
1
|
+
import { _ as createMiddlewarePlugin, g as MiddlewarePluginOptions, v as middlewarePlugin } from "../index-Bi0AaYQy.mjs";
|
|
2
2
|
export { MiddlewarePluginOptions, createMiddlewarePlugin, middlewarePlugin as default, middlewarePlugin };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as middlewarePlugin, r as plugin_default, t as createMiddlewarePlugin } from "../plugin-
|
|
1
|
+
import { n as middlewarePlugin, r as plugin_default, t as createMiddlewarePlugin } from "../plugin-0r5-meph.mjs";
|
|
2
2
|
|
|
3
3
|
export { createMiddlewarePlugin, plugin_default as default, middlewarePlugin };
|
|
@@ -171,36 +171,31 @@ async function extractRouteMiddleware(route, namedMiddleware) {
|
|
|
171
171
|
return normalizeMiddleware(middlewareOption, namedMiddleware);
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
|
+
* Load named middleware by name
|
|
175
|
+
*/
|
|
176
|
+
async function loadNamedMiddleware(name, namedMiddleware) {
|
|
177
|
+
const loader = namedMiddleware[name];
|
|
178
|
+
if (!loader) {
|
|
179
|
+
if (__KIMESH_DEV__) console.warn(`[Kimesh] Unknown middleware: ${name}`);
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
return loader();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
174
185
|
* Normalize middleware to array of functions
|
|
175
186
|
*/
|
|
176
187
|
async function normalizeMiddleware(middleware, namedMiddleware) {
|
|
177
|
-
const result = [];
|
|
178
188
|
if (typeof middleware === "string") {
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
if (__KIMESH_DEV__) console.warn(`[Kimesh] Unknown middleware: ${middleware}`);
|
|
182
|
-
return [];
|
|
183
|
-
}
|
|
184
|
-
const mw = await loader();
|
|
185
|
-
result.push(mw);
|
|
186
|
-
return result;
|
|
187
|
-
}
|
|
188
|
-
if (typeof middleware === "function") {
|
|
189
|
-
result.push(middleware);
|
|
190
|
-
return result;
|
|
191
|
-
}
|
|
192
|
-
if (Array.isArray(middleware)) {
|
|
193
|
-
for (const item of middleware) if (typeof item === "string") {
|
|
194
|
-
const loader = namedMiddleware[item];
|
|
195
|
-
if (!loader) {
|
|
196
|
-
if (__KIMESH_DEV__) console.warn(`[Kimesh] Unknown middleware: ${item}`);
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
const mw = await loader();
|
|
200
|
-
result.push(mw);
|
|
201
|
-
} else if (typeof item === "function") result.push(item);
|
|
202
|
-
return result;
|
|
189
|
+
const mw = await loadNamedMiddleware(middleware, namedMiddleware);
|
|
190
|
+
return mw ? [mw] : [];
|
|
203
191
|
}
|
|
192
|
+
if (typeof middleware === "function") return [middleware];
|
|
193
|
+
if (!Array.isArray(middleware)) return [];
|
|
194
|
+
const result = [];
|
|
195
|
+
for (const item of middleware) if (typeof item === "string") {
|
|
196
|
+
const mw = await loadNamedMiddleware(item, namedMiddleware);
|
|
197
|
+
if (mw) result.push(mw);
|
|
198
|
+
} else if (typeof item === "function") result.push(item);
|
|
204
199
|
return result;
|
|
205
200
|
}
|
|
206
201
|
var plugin_default = middlewarePlugin;
|