@real-router/vue 0.12.1 → 0.14.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.
Files changed (45) hide show
  1. package/README.md +98 -14
  2. package/dist/cjs/createHttpStatusSink-XDu5aGhc.d.ts +32 -0
  3. package/dist/cjs/createHttpStatusSink-XDu5aGhc.d.ts.map +1 -0
  4. package/dist/cjs/index.d.ts +48 -32
  5. package/dist/cjs/index.d.ts.map +1 -1
  6. package/dist/cjs/index.js +1 -1
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/ssr.d.ts +180 -0
  9. package/dist/cjs/ssr.d.ts.map +1 -0
  10. package/dist/cjs/ssr.js +2 -0
  11. package/dist/cjs/ssr.js.map +1 -0
  12. package/dist/cjs/useRoute-BT3SkdOc.js +2 -0
  13. package/dist/cjs/useRoute-BT3SkdOc.js.map +1 -0
  14. package/dist/esm/createHttpStatusSink-DduXvbGr.d.mts +32 -0
  15. package/dist/esm/createHttpStatusSink-DduXvbGr.d.mts.map +1 -0
  16. package/dist/esm/index.d.mts +48 -32
  17. package/dist/esm/index.d.mts.map +1 -1
  18. package/dist/esm/index.mjs +1 -1
  19. package/dist/esm/index.mjs.map +1 -1
  20. package/dist/esm/ssr.d.mts +180 -0
  21. package/dist/esm/ssr.d.mts.map +1 -0
  22. package/dist/esm/ssr.mjs +2 -0
  23. package/dist/esm/ssr.mjs.map +1 -0
  24. package/dist/esm/useRoute-2ocUdDHc.mjs +2 -0
  25. package/dist/esm/useRoute-2ocUdDHc.mjs.map +1 -0
  26. package/package.json +20 -4
  27. package/src/RouterProvider.ts +45 -39
  28. package/src/components/Await.ts +47 -0
  29. package/src/components/ClientOnly.ts +16 -0
  30. package/src/components/HttpStatusCode.ts +74 -0
  31. package/src/components/HttpStatusProvider.ts +22 -0
  32. package/src/components/Link.ts +33 -13
  33. package/src/components/RouteView/RouteView.ts +30 -51
  34. package/src/components/RouteView/helpers.ts +33 -2
  35. package/src/components/ServerOnly.ts +16 -0
  36. package/src/components/Streamed.ts +31 -0
  37. package/src/composables/useDeferred.ts +37 -0
  38. package/src/composables/useIsActiveRoute.ts +33 -3
  39. package/src/composables/useRoute.ts +11 -5
  40. package/src/context.ts +4 -0
  41. package/src/directives/vLink.ts +18 -1
  42. package/src/index.ts +2 -1
  43. package/src/ssr.ts +39 -0
  44. package/src/types.ts +10 -0
  45. package/src/utils/createHttpStatusSink.ts +31 -0
