@real-router/vue 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -122,6 +122,8 @@ Route state composables return `ShallowRef` values. Read `.value` in script, or
122
122
  | `useRouteNode(name)` | `{ navigator, route: ShallowRef, previousRoute: ShallowRef }` | Only when node activates/deactivates |
123
123
  | `useRouteUtils()` | `RouteUtils` | Never |
124
124
  | `useRouterTransition()` | `ShallowRef<RouterTransitionSnapshot>` | On transition start/end |
125
+ | `useRouteExit(handler, options?)` | `void` — wraps `subscribeLeave` with abort + same-route guards | Never (handler captured in `setup()`) |
126
+ | `useRouteEnter(handler, options?)` | `void` — fires once on nav-driven mount via `watch(route)` + `transition.from` | Never (handler captured in `setup()`) |
125
127
 
126
128
  ```typescript
127
129
  // useRouteNode — updates only when "users.*" changes
@@ -163,8 +165,44 @@ const GlobalProgress = defineComponent({
163
165
  : null;
164
166
  },
165
167
  });
168
+
169
+ // useRouteExit — exit animations, draft autosave, AbortSignal-aware cleanup
170
+ const FadeOut = defineComponent({
171
+ setup() {
172
+ const box = useTemplateRef<HTMLDivElement>("box");
173
+ useRouteExit(async ({ signal }) => {
174
+ const el = box.value;
175
+ if (!el) return;
176
+ el.classList.add("fade-out");
177
+ const cleanup = () => el.classList.remove("fade-out");
178
+ signal.addEventListener("abort", cleanup, { once: true });
179
+ el.getBoundingClientRect(); // style flush
180
+ await Promise.allSettled(el.getAnimations().map((a) => a.finished));
181
+ cleanup();
182
+ });
183
+ return () => h("div", { ref: "box" });
184
+ },
185
+ });
186
+
187
+ // useRouteEnter — page-enter analytics, focus management, entry animations
188
+ const PageEnterAnalytics = defineComponent({
189
+ setup() {
190
+ useRouteEnter(({ route, previousRoute }) => {
191
+ analytics.track("page_enter", {
192
+ route: route.name,
193
+ from: previousRoute.name,
194
+ });
195
+ });
196
+ return () => null;
197
+ },
198
+ });
166
199
  ```
167
200
 
201
+ > **Vue handler-reactivity:** composables run once in `setup()`, so `handler`
202
+ > is captured at hook-call time. To vary behavior over time, read
203
+ > refs/computeds **inside** the handler body. See [CLAUDE.md](./CLAUDE.md) →
204
+ > "useRouteExit / useRouteEnter Handler Is Captured At Init".
205
+
168
206
  ## Components
169
207
 
170
208
  ### `<Link>`