@@ -0,0 +1,180 @@
1
+ import { n as createHttpStatusSink, t as HttpStatusSink } from "./createHttpStatusSink-XDu5aGhc.js";
2
+ import { PropType } from "vue";
3
+
4
+ //#region src/components/ClientOnly.d.ts
5
+ declare const ClientOnly: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
6
+ [key: string]: any;
7
+ }>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
8
+ type ClientOnlyProps = InstanceType<typeof ClientOnly>["$props"];
9
+ //#endregion
10
+ //#region src/components/ServerOnly.d.ts
11
+ declare const ServerOnly: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
12
+ [key: string]: any;
13
+ }>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
14
+ type ServerOnlyProps = InstanceType<typeof ServerOnly>["$props"];
15
+ //#endregion
16
+ //#region src/components/Await.d.ts
17
+ /**
18
+ * Reads `useDeferred(name)` and hands the resolved value to the `default`
19
+ * scoped slot via Vue's native `async setup()` Suspense pattern. Wrap in
20
+ * `<Streamed>` (or Vue's `<Suspense>`).
21
+ *
22
+ * ```vue-html
23
+ * <Streamed>
24
+ * <Await name="reviews" v-slot="{ value }">
25
+ * <ReviewList :items="value" />
26
+ * </Await>
27
+ * <template #fallback>
28
+ * <Spinner />
29
+ * </template>
30
+ * </Streamed>
31
+ * ```
32
+ *
33
+ * Or with the render function:
34
+ *
35
+ * ```ts
36
+ * h(Await, { name: "reviews" }, {
37
+ * default: ({ value }: { value: Review[] }) => h(ReviewList, { items: value }),
38
+ * });
39
+ * ```
40
+ *
41
+ * Implementation: `async setup()` awaits the deferred promise. Vue's
42
+ * `<Suspense>` boundary catches the pending promise and shows the fallback
43
+ * until resolution. Rejection bubbles to the nearest `onErrorCaptured`
44
+ * handler.
45
+ */
46
+ declare const Await: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
47
+ /** Deferred key declared in the loader's `defer({ deferred: { <name>: ... } })`. */name: {
48
+ type: StringConstructor;
49
+ required: true;
50
+ };
51
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
52
+ [key: string]: any;
53
+ }>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
54
+ /** Deferred key declared in the loader's `defer({ deferred: { <name>: ... } })`. */name: {
55
+ type: StringConstructor;
56
+ required: true;
57
+ };
58
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
59
+ type AwaitProps = InstanceType<typeof Await>["$props"];
60
+ //#endregion
61
+ //#region src/components/Streamed.d.ts
62
+ /**
63
+ * Cross-adapter alias for Vue's native `<Suspense>`. Symmetric naming with
64
+ * the React/Preact/Solid/Svelte/Angular `<Streamed>` components.
65
+ *
66
+ * Slots:
67
+ * - `default` — content (may contain `<Await>` or `async setup()` children).
68
+ * - `fallback` — shown while any descendant suspends.
69
+ *
70
+ * Vue's `<Suspense>` is **blocking** under SSR (no out-of-order placeholder
71
+ * resolution) — render of HTML after `<Streamed>` waits for every
72
+ * `async setup()` inside. This matches Vue 3's stable streaming behaviour
73
+ * (vs React 19 / Solid which support OOO resolution).
74
+ */
75
+ declare const Streamed: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
76
+ [key: string]: any;
77
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
78
+ type StreamedProps = InstanceType<typeof Streamed>["$props"];
79
+ //#endregion
80
+ //#region src/components/HttpStatusCode.d.ts
81
+ /**
82
+ * Render-time HTTP status declaration. Mount inside a route component (typical
83
+ * use case: a glob `*` route's NotFound page) when the status is decided by
84
+ * the rendered tree rather than a loader.
85
+ *
86
+ * Writes `code` to the nearest `<HttpStatusProvider>`'s sink during `setup()`
87
+ * and renders nothing. With no provider mounted (the standard client-side
88
+ * case) the component is a silent no-op — same component tree hydrates
89
+ * without touching the DOM or warning about mismatches.
90
+ *
91
+ * Loader-driven errors (`LoaderNotFound` → 404, `LoaderRedirect` → 30x) keep
92
+ * working as before; this component covers render-time decisions only.
93
+ *
94
+ * Last write wins when several `<HttpStatusCode />` instances mount in the
95
+ * same render pass — sink reflects the last component that ran.
96
+ *
97
+ * ```vue-html
98
+ * <HttpStatusProvider :sink="sink">
99
+ * <RouterProvider :router="router">
100
+ * <App />
101
+ * </RouterProvider>
102
+ * </HttpStatusProvider>
103
+ *
104
+ * <!-- inside NotFound.vue -->
105
+ * <HttpStatusCode :code="404" />
106
+ * ```
107
+ *
108
+ * **`renderToWebStream` (streaming SSR):** Vue 3 `<Suspense>` is
109
+ * chunked-blocking — Vue waits for every `async setup()` inside a boundary
110
+ * before emitting the chunks past it. So in practice `<HttpStatusCode />`
111
+ * inside a `<Suspense>` boundary still writes to the sink before the
112
+ * response headers flush. Still, prefer mounting in the shell to avoid
113
+ * coupling the contract to that particular Vue 3 streaming behaviour. With
114
+ * `renderToString` there is no ordering concern at all.
115
+ *
116
+ * **Hydration symmetry:** `<HttpStatusProvider>` wraps a render slot, so
117
+ * Vue emits a fragment marker pair (`<!--[-->` / `<!--]-->`) around its
118
+ * children server-side. Mount the same `<HttpStatusProvider>` on the
119
+ * client (with a throwaway sink) to keep the marker count balanced — see
120
+ * the `ssr/` example's `entry-client.ts`. Otherwise hydration logs
121
+ * "Hydration completed but contains mismatches".
122
+ *
123
+ * **Valid `code` range:** Node's `res.end()` throws `Invalid status code`
124
+ * on `NaN`, `0`, negative values, or values `> 999` — this surfaces as a
125
+ * 5xx / dropped connection, not silent corruption. Pass a real HTTP status
126
+ * integer (commonly 4xx/5xx; 100-999 is what Node accepts).
127
+ */
128
+ declare const HttpStatusCode: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
129
+ /** HTTP status to apply to the response. Common values: 404, 410, 451, 503. */code: {
130
+ type: NumberConstructor;
131
+ required: true;
132
+ };
133
+ }>, () => null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
134
+ /** HTTP status to apply to the response. Common values: 404, 410, 451, 503. */code: {
135
+ type: NumberConstructor;
136
+ required: true;
137
+ };
138
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
139
+ type HttpStatusCodeProps = InstanceType<typeof HttpStatusCode>["$props"];
140
+ //#endregion
141
+ //#region src/components/HttpStatusProvider.d.ts
142
+ declare const HttpStatusProvider: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
143
+ sink: {
144
+ type: PropType<HttpStatusSink>;
145
+ required: true;
146
+ };
147
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
148
+ [key: string]: any;
149
+ }>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
150
+ sink: {
151
+ type: PropType<HttpStatusSink>;
152
+ required: true;
153
+ };
154
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
155
+ type HttpStatusProviderProps = InstanceType<typeof HttpStatusProvider>["$props"];
156
+ //#endregion
157
+ //#region src/composables/useDeferred.d.ts
158
+ /**
159
+ * Read a deferred promise published by `defer({ deferred: { <key>: Promise } })`
160
+ * inside an SSR data loader. Returns the Promise for use inside `async setup()`
161
+ * (Vue's native Suspense pattern) or paired with `<Await name="key">`.
162
+ *
163
+ * ```ts
164
+ * // Vue async setup pattern
165
+ * export default defineComponent({
166
+ * async setup() {
167
+ * const reviews = await useDeferred<Review[]>("reviews");
168
+ * return () => h("div", reviews.map(...));
169
+ * },
170
+ * });
171
+ * ```
172
+ *
173
+ * Returns a forever-pending promise when the key is missing — surfaces
174
+ * loader/consumer key drift as a visible Suspense fallback rather than a
175
+ * silent runtime error.
176
+ */
177
+ declare function useDeferred<T = unknown>(key: string): Promise<T>;
178
+ //#endregion
179
+ export { Await, type AwaitProps, ClientOnly, type ClientOnlyProps, HttpStatusCode, type HttpStatusCodeProps, HttpStatusProvider, type HttpStatusProviderProps, type HttpStatusSink, ServerOnly, type ServerOnlyProps, Streamed, type StreamedProps, createHttpStatusSink, useDeferred };
180
+ //# sourceMappingURL=ssr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr.d.ts","names":[],"sources":["../../src/components/ClientOnly.ts","../../src/components/ServerOnly.ts","../../src/components/Await.ts","../../src/components/Streamed.ts","../../src/components/HttpStatusCode.ts","../../src/components/HttpStatusProvider.ts","../../src/composables/useDeferred.ts"],"mappings":";;;;cAEa,UAAA,gBAAU,eAAA,yBAAA,KAAA,eAAA,YAAA,gBAAA,eAAA;EAAA;+IAWrB,QAAA,OAAA,QAAA;KAEU,eAAA,GAAkB,YAAY,QAAQ,UAAA;;;cCbrC,UAAA,gBAAU,eAAA,yBAAA,KAAA,eAAA,YAAA,gBAAA,eAAA;EAAA;+IAWrB,QAAA,OAAA,QAAA;KAEU,eAAA,GAAkB,YAAY,QAAQ,UAAA;;;;;;;ADblD;;;;;;;;;;;;;;;;;AAaA;;;;AAA4D;;;;cEkB/C,KAAA,gBAAK,eAAA,eAAA,gBAAA;EDpBhB;;;;;;;;;;;;KCiCU,UAAA,GAAa,YAAY,QAAQ,KAAA;;;;;;;AF5C7C;;;;;;;;;cGaa,QAAA,gBAAQ,eAAA,yBAAA,KAAA,eAAA,YAAA,gBAAA,eAAA;EAAA;iIAanB,QAAA,OAAA,QAAA;KAEU,aAAA,GAAgB,YAAY,QAAQ,QAAA;;;;;;;AH5BhD;;;;;;;;;;;;;;;;;AAaA;;;;AAA4D;;;;ACb5D;;;;;;;;;;;;;;;;;AAaA;cGyCa,cAAA,gBAAc,eAAA,eAAA,gBAAA;;;;;0CAjDA,qBAAA,gBAAA,qBAAA,4BAAA,WAAA,EAAA,QAAA,eAAA,gBAAA;EF0Bd;;;;;KEwCD,mBAAA,GAAsB,YAAY,QAAQ,cAAA;;;cClEzC,kBAAA,gBAAkB,eAAA,eAAA,gBAAA;;UAGH,QAAA,CAAS,cAAA;;;;;;;UAAT,QAAA,CAAS,cAAA;;;;KASzB,uBAAA,GAA0B,YAAY,QACzC,kBAAA;;;;;;;ALlBT;;;;;;;;;;;;;;;iBM4BgB,WAAA,aAAA,CAAyB,GAAA,WAAc,OAAO,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./useRoute-BT3SkdOc.js`);let t=require(`vue`);const n=(0,t.defineComponent)({name:`ClientOnly`,setup(e,{slots:n}){let r=(0,t.ref)(!1);return(0,t.onMounted)(()=>{r.value=!0}),()=>r.value?n.default?.():n.fallback?.()}}),r=(0,t.defineComponent)({name:`ServerOnly`,setup(e,{slots:n}){let r=(0,t.ref)(!1);return(0,t.onMounted)(()=>{r.value=!0}),()=>r.value?n.fallback?.():n.default?.()}}),i=new Promise(()=>{});function a(t){let{route:n}=e.t();return n.value.context.ssrDataDeferred?.[t]??i}const o=(0,t.defineComponent)({name:`Await`,props:{name:{type:String,required:!0}},async setup(e,{slots:t}){let n=await a(e.name);return()=>t.default?.({value:n})}}),s=(0,t.defineComponent)({name:`Streamed`,setup(e,{slots:n}){return()=>(0,t.h)(t.Suspense,{},{default:()=>n.default?.(),fallback:()=>n.fallback?.()})}}),c=()=>null,l=(0,t.defineComponent)({name:`HttpStatusCode`,props:{code:{type:Number,required:!0}},setup(n){let r=(0,t.inject)(e.n,null);return r&&(r.code=n.code),c}}),u=(0,t.defineComponent)({name:`HttpStatusProvider`,props:{sink:{type:Object,required:!0}},setup(n,{slots:r}){return(0,t.provide)(e.n,n.sink),()=>r.default?.()}});function d(){return{code:void 0}}exports.Await=o,exports.ClientOnly=n,exports.HttpStatusCode=l,exports.HttpStatusProvider=u,exports.ServerOnly=r,exports.Streamed=s,exports.createHttpStatusSink=d,exports.useDeferred=a;
2
+ //# sourceMappingURL=ssr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr.js","names":["useRoute","Suspense","HTTP_STATUS_KEY","HTTP_STATUS_KEY"],"sources":["../../src/components/ClientOnly.ts","../../src/components/ServerOnly.ts","../../src/composables/useDeferred.ts","../../src/components/Await.ts","../../src/components/Streamed.ts","../../src/components/HttpStatusCode.ts","../../src/components/HttpStatusProvider.ts","../../src/utils/createHttpStatusSink.ts"],"sourcesContent":["import { defineComponent, onMounted, ref } from \"vue\";\n\nexport const ClientOnly = defineComponent({\n name: \"ClientOnly\",\n setup(_, { slots }) {\n const mounted = ref(false);\n\n onMounted(() => {\n mounted.value = true;\n });\n\n return () => (mounted.value ? slots.default?.() : slots.fallback?.());\n },\n});\n\nexport type ClientOnlyProps = InstanceType<typeof ClientOnly>[\"$props\"];\n","import { defineComponent, onMounted, ref } from \"vue\";\n\nexport const ServerOnly = defineComponent({\n name: \"ServerOnly\",\n setup(_, { slots }) {\n const mounted = ref(false);\n\n onMounted(() => {\n mounted.value = true;\n });\n\n return () => (mounted.value ? slots.fallback?.() : slots.default?.());\n },\n});\n\nexport type ServerOnlyProps = InstanceType<typeof ServerOnly>[\"$props\"];\n","import { useRoute } from \"./useRoute\";\n\ninterface DeferredContext {\n ssrDataDeferred?: Record<string, Promise<unknown>>;\n}\n\nconst NEVER_PROMISE = new Promise<never>(() => {\n // Intentionally never resolves — surfaces a forever-pending Suspense boundary\n // when a key is requested that the loader never declared.\n});\n\n/**\n * Read a deferred promise published by `defer({ deferred: { <key>: Promise } })`\n * inside an SSR data loader. Returns the Promise for use inside `async setup()`\n * (Vue's native Suspense pattern) or paired with `<Await name=\"key\">`.\n *\n * ```ts\n * // Vue async setup pattern\n * export default defineComponent({\n * async setup() {\n * const reviews = await useDeferred<Review[]>(\"reviews\");\n * return () => h(\"div\", reviews.map(...));\n * },\n * });\n * ```\n *\n * Returns a forever-pending promise when the key is missing — surfaces\n * loader/consumer key drift as a visible Suspense fallback rather than a\n * silent runtime error.\n */\nexport function useDeferred<T = unknown>(key: string): Promise<T> {\n const { route } = useRoute();\n const context = route.value.context as DeferredContext;\n const deferred = context.ssrDataDeferred;\n\n return (deferred?.[key] ?? NEVER_PROMISE) as Promise<T>;\n}\n","import { defineComponent } from \"vue\";\n\nimport { useDeferred } from \"../composables/useDeferred\";\n\n/**\n * Reads `useDeferred(name)` and hands the resolved value to the `default`\n * scoped slot via Vue's native `async setup()` Suspense pattern. Wrap in\n * `<Streamed>` (or Vue's `<Suspense>`).\n *\n * ```vue-html\n * <Streamed>\n * <Await name=\"reviews\" v-slot=\"{ value }\">\n * <ReviewList :items=\"value\" />\n * </Await>\n * <template #fallback>\n * <Spinner />\n * </template>\n * </Streamed>\n * ```\n *\n * Or with the render function:\n *\n * ```ts\n * h(Await, { name: \"reviews\" }, {\n * default: ({ value }: { value: Review[] }) => h(ReviewList, { items: value }),\n * });\n * ```\n *\n * Implementation: `async setup()` awaits the deferred promise. Vue's\n * `<Suspense>` boundary catches the pending promise and shows the fallback\n * until resolution. Rejection bubbles to the nearest `onErrorCaptured`\n * handler.\n */\nexport const Await = defineComponent({\n name: \"Await\",\n props: {\n /** Deferred key declared in the loader's `defer({ deferred: { <name>: ... } })`. */\n name: { type: String, required: true },\n },\n async setup(props, { slots }) {\n const value = await useDeferred(props.name);\n\n return () => slots.default?.({ value });\n },\n});\n\nexport type AwaitProps = InstanceType<typeof Await>[\"$props\"];\n","import { defineComponent, h, Suspense } from \"vue\";\n\n/**\n * Cross-adapter alias for Vue's native `<Suspense>`. Symmetric naming with\n * the React/Preact/Solid/Svelte/Angular `<Streamed>` components.\n *\n * Slots:\n * - `default` — content (may contain `<Await>` or `async setup()` children).\n * - `fallback` — shown while any descendant suspends.\n *\n * Vue's `<Suspense>` is **blocking** under SSR (no out-of-order placeholder\n * resolution) — render of HTML after `<Streamed>` waits for every\n * `async setup()` inside. This matches Vue 3's stable streaming behaviour\n * (vs React 19 / Solid which support OOO resolution).\n */\nexport const Streamed = defineComponent({\n name: \"Streamed\",\n setup(_, { slots }) {\n return () =>\n h(\n Suspense,\n {},\n {\n default: () => slots.default?.(),\n fallback: () => slots.fallback?.(),\n },\n );\n },\n});\n\nexport type StreamedProps = InstanceType<typeof Streamed>[\"$props\"];\n","import { defineComponent, inject } from \"vue\";\n\nimport { HTTP_STATUS_KEY } from \"../context\";\n\n// Module-scope render function — returns null since the component emits no DOM.\n// Hoisted to satisfy `unicorn/consistent-function-scoping` and to avoid\n// re-creating the closure on every component instantiation.\nconst renderNull = (): null => null;\n\n/**\n * Render-time HTTP status declaration. Mount inside a route component (typical\n * use case: a glob `*` route's NotFound page) when the status is decided by\n * the rendered tree rather than a loader.\n *\n * Writes `code` to the nearest `<HttpStatusProvider>`'s sink during `setup()`\n * and renders nothing. With no provider mounted (the standard client-side\n * case) the component is a silent no-op — same component tree hydrates\n * without touching the DOM or warning about mismatches.\n *\n * Loader-driven errors (`LoaderNotFound` → 404, `LoaderRedirect` → 30x) keep\n * working as before; this component covers render-time decisions only.\n *\n * Last write wins when several `<HttpStatusCode />` instances mount in the\n * same render pass — sink reflects the last component that ran.\n *\n * ```vue-html\n * <HttpStatusProvider :sink=\"sink\">\n * <RouterProvider :router=\"router\">\n * <App />\n * </RouterProvider>\n * </HttpStatusProvider>\n *\n * <!-- inside NotFound.vue -->\n * <HttpStatusCode :code=\"404\" />\n * ```\n *\n * **`renderToWebStream` (streaming SSR):** Vue 3 `<Suspense>` is\n * chunked-blocking — Vue waits for every `async setup()` inside a boundary\n * before emitting the chunks past it. So in practice `<HttpStatusCode />`\n * inside a `<Suspense>` boundary still writes to the sink before the\n * response headers flush. Still, prefer mounting in the shell to avoid\n * coupling the contract to that particular Vue 3 streaming behaviour. With\n * `renderToString` there is no ordering concern at all.\n *\n * **Hydration symmetry:** `<HttpStatusProvider>` wraps a render slot, so\n * Vue emits a fragment marker pair (`<!--[-->` / `<!--]-->`) around its\n * children server-side. Mount the same `<HttpStatusProvider>` on the\n * client (with a throwaway sink) to keep the marker count balanced — see\n * the `ssr/` example's `entry-client.ts`. Otherwise hydration logs\n * \"Hydration completed but contains mismatches\".\n *\n * **Valid `code` range:** Node's `res.end()` throws `Invalid status code`\n * on `NaN`, `0`, negative values, or values `> 999` — this surfaces as a\n * 5xx / dropped connection, not silent corruption. Pass a real HTTP status\n * integer (commonly 4xx/5xx; 100-999 is what Node accepts).\n */\nexport const HttpStatusCode = defineComponent({\n name: \"HttpStatusCode\",\n props: {\n /** HTTP status to apply to the response. Common values: 404, 410, 451, 503. */\n code: { type: Number, required: true },\n },\n setup(props) {\n const sink = inject(HTTP_STATUS_KEY, null);\n\n if (sink) {\n sink.code = props.code;\n }\n\n return renderNull;\n },\n});\n\nexport type HttpStatusCodeProps = InstanceType<typeof HttpStatusCode>[\"$props\"];\n","import { defineComponent, provide } from \"vue\";\n\nimport { HTTP_STATUS_KEY } from \"../context\";\n\nimport type { HttpStatusSink } from \"../utils/createHttpStatusSink\";\nimport type { PropType } from \"vue\";\n\nexport const HttpStatusProvider = defineComponent({\n name: \"HttpStatusProvider\",\n props: {\n sink: { type: Object as PropType<HttpStatusSink>, required: true },\n },\n setup(props, { slots }) {\n provide(HTTP_STATUS_KEY, props.sink);\n\n return () => slots.default?.();\n },\n});\n\nexport type HttpStatusProviderProps = InstanceType<\n typeof HttpStatusProvider\n>[\"$props\"];\n","/**\n * Render-scoped HTTP status sink. Created per request on the server, passed to\n * `<HttpStatusProvider :sink=\"...\">`, and read after `renderToString` /\n * `renderToWebStream` to apply the value to the HTTP response.\n *\n * Last write wins: if the rendered tree mounts more than one\n * `<HttpStatusCode />`, the value reflects the last component that ran during\n * the render pass.\n *\n * No-op on the client — `<HttpStatusCode />` reads the optional injected sink\n * and skips the write when no provider is mounted, so the same component tree\n * can be hydrated without changing behaviour.\n *\n * Constraints:\n * - **Per-request only.** Don't share a sink across requests; the rendered\n * tree mutates `code` in place. Module-level singletons leak status\n * between concurrent requests.\n * - **Don't `Object.freeze` the sink.** The component writes to `.code`;\n * freezing makes the assignment throw under ESM strict mode.\n * - **Hydration symmetry:** mount `<HttpStatusProvider>` on both server and\n * client (with a throwaway client sink). Vue emits `<!--[-->` / `<!--]-->`\n * fragment markers around the provider's slot; an extra provider on one\n * side trips Vue with \"Hydration completed but contains mismatches\".\n */\nexport interface HttpStatusSink {\n code: number | undefined;\n}\n\nexport function createHttpStatusSink(): HttpStatusSink {\n return { code: undefined };\n}\n"],"mappings":"kIAEA,MAAa,GAAA,EAAA,EAAA,iBAA6B,CACxC,KAAM,aACN,MAAM,EAAG,CAAE,SAAS,CAClB,IAAM,GAAA,EAAA,EAAA,KAAc,EAAK,EAMzB,OAJA,EAAA,EAAA,eAAgB,CACd,EAAQ,MAAQ,EAClB,CAAC,MAEa,EAAQ,MAAQ,EAAM,UAAU,EAAI,EAAM,WAAW,CACrE,CACF,CAAC,ECXY,GAAA,EAAA,EAAA,iBAA6B,CACxC,KAAM,aACN,MAAM,EAAG,CAAE,SAAS,CAClB,IAAM,GAAA,EAAA,EAAA,KAAc,EAAK,EAMzB,OAJA,EAAA,EAAA,eAAgB,CACd,EAAQ,MAAQ,EAClB,CAAC,MAEa,EAAQ,MAAQ,EAAM,WAAW,EAAI,EAAM,UAAU,CACrE,CACF,CAAC,ECPK,EAAgB,IAAI,YAAqB,CAG/C,CAAC,EAqBD,SAAgB,EAAyB,EAAyB,CAChE,GAAM,CAAE,SAAUA,EAAAA,EAAS,EAI3B,OAHgB,EAAM,MAAM,QACH,kBAEN,IAAQ,CAC7B,CCHA,MAAa,GAAA,EAAA,EAAA,iBAAwB,CACnC,KAAM,QACN,MAAO,CAEL,KAAM,CAAE,KAAM,OAAQ,SAAU,EAAK,CACvC,EACA,MAAM,MAAM,EAAO,CAAE,SAAS,CAC5B,IAAM,EAAQ,MAAM,EAAY,EAAM,IAAI,EAE1C,UAAa,EAAM,UAAU,CAAE,OAAM,CAAC,CACxC,CACF,CAAC,EC7BY,GAAA,EAAA,EAAA,iBAA2B,CACtC,KAAM,WACN,MAAM,EAAG,CAAE,SAAS,CAClB,WAAA,EAAA,EAAA,GAEIC,EAAAA,SACA,CAAC,EACD,CACE,YAAe,EAAM,UAAU,EAC/B,aAAgB,EAAM,WAAW,CACnC,CACF,CACJ,CACF,CAAC,ECrBK,MAAyB,KAiDlB,GAAA,EAAA,EAAA,iBAAiC,CAC5C,KAAM,iBACN,MAAO,CAEL,KAAM,CAAE,KAAM,OAAQ,SAAU,EAAK,CACvC,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAA,EAAA,QAAcC,EAAAA,EAAiB,IAAI,EAMzC,OAJI,IACF,EAAK,KAAO,EAAM,MAGb,CACT,CACF,CAAC,EChEY,GAAA,EAAA,EAAA,iBAAqC,CAChD,KAAM,qBACN,MAAO,CACL,KAAM,CAAE,KAAM,OAAoC,SAAU,EAAK,CACnE,EACA,MAAM,EAAO,CAAE,SAAS,CAGtB,OAFA,EAAA,EAAA,SAAQC,EAAAA,EAAiB,EAAM,IAAI,MAEtB,EAAM,UAAU,CAC/B,CACF,CAAC,ECWD,SAAgB,GAAuC,CACrD,MAAO,CAAE,KAAM,IAAA,EAAU,CAC3B"}
@@ -0,0 +1,2 @@
1
+ let e=require(`vue`);const t=Symbol(`RouterKey`),n=Symbol(`NavigatorKey`),r=Symbol(`RouteKey`),i=Symbol(`HttpStatusSink`),a=()=>{let t=(0,e.inject)(r);if(!t)throw Error(`useRoute must be used within a RouterProvider`);if(!t.route.value)throw Error(`useRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?`);return t};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return a}});
2
+ //# sourceMappingURL=useRoute-BT3SkdOc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRoute-BT3SkdOc.js","names":[],"sources":["../../src/context.ts","../../src/composables/useRoute.ts"],"sourcesContent":["import type { RouteContext as RouteContextType } from \"./types\";\nimport type { HttpStatusSink } from \"./utils/createHttpStatusSink\";\nimport type { Router, Navigator } from \"@real-router/core\";\nimport type { InjectionKey } from \"vue\";\n\nexport const RouterKey: InjectionKey<Router> = Symbol(\"RouterKey\");\n\nexport const NavigatorKey: InjectionKey<Navigator> = Symbol(\"NavigatorKey\");\n\nexport const RouteKey: InjectionKey<RouteContextType> = Symbol(\"RouteKey\");\n\nexport const HTTP_STATUS_KEY: InjectionKey<HttpStatusSink> =\n Symbol(\"HttpStatusSink\");\n","import { inject } from \"vue\";\n\nimport { RouteKey } from \"../context\";\n\nimport type { RouteContext } from \"../types\";\nimport type { Params, State } from \"@real-router/core\";\nimport type { Ref } from \"vue\";\n\n/**\n * Return shape for `useRoute()` — `RouteContext<P>` with `route` narrowed\n * to the non-nullable variant. The composable throws when `route.value`\n * would be `undefined`, so consumers can read `.value.params.x` without a\n * nullable guard. Extracted from inline duplication at two call sites.\n */\nexport type UseRouteReturn<P extends Params = Params> = Omit<\n RouteContext<P>,\n \"route\"\n> & { route: Readonly<Ref<State<P>>> };\n\nexport const useRoute = <P extends Params = Params>(): UseRouteReturn<P> => {\n const routeContext = inject(RouteKey);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouterProvider\");\n }\n\n if (!routeContext.route.value) {\n throw new Error(\n \"useRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?\",\n );\n }\n\n return routeContext as UseRouteReturn<P>;\n};\n"],"mappings":"qBAKA,MAAa,EAAkC,OAAO,WAAW,EAEpD,EAAwC,OAAO,cAAc,EAE7D,EAA2C,OAAO,UAAU,EAE5D,EACX,OAAO,gBAAgB,ECOZ,MAA+D,CAC1E,IAAM,GAAA,EAAA,EAAA,QAAsB,CAAQ,EAEpC,GAAI,CAAC,EACH,MAAU,MAAM,+CAA+C,EAGjE,GAAI,CAAC,EAAa,MAAM,MACtB,MAAU,MACR,mIACF,EAGF,OAAO,CACT"}
@@ -0,0 +1,32 @@
1
+ //#region src/utils/createHttpStatusSink.d.ts
2
+ /**
3
+ * Render-scoped HTTP status sink. Created per request on the server, passed to
4
+ * `<HttpStatusProvider :sink="...">`, and read after `renderToString` /
5
+ * `renderToWebStream` to apply the value to the HTTP response.
6
+ *
7
+ * Last write wins: if the rendered tree mounts more than one
8
+ * `<HttpStatusCode />`, the value reflects the last component that ran during
9
+ * the render pass.
10
+ *
11
+ * No-op on the client — `<HttpStatusCode />` reads the optional injected sink
12
+ * and skips the write when no provider is mounted, so the same component tree
13
+ * can be hydrated without changing behaviour.
14
+ *
15
+ * Constraints:
16
+ * - **Per-request only.** Don't share a sink across requests; the rendered
17
+ * tree mutates `code` in place. Module-level singletons leak status
18
+ * between concurrent requests.
19
+ * - **Don't `Object.freeze` the sink.** The component writes to `.code`;
20
+ * freezing makes the assignment throw under ESM strict mode.
21
+ * - **Hydration symmetry:** mount `<HttpStatusProvider>` on both server and
22
+ * client (with a throwaway client sink). Vue emits `<!--[-->` / `<!--]-->`
23
+ * fragment markers around the provider's slot; an extra provider on one
24
+ * side trips Vue with "Hydration completed but contains mismatches".
25
+ */
26
+ interface HttpStatusSink {
27
+ code: number | undefined;
28
+ }
29
+ declare function createHttpStatusSink(): HttpStatusSink;
30
+ //#endregion
31
+ export { createHttpStatusSink as n, HttpStatusSink as t };
32
+ //# sourceMappingURL=createHttpStatusSink-DduXvbGr.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createHttpStatusSink-DduXvbGr.d.mts","names":[],"sources":["../../src/utils/createHttpStatusSink.ts"],"mappings":";;AAwBA;;;;AACM;AAGN;;;;AAAsD;;;;;;;;;;;;;;UAJrC,cAAA;EACf,IAAI;AAAA;AAAA,iBAGU,oBAAA,CAAA,GAAwB,cAAc"}
@@ -1,4 +1,3 @@
1
- import * as _$vue from "vue";
2
1
  import { Directive, InjectionKey, Plugin, PropType, Ref, ShallowRef, VNode } from "vue";
3
2
  import { NavigationOptions, Navigator, Navigator as Navigator$1, Params, Router, RouterError, State } from "@real-router/core";
4
3
  import { RouteUtils } from "@real-router/route-utils";
@@ -23,7 +22,7 @@ type NotFoundProps = Record<string, never>;
23
22
  //#endregion
24
23
  //#region src/components/RouteView/RouteView.d.ts
25
24
  declare const RouteView: {
26
- new (...args: any[]): _$vue.CreateComponentPublicInstanceWithMixins<Readonly<_$vue.ExtractPropTypes<{
25
+ new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<import("vue").ExtractPropTypes<{
27
26
  nodeName: {
28
27
  type: StringConstructor;
29
28
  required: true;
@@ -32,16 +31,16 @@ declare const RouteView: {
32
31
  type: BooleanConstructor;
33
32
  default: boolean;
34
33
  };
35
- }>> & Readonly<{}>, () => VNode | null, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, _$vue.PublicProps, {
34
+ }>> & Readonly<{}>, () => VNode | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, {
36
35
  keepAlive: boolean;
37
- }, true, {}, {}, _$vue.GlobalComponents, _$vue.GlobalDirectives, string, {}, any, _$vue.ComponentProvideOptions, {
36
+ }, true, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
38
37
  P: {};
39
38
  B: {};
40
39
  D: {};
41
40
  C: {};
42
41
  M: {};
43
42
  Defaults: {};
44
- }, Readonly<_$vue.ExtractPropTypes<{
43
+ }, Readonly<import("vue").ExtractPropTypes<{
45
44
  nodeName: {
46
45
  type: StringConstructor;
47
46
  required: true;
@@ -56,7 +55,7 @@ declare const RouteView: {
56
55
  __isFragment?: never;
57
56
  __isTeleport?: never;
58
57
  __isSuspense?: never;
59
- } & _$vue.ComponentOptionsBase<Readonly<_$vue.ExtractPropTypes<{
58
+ } & import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
60
59
  nodeName: {
61
60
  type: StringConstructor;
62
61
  required: true;
@@ -65,12 +64,12 @@ declare const RouteView: {
65
64
  type: BooleanConstructor;
66
65
  default: boolean;
67
66
  };
68
- }>> & Readonly<{}>, () => VNode | null, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, {
67
+ }>> & Readonly<{}>, () => VNode | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {
69
68
  keepAlive: boolean;
70
- }, {}, string, {}, _$vue.GlobalComponents, _$vue.GlobalDirectives, string, _$vue.ComponentProvideOptions> & _$vue.VNodeProps & _$vue.AllowedComponentProps & _$vue.ComponentCustomProps & {
71
- Match: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
69
+ }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & {
70
+ Match: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
72
71
  segment: {
73
- type: _$vue.PropType<string>;
72
+ type: import("vue").PropType<string>;
74
73
  required: true;
75
74
  };
76
75
  exact: {
@@ -78,16 +77,16 @@ declare const RouteView: {
78
77
  default: boolean;
79
78
  };
80
79
  fallback: {
81
- type: _$vue.PropType<VNode | (() => VNode)>;
80
+ type: import("vue").PropType<VNode | (() => VNode)>;
82
81
  default: undefined;
83
82
  };
84
83
  keepAlive: {
85
84
  type: BooleanConstructor;
86
85
  default: boolean;
87
86
  };
88
- }>, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
87
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
89
88
  segment: {
90
- type: _$vue.PropType<string>;
89
+ type: import("vue").PropType<string>;
91
90
  required: true;
92
91
  };
93
92
  exact: {
@@ -95,7 +94,7 @@ declare const RouteView: {
95
94
  default: boolean;
96
95
  };
97
96
  fallback: {
98
- type: _$vue.PropType<VNode | (() => VNode)>;
97
+ type: import("vue").PropType<VNode | (() => VNode)>;
99
98
  default: undefined;
100
99
  };
101
100
  keepAlive: {
@@ -103,18 +102,18 @@ declare const RouteView: {
103
102
  default: boolean;
104
103
  };
105
104
  }>> & Readonly<{}>, {
106
- fallback: VNode<_$vue.RendererNode, _$vue.RendererElement, {
105
+ fallback: VNode<import("vue").RendererNode, import("vue").RendererElement, {
107
106
  [key: string]: any;
108
107
  }> | (() => VNode);
109
108
  keepAlive: boolean;
110
109
  exact: boolean;
111
- }, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
112
- Self: _$vue.FunctionalComponent<SelfProps, {}, any, {}>;
113
- NotFound: _$vue.DefineComponent<{}, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
110
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
111
+ Self: import("vue").FunctionalComponent<SelfProps, {}, any, {}>;
112
+ NotFound: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
114
113
  };
115
114
  //#endregion
116
115
  //#region src/components/Link.d.ts
117
- declare const Link: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
116
+ declare const Link: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
118
117
  routeName: {
119
118
  type: StringConstructor;
120
119
  required: true;
@@ -157,9 +156,9 @@ declare const Link: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
157
156
  type: StringConstructor;
158
157
  default: undefined;
159
158
  };
160
- }>, () => _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
159
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
161
160
  [key: string]: any;
162
- }>, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
161
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
163
162
  routeName: {
164
163
  type: StringConstructor;
165
164
  required: true;
@@ -211,10 +210,10 @@ declare const Link: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
211
210
  ignoreQueryParams: boolean;
212
211
  target: string;
213
212
  hash: string;
214
- }, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
213
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
215
214
  //#endregion
216
215
  //#region src/components/RouterErrorBoundary.d.ts
217
- declare const RouterErrorBoundary: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
216
+ declare const RouterErrorBoundary: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
218
217
  fallback: {
219
218
  type: PropType<(error: RouterError, resetError: () => void) => VNode>;
220
219
  required: true;
@@ -223,9 +222,9 @@ declare const RouterErrorBoundary: _$vue.DefineComponent<_$vue.ExtractPropTypes<
223
222
  type: PropType<(error: RouterError, toRoute: State | null, fromRoute: State | null) => void>;
224
223
  default: undefined;
225
224
  };
226
- }>, () => VNode<_$vue.RendererNode, _$vue.RendererElement, {
225
+ }>, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
227
226
  [key: string]: any;
228
- }>, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
227
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
229
228
  fallback: {
230
229
  type: PropType<(error: RouterError, resetError: () => void) => VNode>;
231
230
  required: true;
@@ -236,7 +235,7 @@ declare const RouterErrorBoundary: _$vue.DefineComponent<_$vue.ExtractPropTypes<
236
235
  };
237
236
  }>> & Readonly<{}>, {
238
237
  onError: (error: RouterError, toRoute: State | null, fromRoute: State | null) => void;
239
- }, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
238
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
240
239
  type RouterErrorBoundaryProps = InstanceType<typeof RouterErrorBoundary>["$props"];
241
240
  //#endregion
242
241
  //#region src/directives/vLink.d.ts
@@ -277,12 +276,29 @@ interface LinkProps<P extends Params = Params> {
277
276
  activeStrict?: boolean;
278
277
  ignoreQueryParams?: boolean;
279
278
  target?: string;
279
+ /**
280
+ * URL fragment (#532). Decoded, no leading `#`. Tri-state:
281
+ * - `undefined` (default) — preserves current `state.context.url.hash` on click.
282
+ * - `""` — clears the hash.
283
+ * - `"value"` — sets the hash; click routes through `navigateWithHash`,
284
+ * which auto-adds `force: true, hashChange: true` for same-route hash
285
+ * transitions (bypasses core's SAME_STATES check).
286
+ * Active state is hash-aware when `hash` is set.
287
+ */
288
+ hash?: string;
280
289
  }
281
290
  //#endregion
282
291
  //#region src/composables/useRoute.d.ts
283
- declare const useRoute: <P extends Params = Params>() => Omit<RouteContext<P>, "route"> & {
292
+ /**
293
+ * Return shape for `useRoute()` — `RouteContext<P>` with `route` narrowed
294
+ * to the non-nullable variant. The composable throws when `route.value`
295
+ * would be `undefined`, so consumers can read `.value.params.x` without a
296
+ * nullable guard. Extracted from inline duplication at two call sites.
297
+ */
298
+ type UseRouteReturn<P extends Params = Params> = Omit<RouteContext<P>, "route"> & {
284
299
  route: Readonly<Ref<State<P>>>;
285
300
  };
301
+ declare const useRoute: <P extends Params = Params>() => UseRouteReturn<P>;
286
302
  //#endregion
287
303
  //#region src/composables/useRouteNode.d.ts
288
304
  declare function useRouteNode(nodeName: string): RouteContext;
@@ -481,7 +497,7 @@ interface ScrollRestorationOptions {
481
497
  }
482
498
  //#endregion
483
499
  //#region src/RouterProvider.d.ts
484
- declare const RouterProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
500
+ declare const RouterProvider: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
485
501
  router: {
486
502
  type: PropType<Router>;
487
503
  required: true;
@@ -497,9 +513,9 @@ declare const RouterProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
497
513
  type: BooleanConstructor;
498
514
  default: boolean;
499
515
  };
500
- }>, () => _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
516
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
501
517
  [key: string]: any;
502
- }>[] | undefined, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
518
+ }>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
503
519
  router: {
504
520
  type: PropType<Router>;
505
521
  required: true;
@@ -518,12 +534,12 @@ declare const RouterProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
518
534
  }>> & Readonly<{}>, {
519
535
  announceNavigation: boolean;
520
536
  viewTransitions: boolean;
521
- }, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
537
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
522
538
  //#endregion