@@ -482,18 +520,40 @@ h(
482
520
 
483
521
  Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"manual"`. Custom containers via `scrollContainer: () => HTMLElement | null`. Prop is reactive — toggling mode at runtime reconfigures the utility (watched by primitive fields, so inline objects with the same fields do not thrash). See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
484
522
 
523
+ ## View Transitions
524
+
525
+ Opt-in animated route transitions via the browser's [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API):
526
+
527
+ ```vue
528
+ <RouterProvider :router="router" :view-transitions="true">
529
+ <!-- Your app -->
530
+ </RouterProvider>
531
+ ```
532
+
533
+ Or via `h()`:
534
+
535
+ ```typescript
536
+ h(
537
+ RouterProvider,
538
+ { router, viewTransitions: true },
539
+ { default: () => [/* Your app */] },
540
+ );
541
+ ```
542
+
543
+ Prop is reactive — toggling `true`/`false` at runtime creates/destroys the utility. No-op on unsupported browsers (Firefox as of 2026-04, SSR). Customization is pure CSS via `::view-transition-*` pseudo-elements and `view-transition-name` for hero morphs. See [View Transitions guide](https://github.com/greydragon888/real-router/wiki/View-Transitions) for patterns.
544
+
485
545
  ## Documentation
486
546
 
487
547
  Full documentation: [Wiki](https://github.com/greydragon888/real-router/wiki)
488
548
 
489
- - [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Link](https://github.com/greydragon888/real-router/wiki/Link) · [Scroll Restoration](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration)
490
- - [useRouter](https://github.com/greydragon888/real-router/wiki/useRouter) · [useRoute](https://github.com/greydragon888/real-router/wiki/useRoute) · [useRouteNode](https://github.com/greydragon888/real-router/wiki/useRouteNode) · [useNavigator](https://github.com/greydragon888/real-router/wiki/useNavigator) · [useRouteUtils](https://github.com/greydragon888/real-router/wiki/useRouteUtils) · [useRouterTransition](https://github.com/greydragon888/real-router/wiki/useRouterTransition)
549
+ - [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Link](https://github.com/greydragon888/real-router/wiki/Link) · [Scroll Restoration](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) · [View Transitions](https://github.com/greydragon888/real-router/wiki/View-Transitions)
550
+ - [useRouter](https://github.com/greydragon888/real-router/wiki/useRouter) · [useRoute](https://github.com/greydragon888/real-router/wiki/useRoute) · [useRouteNode](https://github.com/greydragon888/real-router/wiki/useRouteNode) · [useNavigator](https://github.com/greydragon888/real-router/wiki/useNavigator) · [useRouteUtils](https://github.com/greydragon888/real-router/wiki/useRouteUtils) · [useRouterTransition](https://github.com/greydragon888/real-router/wiki/useRouterTransition) · [useRouteExit](https://github.com/greydragon888/real-router/wiki/useRouteExit) · [useRouteEnter](https://github.com/greydragon888/real-router/wiki/useRouteEnter)
491
551
 
492
552
  ## Examples
493
553
 
494
- 14 runnable examples — each is a standalone Vite app. Run: `cd examples/vue/basic && pnpm dev`
554
+ 14 runnable examples — each is a standalone Vite app. Run: `cd examples/web/vue/basic && pnpm dev`
495
555
 
496
- [basic](../../examples/vue/basic) · [nested-routes](../../examples/vue/nested-routes) · [auth-guards](../../examples/vue/auth-guards) · [data-loading](../../examples/vue/data-loading) · [lazy-loading](../../examples/vue/lazy-loading) · [async-guards](../../examples/vue/async-guards) · [hash-routing](../../examples/vue/hash-routing) · [persistent-params](../../examples/vue/persistent-params) · [error-handling](../../examples/vue/error-handling) · [dynamic-routes](../../examples/vue/dynamic-routes) · [plugin-installation](../../examples/vue/plugin-installation) · [v-link-directive](../../examples/vue/v-link-directive) · [keep-alive](../../examples/vue/keep-alive) · [combined](../../examples/vue/combined)
556
+ [basic](../../examples/web/vue/basic) · [nested-routes](../../examples/web/vue/nested-routes) · [auth-guards](../../examples/web/vue/auth-guards) · [data-loading](../../examples/web/vue/data-loading) · [lazy-loading](../../examples/web/vue/lazy-loading) · [async-guards](../../examples/web/vue/async-guards) · [hash-routing](../../examples/web/vue/hash-routing) · [persistent-params](../../examples/web/vue/persistent-params) · [error-handling](../../examples/web/vue/error-handling) · [dynamic-routes](../../examples/web/vue/dynamic-routes) · [plugin-installation](../../examples/web/vue/plugin-installation) · [v-link-directive](../../examples/web/vue/v-link-directive) · [keep-alive](../../examples/web/vue/keep-alive) · [combined](../../examples/web/vue/combined)
497
557
 
498
558
  ## Related Packages
499
559
 
@@ -15,6 +15,10 @@ interface MatchProps {
15
15
  readonly fallback?: VNode | (() => VNode);
16
16
  readonly keepAlive?: boolean;
17
17
  }
18
+ interface SelfProps {
19
+ /** Fallback content while children are suspended. */
20
+ readonly fallback?: VNode | (() => VNode);
21
+ }
18
22
  type NotFoundProps = Record<string, never>;
19
23
  //#endregion
20
24
  //#region src/components/RouteView/RouteView.d.ts
@@ -105,6 +109,7 @@ declare const RouteView: {
105
109
  keepAlive: boolean;
106
110
  exact: boolean;
107
111
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
112
+ Self: _$vue.FunctionalComponent<SelfProps, {}, any, {}>;
108
113
  NotFound: _$vue.DefineComponent<{}, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
109
114
  };
110
115
  //#endregion
@@ -262,6 +267,164 @@ declare function useRouteNode(nodeName: string): RouteContext;
262
267
  //#region src/composables/useRouterTransition.d.ts
263
268
  declare function useRouterTransition(): ShallowRef<RouterTransitionSnapshot$1>;
264
269
  //#endregion
270
+ //#region src/composables/useRouteExit.d.ts
271
+ interface RouteExitContext {
272
+ /** The route being left. */
273
+ route: State;
274
+ /** The route being navigated to. */
275
+ nextRoute: State;
276
+ /**
277
+ * AbortSignal that fires when this navigation is superseded by a later
278
+ * one (rapid clicks). Already filtered: when the handler runs,
279
+ * `signal.aborted` is guaranteed to be `false`. Use
280
+ * `signal.addEventListener("abort", cleanup, { once: true })` for
281
+ * cleanup that must run on cancellation.
282
+ */
283
+ signal: AbortSignal;
284
+ }
285
+ interface UseRouteExitOptions {
286
+ /**
287
+ * Skip the handler when `route.name === nextRoute.name`
288
+ * (sort/filter/query-only navigations on the same route). Default:
289
+ * `true`.
290
+ */
291
+ skipSameRoute?: boolean;
292
+ }
293
+ type RouteExitHandler = (context: RouteExitContext) => void | Promise<void>;
294
+ /**
295
+ * Subscribe to the router's leave-window with the universal guards baked
296
+ * in. Wraps `router.subscribeLeave` so consumers don't repeat the same
297
+ * boilerplate every time:
298
+ *
299
+ * - **Reentrant abort pre-check**: if `signal.aborted` is already `true`
300
+ * when the handler would run (rapid navigation superseded a slower
301
+ * one), the handler is skipped entirely.
302
+ * - **Same-route skip**: by default, `route.name === nextRoute.name`
303
+ * short-circuits the handler — query-only navigations skip the work.
304
+ * Opt out with `skipSameRoute: false`.
305
+ *
306
+ * Cleanup is bound to the component's effect scope via `onScopeDispose`.
307
+ *
308
+ * If the handler returns a Promise, the router blocks on it. If the
309
+ * Promise resolves, navigation proceeds. If it rejects, the router emits
310
+ * `TRANSITION_CANCELLED`.
311
+ *
312
+ * **Handler reactivity (Vue):** Vue composables run **once** during
313
+ * `setup()`; `handler` is captured in closure at the call site. To vary
314
+ * behavior over time, read refs/computeds inside the handler body — do
315
+ * not rely on swapping the handler reference.
316
+ *
317
+ * @example Animation
318
+ * ```ts
319
+ * const ref = useTemplateRef<HTMLDivElement>("box");
320
+ *
321
+ * useRouteExit(async ({ signal }) => {
322
+ * const el = ref.value;
323
+ * if (!el) return;
324
+ * el.classList.add("fade-out");
325
+ * const cleanup = () => el.classList.remove("fade-out");
326
+ * signal.addEventListener("abort", cleanup, { once: true });
327
+ * try {
328
+ * el.getBoundingClientRect();
329
+ * await Promise.allSettled(el.getAnimations().map((a) => a.finished));
330
+ * } finally {
331
+ * cleanup();
332
+ * }
333
+ * });
334
+ * ```
335
+ *
336
+ * @example Auto-save form draft
337
+ * ```ts
338
+ * useRouteExit(async ({ signal }) => {
339
+ * if (formState.value.dirty) {
340
+ * await api.saveDraft(formState.value, { signal });
341
+ * }
342
+ * });
343
+ * ```
344
+ *
345
+ * @example Reading rich transition metadata via `nextRoute.transition`
346
+ * ```ts
347
+ * useRouteExit(({ route, nextRoute }) => {
348
+ * if (nextRoute.transition.segments.deactivated.includes("products")) {
349
+ * productCache.clear();
350
+ * }
351
+ * if (nextRoute.transition.redirected) return;
352
+ * });
353
+ * ```
354
+ */
355
+ declare function useRouteExit(handler: RouteExitHandler, options?: UseRouteExitOptions): void;
356
+ //#endregion
357
+ //#region src/composables/useRouteEnter.d.ts
358
+ interface RouteEnterContext {
359
+ /** The route that was just activated. */
360
+ route: State;
361
+ /** The route that was active immediately before this navigation. */
362
+ previousRoute: State;
363
+ }
364
+ type RouteEnterHandler = (context: RouteEnterContext) => void;
365
+ interface UseRouteEnterOptions {
366
+ /**
367
+ * Skip the handler when `route.name === previousRoute.name`
368
+ * (sort/filter/query-only navigations on the same route). Default:
369
+ * `true`. Symmetric with `useRouteExit`'s same-name option.
370
+ */
371
+ skipSameRoute?: boolean;
372
+ }
373
+ /**
374
+ * Fire `handler` once when the component mounts as a result of a
375
+ * navigation. Mirror of `useRouteExit` for the entry side.
376
+ *
377
+ * What this composable covers that an ad-hoc `watch` + `useRoute()`
378
+ * doesn't:
379
+ *
380
+ * - **Skip-initial**: `watch` (with default `immediate: false`) plus the
381
+ * explicit `route.transition.from` guard ensures the handler doesn't
382
+ * fire on the very first state committed by `router.start()`.
383
+ * - **Same-route skip** (default): handler is skipped when
384
+ * `route.transition.from === route.name`. Sort/filter/query-only
385
+ * navigations re-trigger the watcher, but they are not "entries" in
386
+ * the animation / analytics sense. Opt out with
387
+ * `skipSameRoute: false`.
388
+ * - **Mount-time `route` / `previousRoute` snapshot**: handler receives
389
+ * the values that were live at the moment of the new state, not the
390
+ * latest ones (which may have moved on if the user navigated again
391
+ * before the watcher drained).
392
+ *
393
+ * **Handler reactivity (Vue):** Vue composables run **once** during
394
+ * `setup()`; `handler` is captured in closure at the call site. To vary
395
+ * behavior over time, read refs/computeds inside the handler body.
396
+ *
397
+ * @example Direction-aware entry animation
398
+ * ```ts
399
+ * useRouteEnter(({ route }) => {
400
+ * const direction = route.context.browser?.direction;
401
+ * ref.value?.classList.add(
402
+ * direction === "back" ? "slide-from-left" : "slide-from-right",
403
+ * );
404
+ * });
405
+ * ```
406
+ *
407
+ * @example Analytics page-enter event (skip-initial built-in)
408
+ * ```ts
409
+ * useRouteEnter(({ route, previousRoute }) => {
410
+ * analytics.track("page_enter", {
411
+ * route: route.name,
412
+ * from: previousRoute.name,
413
+ * });
414
+ * });
415
+ * ```
416
+ *
417
+ * @example Reading rich transition metadata via `route.transition`
418
+ * ```ts
419
+ * useRouteEnter(({ route }) => {
420
+ * if (route.transition.redirected) {
421
+ * showToast(`Redirected from ${route.transition.from}`);
422
+ * }
423
+ * });
424
+ * ```
425
+ */
426
+ declare function useRouteEnter(handler: RouteEnterHandler, options?: UseRouteEnterOptions): void;
427
+ //#endregion
265
428
  //#region src/createRouterPlugin.d.ts
266
429
  declare function createRouterPlugin(router: Router): Plugin<[]>;
267
430
  //#endregion
@@ -286,6 +449,10 @@ declare const RouterProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
286
449
  scrollRestoration: {
287
450
  type: PropType<ScrollRestorationOptions>;
288
451
  };
452
+ viewTransitions: {
453
+ type: BooleanConstructor;
454
+ default: boolean;
455
+ };
289
456
  }>, () => _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
290
457
  [key: string]: any;
291
458
  }>[] | undefined, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
@@ -300,8 +467,13 @@ declare const RouterProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
300
467
  scrollRestoration: {
301
468
  type: PropType<ScrollRestorationOptions>;
302
469
  };
470
+ viewTransitions: {
471
+ type: BooleanConstructor;
472
+ default: boolean;
473
+ };
303
474
  }>> & Readonly<{}>, {
304
475
  announceNavigation: boolean;
476
+ viewTransitions: boolean;
305
477
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
306
478
  //#endregion
307
479
  //#region src/context.d.ts
@@ -309,5 +481,5 @@ declare const RouterKey: InjectionKey<Router>;
309
481
  declare const NavigatorKey: InjectionKey<Navigator$1>;
310
482
  declare const RouteKey: InjectionKey<RouteContext>;
311
483
  //#endregion
312
- export { Link, type LinkDirectiveValue, type LinkProps, type Navigator, NavigatorKey, RouteKey, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterKey, RouterProvider, type RouterTransitionSnapshot, createRouterPlugin, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition, vLink };
484
+ export { Link, type LinkDirectiveValue, type LinkProps, type Navigator, NavigatorKey, type RouteEnterContext, type RouteEnterHandler, type RouteExitContext, type RouteExitHandler, RouteKey, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterKey, RouterProvider, type RouterTransitionSnapshot, type UseRouteEnterOptions, type UseRouteExitOptions, createRouterPlugin, useNavigator, useRoute, useRouteEnter, useRouteExit, useRouteNode, useRouteUtils, useRouter, useRouterTransition, vLink };
313
485
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/components/RouteView/types.ts","../../src/components/RouteView/RouteView.ts","../../src/components/Link.ts","../../src/components/RouterErrorBoundary.ts","../../src/directives/vLink.ts","../../src/composables/useRouter.ts","../../src/composables/useNavigator.ts","../../src/composables/useRouteUtils.ts","../../src/types.ts","../../src/composables/useRoute.ts","../../src/composables/useRouteNode.ts","../../src/composables/useRouterTransition.ts","../../src/createRouterPlugin.ts","../../../../shared/dom-utils/scroll-restore.ts","../../src/RouterProvider.ts","../../src/context.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/components/RouteView/types.ts","../../src/components/RouteView/RouteView.ts","../../src/components/Link.ts","../../src/components/RouterErrorBoundary.ts","../../src/directives/vLink.ts","../../src/composables/useRouter.ts","../../src/composables/useNavigator.ts","../../src/composables/useRouteUtils.ts","../../src/types.ts","../../src/composables/useRoute.ts","../../src/composables/useRouteNode.ts","../../src/composables/useRouterTransition.ts","../../src/composables/useRouteExit.ts","../../src/composables/useRouteEnter.ts","../../src/createRouterPlugin.ts","../../../../shared/dom-utils/scroll-restore.ts","../../src/RouterProvider.ts","../../src/context.ts"],"mappings":"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"}
package/dist/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`vue`),t=require(`@real-router/core`),n=require(`@real-router/route-utils`),r=require(`@real-router/sources`),i=require(`@real-router/core/api`);function a(){return null}const o=(0,e.defineComponent)({name:`RouteView.Match`,props:{segment:{type:String,required:!0},exact:{type:Boolean,default:!1},fallback:{type:[Object,Function],default:void 0},keepAlive:{type:Boolean,default:!1}},render:a}),s=(0,e.defineComponent)({name:`RouteView.NotFound`,render:a});function c(e,t,r){return r?e===t:(0,n.startsWithSegment)(e,t)}function l(t){if(Array.isArray(t)){let n=[];for(let r of t)Array.isArray(r)?n.push(...l(r)):(0,e.isVNode)(r)&&n.push(r);return n}return(0,e.isVNode)(t)?[t]:[]}function u(t,n){let r=l(t);for(let t of r)t.type===o||t.type===s?n.push(t):t.type===e.Fragment&&u(t.children,n)}function d(e,n,r){let i=null,a=!1,o,l=[];for(let t of e){if(t.type===s){i=t.children;continue}let e=t.props,u=e?.segment??``,d=e?.exact??!1,f=r?`${r}.${u}`:u;!a&&c(n,f,d)&&(a=!0,o=e?.fallback,l.push(t))}if(!a&&n===t.UNKNOWN_ROUTE&&i!==null){let t=e.filter(e=>e.type===s).at(-1);t&&l.push(t)}return{rendered:l,activeMatchFound:a,fallback:o}}function f(t){let n=(0,e.shallowRef)(t.getSnapshot());return(0,e.onScopeDispose)(t.subscribe(()=>{n.value=t.getSnapshot()})),n}const p=Symbol(`RouterKey`),m=Symbol(`NavigatorKey`),h=Symbol(`RouteKey`),g=()=>{let t=(0,e.inject)(p);if(!t)throw Error(`useRouter must be used within a RouterProvider`);return t};function _(n){let i=g(),a=f((0,r.createRouteNodeSource)(i,n));return{navigator:(0,t.getNavigator)(i),route:(0,e.computed)(()=>a.value.route),previousRoute:(0,e.computed)(()=>a.value.previousRoute)}}function v(e){return e.children?.default?.()??null}function y(t,n){let r=t.get(n);if(r)return r;let i=(0,e.markRaw)((0,e.defineComponent)({name:`KeepAlive-${n}`,setup(e,t){return()=>t.slots.default?.()}}));return t.set(n,i),i}function b(t,n){if(n===void 0)return t;let r=typeof n==`function`?n():n;return(0,e.h)(e.Suspense,{},{default:()=>t,fallback:()=>r})}const ee=(0,e.markRaw)((0,e.defineComponent)({name:`KeepAlive-placeholder`,render(){return null}}));function x(t,n,r){let i=t.props?.segment??`__not-found__`,a=y(n,i),o=v(t)??[];return b((0,e.h)(e.KeepAlive,null,{default:()=>(0,e.h)(a,{key:i},{default:()=>o})}),r)}function S(e){return e===!0||e===``||e===`keep-alive`}function C(t,n,r){let i=t.props;if(S(i?.keepAlive)&&t.type===o){let r=i?.segment??`__not-found__`,a=y(n,r),o=v(t)??[];return(0,e.h)(e.Fragment,[(0,e.h)(e.KeepAlive,null,{default:()=>(0,e.h)(a,{key:r},{default:()=>o})})])}let a=v(t);return a?(0,e.h)(e.Fragment,[(0,e.h)(e.KeepAlive,null,{default:()=>(0,e.h)(ee)}),b((0,e.h)(e.Fragment,a),r)]):null}const w=(0,e.defineComponent)({name:`RouteView`,props:{nodeName:{type:String,required:!0},keepAlive:{type:Boolean,default:!1}},setup(t,{slots:n}){let r=_(t.nodeName),i=new Map,a=null,c=!1;function l(e,t){return t===a?c:(a=t,c=e.some(e=>e.type===o&&S(e.props?.keepAlive)),c)}return()=>{let a=r.route.value;if(!a)return null;let c=n.default?.(),f=[];u(c,f);let{rendered:p,fallback:m}=d(f,a.name,t.nodeName);if(p.length===0)return null;let h=p[0];if(t.keepAlive)return x(h,i,m);if(h.type!==o&&h.type!==s)return null;if(l(f,c))return C(h,i,m);let g=v(h);return g?b((0,e.h)(e.Fragment,g),m):null}}}),te=Object.assign(w,{Match:o,NotFound:s}),ne=Object.freeze({}),re=Object.freeze({}),T=`data-real-router-announcer`;function E(e,t){let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=D(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),A(t)},f=setTimeout(()=>{if(a=!0,c!==null&&!o){let e=c;c=null,d(e,document.querySelector(`h1`))}},100),p=e.subscribe(({route:e})=>{if(i){i=!1;return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(o)return;let t=document.querySelector(`h1`),i=k(e,n,r,t);if(!(!i||i===s)){if(!a){c=i;return}d(i,t)}})})});return{destroy(){o=!0,p(),clearTimeout(l),clearTimeout(f),O()}}}function D(){let e=document.querySelector(`[${T}]`);if(e)return e;let t=document.createElement(`div`);return t.setAttribute(`style`,`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0`),t.setAttribute(`aria-live`,`assertive`),t.setAttribute(`aria-atomic`,`true`),t.setAttribute(T,``),document.body.prepend(t),t}function O(){document.querySelector(`[${T}]`)?.remove()}function k(e,t,n,r){if(n)return n(e);let i=r?.textContent.trim()??``,a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function A(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const j=`real-router:scroll`,M=Object.freeze({destroy:()=>{}});function ie(e,t){if(globalThis.window===void 0)return M;let n=t?.mode??`restore`;if(n===`manual`)return M;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let o=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},s=e=>{let t=i?.();t?t.scrollTop=e:globalThis.scrollTo(0,e)},c=()=>{let e=globalThis.location.hash;if(r&&e.length>1){let t;try{t=decodeURIComponent(e.slice(1))}catch{t=e.slice(1)}let n=document.getElementById(t);if(n){n.scrollIntoView();return}}s(0)},l=!1,u=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;t&&F(N(t),o()),requestAnimationFrame(()=>{if(!l){if(n===`top`||!r){c();return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){s(P()[N(e)]??0);return}c()}}})}),d=()=>{let t=e.getState();t&&F(N(t),o())};return globalThis.addEventListener(`pagehide`,d),{destroy:()=>{if(!l){l=!0,u(),globalThis.removeEventListener(`pagehide`,d);try{history.scrollRestoration=a}catch{}}}}}function N(e){return`${e.name}:${I(e.params)}`}function P(){try{let e=sessionStorage.getItem(j);return e?JSON.parse(e):{}}catch{return{}}}function F(e,t){try{let n=P();n[e]=t,sessionStorage.setItem(j,JSON.stringify(n))}catch{}}function I(e){return JSON.stringify(e,L)}function L(e,t){if(typeof t==`object`&&t&&!Array.isArray(t)){let e={},n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}function R(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}function z(e,t,n){try{let r=e.buildUrl;if(r){let e=r(t,n);if(e!==void 0)return e}return e.buildPath(t,n)}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function B(e){return e?e.match(/\S+/g)??[]:[]}function V(e,t,n){if(e&&t){let e=B(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=B(n),i=new Set(r);for(let t of e)i.has(t)||(i.add(t),r.push(t));return r.join(` `)}return n??void 0}function H(e){e&&(e instanceof HTMLAnchorElement||e instanceof HTMLButtonElement||(e.hasAttribute(`role`)||e.setAttribute(`role`,`link`),e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`0`)))}function U(e,t){if(typeof e==`function`){e(t);return}if(Array.isArray(e)){let n=e;for(let e of n)if(typeof e==`function`&&(e(t),t.defaultPrevented))return}}const W=(0,e.defineComponent)({name:`Link`,inheritAttrs:!1,props:{routeName:{type:String,required:!0},routeParams:{type:Object,default:()=>ne},routeOptions:{type:Object,default:()=>re},class:{type:String,default:void 0},activeClassName:{type:String,default:`active`},activeStrict:{type:Boolean,default:!1},ignoreQueryParams:{type:Boolean,default:!0},target:{type:String,default:void 0}},setup(t,{slots:n,attrs:i}){let a=g(),o=(0,e.shallowRef)(!1);(0,e.watch)(()=>[t.routeName,t.routeParams,t.activeStrict,t.ignoreQueryParams],([e,t,n,i],s,c)=>{let l=(0,r.createActiveRouteSource)(a,e,t,{strict:n,ignoreQueryParams:i});o.value=l.getSnapshot(),c(l.subscribe(()=>{o.value=l.getSnapshot()}))},{immediate:!0,flush:`sync`});let s=(0,e.computed)(()=>z(a,t.routeName,t.routeParams)),c=(0,e.computed)(()=>V(o.value,t.activeClassName,t.class)),l=e=>{i.onClick!==void 0&&i.onClick!==null&&(U(i.onClick,e),e.defaultPrevented)||!R(e)||t.target===`_blank`||(e.preventDefault(),a.navigate(t.routeName,t.routeParams,t.routeOptions).catch(()=>{}))};return()=>{let r={};for(let e of Object.keys(i))e!==`onClick`&&(r[e]=i[e]);return(0,e.h)(`a`,{...r,href:s.value,class:c.value,target:t.target,onClick:l},n.default?.())}}}),G=(0,e.defineComponent)({name:`RouterErrorBoundary`,props:{fallback:{type:Function,required:!0},onError:{type:Function,default:void 0}},setup(t,{slots:n}){let i=f((0,r.createDismissableError)(g()));return(0,e.watch)(()=>i.value.version,()=>{i.value.error&&t.onError?.(i.value.error,i.value.toRoute,i.value.fromRoute)},{immediate:!0}),()=>{let r=n.default?.()??[],a=i.value.error?t.fallback(i.value.error,i.value.resetError):null;return(0,e.h)(e.Fragment,null,[...r,a])}}}),K=[];function q(e){return K.push(e),()=>{let t=K.lastIndexOf(e);t!==-1&&K.splice(t,1)}}function J(){let e=K.at(-1);if(!e)throw Error(`v-link directive requires a RouterProvider ancestor. Make sure RouterProvider is mounted.`);return e}const Y=new WeakMap;function X(e){return e==null?(console.error(`[real-router] v-link directive received null/undefined value. The element will not be wired for navigation.`),!1):typeof e.name==`string`?!0:(console.error("[real-router] v-link directive value is missing a string `name` field. The element will not be wired for navigation."),!1)}function ae(e,t){return n=>{R(n)&&(n.preventDefault(),e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{}))}}function oe(e,t,n){return r=>{r.key===`Enter`&&!(n instanceof HTMLButtonElement)&&e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{})}}function Z(e,t,n){let r=ae(t,n),i=oe(t,n,e);e.addEventListener(`click`,r),e.addEventListener(`keydown`,i),Y.set(e,{click:r,keydown:i})}function Q(e){let t=Y.get(e);t&&(e.removeEventListener(`click`,t.click),e.removeEventListener(`keydown`,t.keydown),Y.delete(e))}const se={mounted(e,t){let n=J();H(e),e.style.cursor=`pointer`,X(t.value)&&Z(e,n,t.value)},updated(e,t){let n=J();Q(e),X(t.value)&&Z(e,n,t.value)},beforeUnmount(e){Q(e)}},ce=()=>{let t=(0,e.inject)(m);if(!t)throw Error(`useNavigator must be used within a RouterProvider`);return t},le=()=>(0,n.getRouteUtils)((0,i.getPluginApi)(g()).getTree()),ue=()=>{let t=(0,e.inject)(h);if(!t)throw Error(`useRoute must be used within a RouterProvider`);return t};function de(){return f((0,r.getTransitionSource)(g()))}function $(n){let i=(0,t.getNavigator)(n),a=(0,r.createRouteSource)(n),o=a.getSnapshot(),s=(0,e.shallowRef)(o.route),c=(0,e.shallowRef)(o.previousRoute);return{navigator:i,route:s,previousRoute:c,unsubscribe:a.subscribe(()=>{let e=a.getSnapshot();s.value=e.route,c.value=e.previousRoute})}}function fe(e){return{install(t){let n=q(e),{navigator:r,route:i,previousRoute:a,unsubscribe:o}=$(e);`onUnmount`in t&&t.onUnmount(()=>{n(),o()}),t.provide(p,e),t.provide(m,r),t.provide(h,{navigator:r,route:i,previousRoute:a})}}}const pe=(0,e.defineComponent)({name:`RouterProvider`,props:{router:{type:Object,required:!0},announceNavigation:{type:Boolean,default:!1},scrollRestoration:{type:Object}},setup(t,{slots:n}){(0,e.watch)(()=>[t.router,t.announceNavigation],([e,t],n,r)=>{if(!t)return;let i=E(e);r(()=>{i.destroy()})},{immediate:!0}),(0,e.watch)(()=>[t.router,t.scrollRestoration!==void 0,t.scrollRestoration?.mode,t.scrollRestoration?.anchorScrolling],([e,n,r,i],a,o)=>{if(!n)return;let s=ie(e,{mode:r,anchorScrolling:i,scrollContainer:t.scrollRestoration?.scrollContainer});o(()=>{s.destroy()})},{immediate:!0});let r=q(t.router),{navigator:i,route:a,previousRoute:o,unsubscribe:s}=$(t.router);return(0,e.onScopeDispose)(()=>{r(),s()}),(0,e.provide)(p,t.router),(0,e.provide)(m,i),(0,e.provide)(h,{navigator:i,route:a,previousRoute:o}),()=>n.default?.()}});exports.Link=W,exports.NavigatorKey=m,exports.RouteKey=h,exports.RouteView=te,exports.RouterErrorBoundary=G,exports.RouterKey=p,exports.RouterProvider=pe,exports.createRouterPlugin=fe,exports.useNavigator=ce,exports.useRoute=ue,exports.useRouteNode=_,exports.useRouteUtils=le,exports.useRouter=g,exports.useRouterTransition=de,exports.vLink=se;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`vue`),t=require(`@real-router/core`),n=require(`@real-router/route-utils`),r=require(`@real-router/sources`),i=require(`@real-router/core/api`);function a(){return null}const o=(0,e.defineComponent)({name:`RouteView.Match`,props:{segment:{type:String,required:!0},exact:{type:Boolean,default:!1},fallback:{type:[Object,Function],default:void 0},keepAlive:{type:Boolean,default:!1}},render:a}),s=(0,e.defineComponent)({name:`RouteView.Self`,props:{fallback:{type:[Object,Function],default:void 0}},render:a}),c=(0,e.defineComponent)({name:`RouteView.NotFound`,render:a});function l(e,t,r){return r?e===t:(0,n.startsWithSegment)(e,t)}function u(t){if(Array.isArray(t)){let n=[];for(let r of t)Array.isArray(r)?n.push(...u(r)):(0,e.isVNode)(r)&&n.push(r);return n}return(0,e.isVNode)(t)?[t]:[]}function d(t,n){let r=u(t);for(let t of r)t.type===o||t.type===s||t.type===c?n.push(t):t.type===e.Fragment&&d(t.children,n)}function f(e,t){return e.type===c?(t.notFoundChildren=e.children,!0):e.type===s?(t.selfVNode===null&&(t.selfVNode=e,t.selfFallback=e.props?.fallback),!0):!1}function p(e,t,n){let r=e.props,i=r?.segment??``,a=r?.exact??!1;return{isActive:l(t,n?`${n}.${i}`:i,a),fallback:r?.fallback}}function m(e,n,r,i,a){if(i.selfVNode!==null&&n===r)return e.push(i.selfVNode),i.selfFallback;if(n===t.UNKNOWN_ROUTE&&i.notFoundChildren!==null){let t=a.filter(e=>e.type===c).at(-1);t&&e.push(t)}}function h(e,t,n){let r={selfVNode:null,selfFallback:void 0,notFoundChildren:null},i=!1,a,o=[];for(let s of e){if(f(s,r)||i)continue;let e=p(s,t,n);e.isActive&&(i=!0,a=e.fallback,o.push(s))}return i||(a=m(o,t,n,r,e)),{rendered:o,activeMatchFound:i,fallback:a}}function g(t){let n=(0,e.shallowRef)(t.getSnapshot());return(0,e.onScopeDispose)(t.subscribe(()=>{n.value=t.getSnapshot()})),n}const _=Symbol(`RouterKey`),v=Symbol(`NavigatorKey`),y=Symbol(`RouteKey`),b=()=>{let t=(0,e.inject)(_);if(!t)throw Error(`useRouter must be used within a RouterProvider`);return t};function x(n){let i=b(),a=g((0,r.createRouteNodeSource)(i,n));return{navigator:(0,t.getNavigator)(i),route:(0,e.computed)(()=>a.value.route),previousRoute:(0,e.computed)(()=>a.value.previousRoute)}}function S(e){return e.children?.default?.()??null}function C(t,n){let r=t.get(n);if(r)return r;let i=(0,e.markRaw)((0,e.defineComponent)({name:`KeepAlive-${n}`,setup(e,t){return()=>t.slots.default?.()}}));return t.set(n,i),i}function w(t,n){if(n===void 0)return t;let r=typeof n==`function`?n():n;return(0,e.h)(e.Suspense,{},{default:()=>t,fallback:()=>r})}const ee=(0,e.markRaw)((0,e.defineComponent)({name:`KeepAlive-placeholder`,render(){return null}}));function te(t,n,r){let i=t.props?.segment??`__not-found__`,a=C(n,i),o=S(t)??[];return w((0,e.h)(e.KeepAlive,null,{default:()=>(0,e.h)(a,{key:i},{default:()=>o})}),r)}function T(e){return e===!0||e===``||e===`keep-alive`}function ne(t,n,r){let i=t.props;if(T(i?.keepAlive)&&t.type===o){let r=i?.segment??`__not-found__`,a=C(n,r),o=S(t)??[];return(0,e.h)(e.Fragment,[(0,e.h)(e.KeepAlive,null,{default:()=>(0,e.h)(a,{key:r},{default:()=>o})})])}let a=S(t);return a?(0,e.h)(e.Fragment,[(0,e.h)(e.KeepAlive,null,{default:()=>(0,e.h)(ee)}),w((0,e.h)(e.Fragment,a),r)]):null}const re=(0,e.defineComponent)({name:`RouteView`,props:{nodeName:{type:String,required:!0},keepAlive:{type:Boolean,default:!1}},setup(t,{slots:n}){let r=x(t.nodeName),i=new Map,a=null,l=!1;function u(e,t){return t===a?l:(a=t,l=e.some(e=>e.type===o&&T(e.props?.keepAlive)),l)}return()=>{let a=r.route.value;if(!a)return null;let l=n.default?.(),f=[];d(l,f);let{rendered:p,fallback:m}=h(f,a.name,t.nodeName);if(p.length===0)return null;let g=p[0];if(t.keepAlive)return te(g,i,m);if(g.type!==o&&g.type!==s&&g.type!==c)return null;if(u(f,l))return ne(g,i,m);let _=S(g);return _?w((0,e.h)(e.Fragment,_),m):null}}}),ie=Object.assign(re,{Match:o,Self:s,NotFound:c}),ae=Object.freeze({}),oe=Object.freeze({}),E=`data-real-router-announcer`;function D(e,t){let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=O(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),ce(t)},f=setTimeout(()=>{if(a=!0,c!==null&&!o){let e=c;c=null,d(e,document.querySelector(`h1`))}},100),p=e.subscribe(({route:e})=>{if(i){i=!1;return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(o)return;let t=document.querySelector(`h1`),i=se(e,n,r,t);if(!(!i||i===s)){if(!a){c=i;return}d(i,t)}})})});return{destroy(){o=!0,p(),clearTimeout(l),clearTimeout(f),k()}}}function O(){let e=document.querySelector(`[${E}]`);if(e)return e;let t=document.createElement(`div`);return t.setAttribute(`style`,`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0`),t.setAttribute(`aria-live`,`assertive`),t.setAttribute(`aria-atomic`,`true`),t.setAttribute(E,``),document.body.prepend(t),t}function k(){document.querySelector(`[${E}]`)?.remove()}function se(e,t,n,r){if(n)return n(e);let i=(r?.textContent??``).trim(),a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function ce(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const A=`real-router:scroll`,j=Object.freeze({destroy:()=>{}});function le(e,t){if(globalThis.window===void 0)return j;let n=t?.mode??`restore`;if(n===`manual`)return j;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let o=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},s=e=>{let t=i?.();t?t.scrollTop=e:globalThis.scrollTo(0,e)},c=()=>{let e=globalThis.location.hash;if(r&&e.length>1){let t;try{t=decodeURIComponent(e.slice(1))}catch{t=e.slice(1)}let n=document.getElementById(t);if(n){n.scrollIntoView();return}}s(0)},l=!1,u=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;t&&P(M(t),o()),requestAnimationFrame(()=>{if(!l){if(n===`top`||!r){c();return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){s(N()[M(e)]??0);return}c()}}})}),d=()=>{let t=e.getState();t&&P(M(t),o())};return globalThis.addEventListener(`pagehide`,d),{destroy:()=>{if(!l){l=!0,u(),globalThis.removeEventListener(`pagehide`,d);try{history.scrollRestoration=a}catch{}}}}}function M(e){return`${e.name}:${F(e.params)}`}function N(){try{let e=sessionStorage.getItem(A);return e?JSON.parse(e):{}}catch{return{}}}function P(e,t){try{let n=N();n[e]=t,sessionStorage.setItem(A,JSON.stringify(n))}catch{}}function F(e){return JSON.stringify(e,I)}function I(e,t){if(typeof t==`object`&&t&&!Array.isArray(t)){let e={},n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}const L=Object.freeze({destroy:()=>{}});function R(e){if(typeof document>`u`||typeof document.startViewTransition!=`function`)return L;let t=null,n=null,r=!1,i=()=>{t?.(),t=null},a=e.subscribeLeave(({signal:e})=>{if(!e.aborted)return r=!1,i(),new Promise(a=>{let o=new Promise(e=>{t=e});e.addEventListener(`abort`,()=>{r||(i(),n?.skipTransition?.(),a())},{once:!0});try{n=document.startViewTransition(()=>(a(),o))}catch{i(),a()}})}),o=e.subscribe(()=>{let e=t;r=!0,t=null,e===null?n=null:setTimeout(()=>{e(),n=null},0)});return{destroy:()=>{a(),o(),n?.skipTransition?.(),n=null,i()}}}function z(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}function B(e,t,n){try{let r=e.buildUrl;if(r){let e=r(t,n);if(e!==void 0)return e}return e.buildPath(t,n)}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function V(e){return e?e.match(/\S+/g)??[]:[]}function H(e,t,n){if(e&&t){let e=V(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=V(n),i=new Set(r);for(let t of e)i.has(t)||(i.add(t),r.push(t));return r.join(` `)}return n??void 0}function U(e){e&&(e instanceof HTMLAnchorElement||e instanceof HTMLButtonElement||(e.hasAttribute(`role`)||e.setAttribute(`role`,`link`),e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`0`)))}function W(e,t){if(typeof e==`function`){e(t);return}if(Array.isArray(e)){let n=e;for(let e of n)if(typeof e==`function`&&(e(t),t.defaultPrevented))return}}const ue=(0,e.defineComponent)({name:`Link`,inheritAttrs:!1,props:{routeName:{type:String,required:!0},routeParams:{type:Object,default:()=>ae},routeOptions:{type:Object,default:()=>oe},class:{type:String,default:void 0},activeClassName:{type:String,default:`active`},activeStrict:{type:Boolean,default:!1},ignoreQueryParams:{type:Boolean,default:!0},target:{type:String,default:void 0}},setup(t,{slots:n,attrs:i}){let a=b(),o=(0,e.shallowRef)(!1);(0,e.watch)(()=>[t.routeName,t.routeParams,t.activeStrict,t.ignoreQueryParams],([e,t,n,i],s,c)=>{let l=(0,r.createActiveRouteSource)(a,e,t,{strict:n,ignoreQueryParams:i});o.value=l.getSnapshot(),c(l.subscribe(()=>{o.value=l.getSnapshot()}))},{immediate:!0,flush:`sync`});let s=(0,e.computed)(()=>B(a,t.routeName,t.routeParams)),c=(0,e.computed)(()=>H(o.value,t.activeClassName,t.class)),l=e=>{i.onClick!==void 0&&i.onClick!==null&&(W(i.onClick,e),e.defaultPrevented)||!z(e)||t.target===`_blank`||(e.preventDefault(),a.navigate(t.routeName,t.routeParams,t.routeOptions).catch(()=>{}))};return()=>{let r={};for(let e of Object.keys(i))e!==`onClick`&&(r[e]=i[e]);return(0,e.h)(`a`,{...r,href:s.value,class:c.value,target:t.target,onClick:l},n.default?.())}}}),de=(0,e.defineComponent)({name:`RouterErrorBoundary`,props:{fallback:{type:Function,required:!0},onError:{type:Function,default:void 0}},setup(t,{slots:n}){let i=g((0,r.createDismissableError)(b()));return(0,e.watch)(()=>i.value.version,()=>{i.value.error&&t.onError?.(i.value.error,i.value.toRoute,i.value.fromRoute)},{immediate:!0}),()=>{let r=n.default?.()??[],a=i.value.error?t.fallback(i.value.error,i.value.resetError):null;return(0,e.h)(e.Fragment,null,[...r,a])}}}),G=[];function K(e){return G.push(e),()=>{let t=G.lastIndexOf(e);t!==-1&&G.splice(t,1)}}function q(){let e=G.at(-1);if(!e)throw Error(`v-link directive requires a RouterProvider ancestor. Make sure RouterProvider is mounted.`);return e}const J=new WeakMap;function Y(e){return e==null?(console.error(`[real-router] v-link directive received null/undefined value. The element will not be wired for navigation.`),!1):typeof e.name==`string`?!0:(console.error("[real-router] v-link directive value is missing a string `name` field. The element will not be wired for navigation."),!1)}function fe(e,t){return n=>{z(n)&&(n.preventDefault(),e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{}))}}function pe(e,t,n){return r=>{r.key===`Enter`&&!(n instanceof HTMLButtonElement)&&e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{})}}function X(e,t,n){let r=fe(t,n),i=pe(t,n,e);e.addEventListener(`click`,r),e.addEventListener(`keydown`,i),J.set(e,{click:r,keydown:i})}function Z(e){let t=J.get(e);t&&(e.removeEventListener(`click`,t.click),e.removeEventListener(`keydown`,t.keydown),J.delete(e))}const me={mounted(e,t){let n=q();U(e),e.style.cursor=`pointer`,Y(t.value)&&X(e,n,t.value)},updated(e,t){let n=q();Z(e),Y(t.value)&&X(e,n,t.value)},beforeUnmount(e){Z(e)}},he=()=>{let t=(0,e.inject)(v);if(!t)throw Error(`useNavigator must be used within a RouterProvider`);return t},ge=()=>(0,n.getRouteUtils)((0,i.getPluginApi)(b()).getTree()),Q=()=>{let t=(0,e.inject)(y);if(!t)throw Error(`useRoute must be used within a RouterProvider`);return t};function _e(){return g((0,r.getTransitionSource)(b()))}function ve(t,n){let r=b(),i=n?.skipSameRoute??!0;(0,e.onScopeDispose)(r.subscribeLeave(({route:e,nextRoute:n,signal:r})=>{if(!(i&&e.name===n.name)&&!r.aborted)return t({route:e,nextRoute:n,signal:r})}))}function ye(t,n){let{route:r,previousRoute:i}=Q(),a=n?.skipSameRoute??!0,o=null;(0,e.watch)(r,e=>{let n=i.value;e&&e.transition.from&&(a&&e.transition.from===e.name||o===e||!n||(o=e,t({route:e,previousRoute:n})))})}function $(n){let i=(0,t.getNavigator)(n),a=(0,r.createRouteSource)(n),o=a.getSnapshot(),s=(0,e.shallowRef)(o.route),c=(0,e.shallowRef)(o.previousRoute);return{navigator:i,route:s,previousRoute:c,unsubscribe:a.subscribe(()=>{let e=a.getSnapshot();s.value=e.route,c.value=e.previousRoute})}}function be(e){return{install(t){let n=K(e),{navigator:r,route:i,previousRoute:a,unsubscribe:o}=$(e);`onUnmount`in t&&t.onUnmount(()=>{n(),o()}),t.provide(_,e),t.provide(v,r),t.provide(y,{navigator:r,route:i,previousRoute:a})}}}const xe=(0,e.defineComponent)({name:`RouterProvider`,props:{router:{type:Object,required:!0},announceNavigation:{type:Boolean,default:!1},scrollRestoration:{type:Object},viewTransitions:{type:Boolean,default:!1}},setup(t,{slots:n}){(0,e.watch)(()=>[t.router,t.announceNavigation],([e,t],n,r)=>{if(!t)return;let i=D(e);r(()=>{i.destroy()})},{immediate:!0}),(0,e.watch)(()=>[t.router,t.scrollRestoration!==void 0,t.scrollRestoration?.mode,t.scrollRestoration?.anchorScrolling],([e,n,r,i],a,o)=>{if(!n)return;let s=le(e,{mode:r,anchorScrolling:i,scrollContainer:t.scrollRestoration?.scrollContainer});o(()=>{s.destroy()})},{immediate:!0}),(0,e.watch)(()=>[t.router,t.viewTransitions],([e,t],n,r)=>{if(!t)return;let i=R(e);r(()=>{i.destroy()})},{immediate:!0});let r=K(t.router),{navigator:i,route:a,previousRoute:o,unsubscribe:s}=$(t.router);return(0,e.onScopeDispose)(()=>{r(),s()}),(0,e.provide)(_,t.router),(0,e.provide)(v,i),(0,e.provide)(y,{navigator:i,route:a,previousRoute:o}),()=>n.default?.()}});exports.Link=ue,exports.NavigatorKey=v,exports.RouteKey=y,exports.RouteView=ie,exports.RouterErrorBoundary=de,exports.RouterKey=_,exports.RouterProvider=xe,exports.createRouterPlugin=be,exports.useNavigator=he,exports.useRoute=Q,exports.useRouteEnter=ye,exports.useRouteExit=ve,exports.useRouteNode=x,exports.useRouteUtils=ge,exports.useRouter=b,exports.useRouterTransition=_e,exports.vLink=me;
2
2
  //# sourceMappingURL=index.js.map