523
539
  //#region src/context.d.ts
524
540
  declare const RouterKey: InjectionKey<Router>;
525
541
  declare const NavigatorKey: InjectionKey<Navigator$1>;
526
542
  declare const RouteKey: InjectionKey<RouteContext>;
527
543
  //#endregion
528
- 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 };
544
+ export { Link, type LinkDirectiveValue, type LinkProps, type Navigator, NavigatorKey, type RouteContext, type RouteEnterContext, type RouteEnterHandler, type RouteExitContext, type RouteExitHandler, RouteKey, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, type SelfProps as RouteViewSelfProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterKey, RouterProvider, type RouterTransitionSnapshot, type UseRouteEnterOptions, type UseRouteExitOptions, createRouterPlugin, useNavigator, useRoute, useRouteEnter, useRouteExit, useRouteNode, useRouteUtils, useRouter, useRouterTransition, vLink };
529
545
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","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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"}
1
+ {"version":3,"file":"index.d.mts","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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"}
@@ -1,2 +1,2 @@
1
- import{Fragment as e,KeepAlive as t,Suspense as n,computed as r,defineComponent as i,h as a,inject as o,isVNode as s,markRaw as c,onScopeDispose as l,provide as u,shallowRef as d,watch as f}from"vue";import{UNKNOWN_ROUTE as p,getNavigator as m}from"@real-router/core";import{getRouteUtils as h,startsWithSegment as ee}from"@real-router/route-utils";import{createActiveRouteSource as te,createDismissableError as ne,createRouteNodeSource as re,createRouteSource as ie,getTransitionSource as ae}from"@real-router/sources";import{getPluginApi as oe}from"@real-router/core/api";function g(){return null}const _=i({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:g}),v=i({name:`RouteView.Self`,props:{fallback:{type:[Object,Function],default:void 0}},render:g}),y=i({name:`RouteView.NotFound`,render:g});function se(e,t,n){return n?e===t:ee(e,t)}function b(e){if(Array.isArray(e)){let t=[];for(let n of e)Array.isArray(n)?t.push(...b(n)):s(n)&&t.push(n);return t}return s(e)?[e]:[]}function x(t,n){let r=b(t);for(let t of r)t.type===_||t.type===v||t.type===y?n.push(t):t.type===e&&x(t.children,n)}function ce(e,t){return e.type===y?(t.notFoundChildren=e.children,!0):e.type===v?(t.selfVNode===null&&(t.selfVNode=e,t.selfFallback=e.props?.fallback),!0):!1}function le(e,t,n){let r=e.props,i=r?.segment??``,a=r?.exact??!1;return{isActive:se(t,n?`${n}.${i}`:i,a),fallback:r?.fallback}}function S(e,t,n,r,i){if(r.selfVNode!==null&&t===n)return e.push(r.selfVNode),r.selfFallback;if(t===p&&r.notFoundChildren!==null){let t=i.filter(e=>e.type===y).at(-1);t&&e.push(t)}}function ue(e,t,n){let r={selfVNode:null,selfFallback:void 0,notFoundChildren:null},i=!1,a,o=[];for(let s of e){if(ce(s,r)||i)continue;let e=le(s,t,n);e.isActive&&(i=!0,a=e.fallback,o.push(s))}return i||(a=S(o,t,n,r,e)),{rendered:o,activeMatchFound:i,fallback:a}}function C(e){let t=d(e.getSnapshot());return l(e.subscribe(()=>{t.value=e.getSnapshot()})),t}const w=Symbol(`RouterKey`),T=Symbol(`NavigatorKey`),E=Symbol(`RouteKey`),D=()=>{let e=o(w);if(!e)throw Error(`useRouter must be used within a RouterProvider`);return e};function O(e){let t=D(),n=C(re(t,e));return{navigator:m(t),route:r(()=>n.value.route),previousRoute:r(()=>n.value.previousRoute)}}function k(e){return e.children?.default?.()??null}function A(e,t){let n=e.get(t);if(n)return n;let r=c(i({name:`KeepAlive-${t}`,setup(e,t){return()=>t.slots.default?.()}}));return e.set(t,r),r}function j(e,t){if(t===void 0)return e;let r=typeof t==`function`?t():t;return a(n,{},{default:()=>e,fallback:()=>r})}const de=c(i({name:`KeepAlive-placeholder`,render(){return null}}));function fe(e,n,r){let i=e.props?.segment??`__not-found__`,o=A(n,i),s=k(e)??[];return j(a(t,null,{default:()=>a(o,{key:i},{default:()=>s})}),r)}function M(e){return e===!0||e===``||e===`keep-alive`}function pe(n,r,i){let o=n.props;if(M(o?.keepAlive)&&n.type===_){let i=o?.segment??`__not-found__`,s=A(r,i),c=k(n)??[];return a(e,[a(t,null,{default:()=>a(s,{key:i},{default:()=>c})})])}let s=k(n);return s?a(e,[a(t,null,{default:()=>a(de)}),j(a(e,s),i)]):null}const me=i({name:`RouteView`,props:{nodeName:{type:String,required:!0},keepAlive:{type:Boolean,default:!1}},setup(t,{slots:n}){let r=O(t.nodeName),i=new Map,o=null,s=!1;function c(e,t){return t===o?s:(o=t,s=e.some(e=>e.type===_&&M(e.props?.keepAlive)),s)}return()=>{let o=r.route.value;if(!o)return null;let s=n.default?.(),l=[];x(s,l);let{rendered:u,fallback:d}=ue(l,o.name,t.nodeName);if(u.length===0)return null;let f=u[0];if(t.keepAlive)return fe(f,i,d);if(f.type!==_&&f.type!==v&&f.type!==y)return null;if(c(l,s))return pe(f,i,d);let p=k(f);return p?j(a(e,p),d):null}}}),N=Object.assign(me,{Match:_,Self:v,NotFound:y}),P=Object.freeze({}),F=Object.freeze({}),I=`data-real-router-announcer`;function L(e,t){let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=R(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),ge(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=he(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),z()}}}function R(){let e=document.querySelector(`[${I}]`);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(I,``),document.body.prepend(t),t}function z(){document.querySelector(`[${I}]`)?.remove()}function he(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 ge(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const B=Object.freeze({destroy:()=>{}});function _e(e,t){if(globalThis.window===void 0)return B;let n=t?.mode??`restore`;if(n===`native`)return B;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=t?.behavior??`auto`,o=t?.storageKey??`real-router:scroll`,s=()=>{try{let e=sessionStorage.getItem(o);return e?JSON.parse(e):{}}catch{return{}}},c=(e,t)=>{try{let n=s();n[e]=t,sessionStorage.setItem(o,JSON.stringify(n))}catch{}},l=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let u=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},d=e=>{let t=i?.();t?t.scrollTo({top:e,left:0,behavior:a}):globalThis.scrollTo({top:e,left:0,behavior:a})},f=e=>{let t=e.context?.url?.hash;if(t!==void 0){if(r&&t.length>0){let e=document.getElementById(t);if(e){e.scrollIntoView({behavior:a});return}}d(0);return}let n=globalThis.location.hash;if(r&&n.length>1){let e;try{e=decodeURIComponent(n.slice(1))}catch{e=n.slice(1)}let t=document.getElementById(e);if(t){t.scrollIntoView({behavior:a});return}}d(0)},p=!1,m=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;t&&c(V(t),u()),requestAnimationFrame(()=>{if(!p){if(n===`top`||!r){f(e);return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){d(s()[V(e)]??0);return}f(e)}}})}),h=()=>{let t=e.getState();t&&c(V(t),u())};return globalThis.addEventListener(`pagehide`,h),{destroy:()=>{if(!p){p=!0,m(),globalThis.removeEventListener(`pagehide`,h);try{history.scrollRestoration=l}catch{}}}}}function V(e){return`${e.name}:${ve(e.params)}`}function ve(e){return JSON.stringify(e,ye)}function ye(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 be=Object.freeze({destroy:()=>{}});function xe(e){if(typeof document>`u`||typeof document.startViewTransition!=`function`)return be;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 H(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}function Se(e){return encodeURI(e).replaceAll(`#`,`%23`)}function Ce(e,t,n,r){try{let i=r?.hash,a;i!==void 0&&(a=i.startsWith(`#`)?i.slice(1):i);let o=e.buildUrl;if(o){let e=o(t,n,a===void 0?void 0:{hash:a});if(e!==void 0)return e}let s=e.buildPath(t,n);return a?`${s}#${Se(a)}`:s}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function we(e,t,n,r,i){let a={...i};r!==void 0&&(a.hash=r);let o=e.getState();if(o?.name===t&&Ee(o.params,n)){let e=o.context?.url?.hash??``;e!==(r??e)&&(a.force=!0,a.hashChange=!0)}return e.navigate(t,n,a)}function U(e){return e?e.match(/\S+/g)??[]:[]}function Te(e,t,n){if(e&&t){let e=U(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=U(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 Ee(e,t){if(Object.is(e,t))return!0;if(!e||!t)return!1;let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;let r=e,i=t;for(let e of n)if(!Object.is(r[e],i[e]))return!1;return!0}function De(e){e&&(e instanceof HTMLAnchorElement||e instanceof HTMLButtonElement||(e.hasAttribute(`role`)||e.setAttribute(`role`,`link`),e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`0`)))}function Oe(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 ke=i({name:`Link`,inheritAttrs:!1,props:{routeName:{type:String,required:!0},routeParams:{type:Object,default:()=>P},routeOptions:{type:Object,default:()=>F},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},hash:{type:String,default:void 0}},setup(e,{slots:t,attrs:n}){let i=D(),o=d(!1);f(()=>[e.routeName,e.routeParams,e.activeStrict,e.ignoreQueryParams,e.hash],([e,t,n,r,a],s,c)=>{let l=te(i,e,t,a===void 0?{strict:n,ignoreQueryParams:r}:{strict:n,ignoreQueryParams:r,hash:a});o.value=l.getSnapshot(),c(l.subscribe(()=>{o.value=l.getSnapshot()}))},{immediate:!0,flush:`sync`});let s=r(()=>Ce(i,e.routeName,e.routeParams,e.hash===void 0?void 0:{hash:e.hash})),c=r(()=>Te(o.value,e.activeClassName,e.class)),l=t=>{n.onClick!==void 0&&n.onClick!==null&&(Oe(n.onClick,t),t.defaultPrevented)||!H(t)||e.target===`_blank`||(t.preventDefault(),we(i,e.routeName,e.routeParams,e.hash,e.routeOptions).catch(()=>{}))};return()=>{let r={};for(let e of Object.keys(n))e!==`onClick`&&(r[e]=n[e]);return a(`a`,{...r,href:s.value,class:c.value,target:e.target,onClick:l},t.default?.())}}}),Ae=i({name:`RouterErrorBoundary`,props:{fallback:{type:Function,required:!0},onError:{type:Function,default:void 0}},setup(t,{slots:n}){let r=C(ne(D()));return f(()=>r.value.version,()=>{r.value.error&&t.onError?.(r.value.error,r.value.toRoute,r.value.fromRoute)},{immediate:!0}),()=>{let i=n.default?.()??[],o=r.value.error?t.fallback(r.value.error,r.value.resetError):null;return a(e,null,[...i,o])}}}),W=[];function G(e){return W.push(e),()=>{let t=W.lastIndexOf(e);t!==-1&&W.splice(t,1)}}function K(){let e=W.at(-1);if(!e)throw Error(`v-link directive requires a RouterProvider ancestor. Make sure RouterProvider is mounted.`);return e}const q=new WeakMap;function J(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 je(e,t){return n=>{H(n)&&(n.preventDefault(),e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{}))}}function Me(e,t,n){return r=>{r.key===`Enter`&&!(n instanceof HTMLButtonElement)&&e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{})}}function Y(e,t,n){let r=je(t,n),i=Me(t,n,e);e.addEventListener(`click`,r),e.addEventListener(`keydown`,i),q.set(e,{click:r,keydown:i})}function X(e){let t=q.get(e);t&&(e.removeEventListener(`click`,t.click),e.removeEventListener(`keydown`,t.keydown),q.delete(e))}const Z={mounted(e,t){let n=K();De(e),e.style.cursor=`pointer`,J(t.value)&&Y(e,n,t.value)},updated(e,t){let n=K();X(e),J(t.value)&&Y(e,n,t.value)},beforeUnmount(e){X(e)}},Ne=()=>{let e=o(T);if(!e)throw Error(`useNavigator must be used within a RouterProvider`);return e},Pe=()=>h(oe(D()).getTree()),Q=()=>{let e=o(E);if(!e)throw Error(`useRoute must be used within a RouterProvider`);if(!e.route.value)throw Error(`useRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?`);return e};function Fe(){return C(ae(D()))}function Ie(e,t){let n=D(),r=t?.skipSameRoute??!0;l(n.subscribeLeave(({route:t,nextRoute:n,signal:i})=>{if(!(r&&t.name===n.name)&&!i.aborted)return e({route:t,nextRoute:n,signal:i})}))}function Le(e,t){let{route:n,previousRoute:r}=Q(),i=t?.skipSameRoute??!0,a=null;f(n,t=>{let n=r.value;t.transition.from&&(i&&t.transition.from===t.name||a===t||!n||(a=t,e({route:t,previousRoute:n})))})}function $(e){let t=m(e),n=ie(e),r=n.getSnapshot(),i=d(r.route),a=d(r.previousRoute);return{navigator:t,route:i,previousRoute:a,unsubscribe:n.subscribe(()=>{let e=n.getSnapshot();i.value=e.route,a.value=e.previousRoute})}}function Re(e){return{install(t){let n=G(e),{navigator:r,route:i,previousRoute:a,unsubscribe:o}=$(e);`onUnmount`in t&&t.onUnmount(()=>{n(),o()}),t.provide(w,e),t.provide(T,r),t.provide(E,{navigator:r,route:i,previousRoute:a})}}}const ze=i({name:`RouterProvider`,props:{router:{type:Object,required:!0},announceNavigation:{type:Boolean,default:!1},scrollRestoration:{type:Object},viewTransitions:{type:Boolean,default:!1}},setup(e,{slots:t}){f(()=>[e.router,e.announceNavigation],([e,t],n,r)=>{if(!t)return;let i=L(e);r(()=>{i.destroy()})},{immediate:!0}),f(()=>[e.router,e.scrollRestoration!==void 0,e.scrollRestoration?.mode,e.scrollRestoration?.anchorScrolling,e.scrollRestoration?.behavior,e.scrollRestoration?.storageKey],([t,n,r,i,a,o],s,c)=>{if(!n)return;let l=_e(t,{mode:r,anchorScrolling:i,behavior:a,storageKey:o,scrollContainer:e.scrollRestoration?.scrollContainer});c(()=>{l.destroy()})},{immediate:!0}),f(()=>[e.router,e.viewTransitions],([e,t],n,r)=>{if(!t)return;let i=xe(e);r(()=>{i.destroy()})},{immediate:!0});let n=G(e.router),{navigator:r,route:i,previousRoute:a,unsubscribe:o}=$(e.router);return l(()=>{n(),o()}),u(w,e.router),u(T,r),u(E,{navigator:r,route:i,previousRoute:a}),()=>t.default?.()}});export{ke as Link,T as NavigatorKey,E as RouteKey,N as RouteView,Ae as RouterErrorBoundary,w as RouterKey,ze as RouterProvider,Re as createRouterPlugin,Ne as useNavigator,Q as useRoute,Le as useRouteEnter,Ie as useRouteExit,O as useRouteNode,Pe as useRouteUtils,D as useRouter,Fe as useRouterTransition,Z as vLink};
1
+ import{a as e,i as t,r as n,t as r}from"./useRoute-2ocUdDHc.mjs";import{Fragment as i,KeepAlive as a,Suspense as o,computed as s,defineComponent as c,h as l,inject as u,isVNode as d,markRaw as f,onScopeDispose as p,provide as m,shallowRef as h,watch as g}from"vue";import{UNKNOWN_ROUTE as _,getNavigator as v}from"@real-router/core";import{getRouteUtils as ee,startsWithSegment as te}from"@real-router/route-utils";import{canonicalJson as ne,createActiveRouteSource as re,createDismissableError as ie,createRouteNodeSource as ae,createRouteSource as oe,getTransitionSource as y}from"@real-router/sources";import{getPluginApi as se}from"@real-router/core/api";function b(){return null}const x=c({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:b}),S=c({name:`RouteView.Self`,props:{fallback:{type:[Object,Function],default:void 0}},render:b}),C=c({name:`RouteView.NotFound`,render:b});function ce(e,t,n){return n?e===t:te(e,t)}function w(e){return e===!0||e===``||e===`keep-alive`}function T(e){if(Array.isArray(e)){let t=[];for(let n of e)Array.isArray(n)?t.push(...T(n)):d(n)&&t.push(n);return t}return d(e)?[e]:[]}function E(e,t){let n=T(e);for(let e of n)e.type===x||e.type===S||e.type===C?t.push(e):e.type===i&&E(e.children,t)}function le(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 ue(e,t,n){let r=e.props,i=r?.segment??``,a=r?.exact??!1;return{isActive:ce(t,n?`${n}.${i}`:i,a),fallback:r?.fallback}}function de(e,t,n,r,i){if(r.selfVNode!==null&&t===n)return e.push(r.selfVNode),r.selfFallback;if(t===_&&r.notFoundChildren!==null){let t=i.filter(e=>e.type===C).at(-1);t&&e.push(t)}}function fe(e,t,n){let r={selfVNode:null,selfFallback:void 0,notFoundChildren:null},i=!1,a,o=!1,s=[];for(let c of e){if(!o&&c.type===x){let e=c.props;w(e?.keepAlive)&&(o=!0)}if(le(c,r)||i)continue;let e=ue(c,t,n);e.isActive&&(i=!0,a=e.fallback,s.push(c))}return i||(a=de(s,t,n,r,e)),{rendered:s,activeMatchFound:i,fallback:a,hasPerMatchKA:o}}function D(e){let t=h(e.getSnapshot());return p(e.subscribe(()=>{t.value=e.getSnapshot()})),t}const O=()=>{let t=u(e);if(!t)throw Error(`useRouter must be used within a RouterProvider`);return t};function k(e){let t=O(),n=D(ae(t,e));return{navigator:v(t),route:s(()=>n.value.route),previousRoute:s(()=>n.value.previousRoute)}}function A(e){return e.children?.default?.()??null}function j(e,t){let n=e.get(t);if(n)return n;let r=f(c({name:`KeepAlive-${t}`,setup(e,t){return()=>t.slots.default?.()}}));return e.set(t,r),r}function M(e,t){if(t===void 0)return e;let n=typeof t==`function`?t():t;return l(o,{},{default:()=>e,fallback:()=>n})}let N=null;function pe(){return N??=f(c({name:`KeepAlive-placeholder`,render(){return null}})),N}function me(e,t,n){let r=e.props?.segment??`__not-found__`,i=j(t,r),o=A(e)??[];return M(l(a,null,{default:()=>l(i,{key:r},{default:()=>o})}),n)}function P(e,t,n){let r=e.props;if(w(r?.keepAlive)&&e.type===x){let n=r?.segment??`__not-found__`,o=j(t,n),s=A(e)??[];return l(i,[l(a,null,{default:()=>l(o,{key:n},{default:()=>s})})])}let o=A(e);return o?l(i,[l(a,null,{default:()=>l(pe())}),M(l(i,o),n)]):null}const F=c({name:`RouteView`,props:{nodeName:{type:String,required:!0},keepAlive:{type:Boolean,default:!1}},setup(e,{slots:t}){let n=k(e.nodeName),r=new Map;return()=>{let a=n.route.value;if(!a)return null;let o=t.default?.(),s=[];E(o,s);let{rendered:c,fallback:u,hasPerMatchKA:d}=fe(s,a.name,e.nodeName);if(c.length===0)return null;let f=c[0];if(e.keepAlive)return me(f,r,u);if(f.type!==x&&f.type!==S&&f.type!==C)return null;if(d)return P(f,r,u);let p=A(f);return p?M(l(i,p),u):null}}}),I=Object.assign(F,{Match:x,Self:S,NotFound:C}),L=Object.freeze({}),R=Object.freeze({}),z=`data-real-router-announcer`,he=Object.freeze({destroy:()=>{}});function ge(e,t){if(typeof document>`u`)return he;let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=_e(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),be(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=ye(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),ve()}}}function _e(){let e=document.querySelector(`[${z}]`);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(z,``),(document.body??document.documentElement).prepend(t),t}function ve(){document.querySelector(`[${z}]`)?.remove()}function ye(e,t,n,r){if(n)try{let t=n(e);if(t)return t}catch(e){console.error(`[real-router] getAnnouncementText threw; falling back to default resolution.`,e)}let i=(r?.textContent??``).trim(),a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function be(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const B=Object.freeze({destroy:()=>{}});function xe(e,t){if(globalThis.window===void 0)return B;let n=t?.mode??`restore`;if(n===`native`)return B;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=t?.behavior??`auto`,o=t?.storageKey??`real-router:scroll`,s,c=()=>{if(s!==void 0)return s;try{let e=sessionStorage.getItem(o);s=e?JSON.parse(e):{}}catch{s={}}return s},l=(e,t)=>{try{let n=c();if(n[e]===t)return;n[e]=t,sessionStorage.setItem(o,JSON.stringify(n))}catch{}},u=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let d=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},f=e=>{let t=i?.();t?t.scrollTo({top:e,left:0,behavior:a}):globalThis.scrollTo({top:e,left:0,behavior:a})},p=e=>{let t=e.context?.url?.hash;if(t!==void 0){if(r&&t.length>0){let e=document.getElementById(t);if(e){e.scrollIntoView({behavior:a});return}}f(0);return}let n=globalThis.location.hash;if(r&&n.length>1){let e;try{e=decodeURIComponent(n.slice(1))}catch{e=n.slice(1)}let t=document.getElementById(e);if(t){t.scrollIntoView({behavior:a});return}}f(0)},m=!1,h=!1,g=e=>{try{return Se(e)}catch{return h||(h=!0,console.error(`[real-router] scroll-restore: route "${e.name}" has params that cannot be canonicalized (e.g. BigInt or cyclic structure). Scroll position will not be captured or restored for this route.`)),null}},_=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;if(t){let e=g(t);e!==null&&l(e,d())}requestAnimationFrame(()=>{if(!m){if(n===`top`){p(e);return}if(!(e.transition.replace||r?.navigationType===`replace`)){if(e.transition.reload||r?.navigationType===`reload`){let t=g(e);f(t===null?0:c()[t]??0);return}if(r?.direction===`back`||r?.navigationType===`traverse`){let t=g(e);f(t===null?0:c()[t]??0);return}p(e)}}})}),v=()=>{let t=e.getState();if(t){let e=g(t);e!==null&&l(e,d())}};return globalThis.addEventListener(`pagehide`,v),{destroy:()=>{if(!m){m=!0,_(),globalThis.removeEventListener(`pagehide`,v);try{history.scrollRestoration=u}catch{}}}}}const V=new WeakMap;function Se(e){let t=V.get(e);if(t!==void 0)return t;let n=`${e.name}:${Ce(e.params)}`;return V.set(e,n),n}function Ce(e){return JSON.stringify(e,we)}function we(e,t){if(typeof t==`function`)return`<fn>`;if(typeof t==`symbol`)return`<sym>`;if(typeof t==`object`&&t&&!Array.isArray(t)){let e=Object.create(null),n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}const Te=Object.freeze({destroy:()=>{}});function Ee(e){if(typeof document>`u`||typeof document.startViewTransition!=`function`)return Te;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 H(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}const U=/%[\dA-Fa-f]{2}/;function De(e){if(U.test(e))try{return encodeURI(decodeURIComponent(e)).replaceAll(`#`,`%23`)}catch{}return encodeURI(e).replaceAll(`#`,`%23`)}function Oe(e,t,n,r){try{let i=r?.hash,a;i!==void 0&&(a=i.startsWith(`#`)?i.slice(1):i);let o=e.buildUrl;if(o){let e=o(t,n,a===void 0?void 0:{hash:a});if(typeof e==`string`&&e.length>0)return e}let s=e.buildPath(t,n);if(typeof s!=`string`||s.length===0){console.error(`[real-router] Route "${t}" yielded an empty path. The element will render without an href attribute.`);return}return a?`${s}#${De(a)}`:s}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function ke(e,t,n,r,i){let a={...i};r!==void 0&&(a.hash=r);let o=e.getState();if(o?.name===t&&Ne(o.params,n)){let e=o.context?.url?.hash??``;e!==(r??e)&&(a.force=!0,a.hashChange=!0)}return e.navigate(t,n,a)}const Ae=/\s/,je=/\S+/g;function W(e){return e?Ae.test(e)?e.match(je)??[]:[e]:[]}function Me(e,t,n){if(e&&t){let e=W(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=W(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 Ne(e,t){if(Object.is(e,t))return!0;if(!e||!t)return!1;let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;let r=e,i=t;for(let e of n)if(!Object.prototype.hasOwnProperty.call(t,e)||!Object.is(r[e],i[e]))return!1;return!0}function Pe(e){if(!e)return;let t=e.tagName;t===`A`||t===`BUTTON`||(e.hasAttribute(`role`)||e.setAttribute(`role`,`link`),e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`0`))}function Fe(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 Ie=c({name:`Link`,inheritAttrs:!1,props:{routeName:{type:String,required:!0},routeParams:{type:Object,default:()=>L},routeOptions:{type:Object,default:()=>R},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},hash:{type:String,default:void 0}},setup(e,{slots:t,attrs:n}){let r=O(),i=h(!1);g(()=>[e.routeName,ne(e.routeParams),e.activeStrict,e.ignoreQueryParams,e.hash],([t,n,a,o,s],c,l)=>{let u=e.routeParams,d=re(r,t,u,s===void 0?{strict:a,ignoreQueryParams:o}:{strict:a,ignoreQueryParams:o,hash:s});i.value=d.getSnapshot(),l(d.subscribe(()=>{i.value=d.getSnapshot()}))},{immediate:!0,flush:`sync`});let a=s(()=>Oe(r,e.routeName,e.routeParams,e.hash===void 0?void 0:{hash:e.hash})),o=s(()=>Me(i.value,e.activeClassName,e.class)),c=t=>{n.onClick!==void 0&&n.onClick!==null&&(Fe(n.onClick,t),t.defaultPrevented)||!H(t)||e.target===`_blank`||(t.preventDefault(),ke(r,e.routeName,e.routeParams,e.hash,e.routeOptions).catch(()=>{}))};return()=>{let r={...n};return delete r.onClick,l(`a`,{...r,href:a.value,class:o.value,target:e.target,onClick:c},t.default?.())}}}),Le=c({name:`RouterErrorBoundary`,props:{fallback:{type:Function,required:!0},onError:{type:Function,default:void 0}},setup(e,{slots:t}){let n=D(ie(O()));return g(()=>n.value.version,()=>{n.value.error&&e.onError?.(n.value.error,n.value.toRoute,n.value.fromRoute)},{immediate:!0}),()=>{let r=t.default?.()??[],a=n.value.error?e.fallback(n.value.error,n.value.resetError):null;return l(i,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 Re(e,t){return n=>{H(n)&&(n.preventDefault(),e.navigate(t.name,t.params??{},t.options??{}).catch(()=>{}))}}function ze(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=Re(t,n),i=ze(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 Be={mounted(e,t){let n=q();Pe(e),e.style.cursor=`pointer`,Y(t.value)&&X(e,n,t.value)},updated(e,t){if(t.value===t.oldValue)return;let n=q();Z(e),Y(t.value)&&X(e,n,t.value)},beforeUnmount(e){Z(e)}},Ve=()=>{let e=u(n);if(!e)throw Error(`useNavigator must be used within a RouterProvider`);return e},He=()=>ee(se(O()).getTree());function Ue(){return D(y(O()))}function We(e,t){let n=O(),r=t?.skipSameRoute??!0;p(n.subscribeLeave(({route:t,nextRoute:n,signal:i})=>{if(!(r&&t.name===n.name)&&!i.aborted)return e({route:t,nextRoute:n,signal:i})}))}function Ge(e,t){let{route:n,previousRoute:i}=r(),a=t?.skipSameRoute??!0,o=null;g(n,t=>{let n=i.value;t.transition.from&&(a&&t.transition.from===t.name||o===t||!n||(o=t,e({route:t,previousRoute:n})))})}function Q(e){let t=v(e),n=oe(e),r=n.getSnapshot(),i=h(r.route),a=h(r.previousRoute);return{navigator:t,route:i,previousRoute:a,unsubscribe:n.subscribe(()=>{let e=n.getSnapshot();i.value=e.route,a.value=e.previousRoute})}}function Ke(r){return{install(i){let a=K(r),{navigator:o,route:s,previousRoute:c,unsubscribe:l}=Q(r);`onUnmount`in i&&i.onUnmount(()=>{a(),l()}),i.provide(e,r),i.provide(n,o),i.provide(t,{navigator:o,route:s,previousRoute:c})}}}function $(e,t){g(e,(e,n,r)=>{let i=t(e);i&&r(()=>{i.destroy()})},{immediate:!0})}const qe=c({name:`RouterProvider`,props:{router:{type:Object,required:!0},announceNavigation:{type:Boolean,default:!1},scrollRestoration:{type:Object},viewTransitions:{type:Boolean,default:!1}},setup(r,{slots:i}){$(()=>[r.router,r.announceNavigation],([e,t])=>t?ge(e):void 0),$(()=>[r.router,r.scrollRestoration!==void 0,r.scrollRestoration?.mode,r.scrollRestoration?.anchorScrolling,r.scrollRestoration?.behavior,r.scrollRestoration?.storageKey],([e,t,n,i,a,o])=>{if(t)return xe(e,{mode:n,anchorScrolling:i,behavior:a,storageKey:o,scrollContainer:r.scrollRestoration?.scrollContainer})}),$(()=>[r.router,r.viewTransitions],([e,t])=>t?Ee(e):void 0);let a=K(r.router),{navigator:o,route:s,previousRoute:c,unsubscribe:l}=Q(r.router);return p(()=>{a(),l()}),m(e,r.router),m(n,o),m(t,{navigator:o,route:s,previousRoute:c}),()=>i.default?.()}});export{Ie as Link,n as NavigatorKey,t as RouteKey,I as RouteView,Le as RouterErrorBoundary,e as RouterKey,qe as RouterProvider,Ke as createRouterPlugin,Ve as useNavigator,r as useRoute,Ge as useRouteEnter,We as useRouteExit,k as useRouteNode,He as useRouteUtils,O as useRouter,Ue as useRouterTransition,Be as vLink};
2
2
  //# sourceMappingURL=index.mjs.map