@esmx/router-vue 3.0.0-rc.70 → 3.0.0-rc.72

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/package.json CHANGED
@@ -50,19 +50,19 @@
50
50
  "vue": "^3.5.0 || ^2.7.0"
51
51
  },
52
52
  "dependencies": {
53
- "@esmx/router": "3.0.0-rc.70"
53
+ "@esmx/router": "3.0.0-rc.72"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@biomejs/biome": "1.9.4",
57
- "@types/node": "^24.0.0",
57
+ "@types/node": "^24.10.0",
58
58
  "@vitest/coverage-v8": "3.2.4",
59
- "typescript": "5.9.2",
60
- "unbuild": "3.6.0",
59
+ "typescript": "5.9.3",
60
+ "unbuild": "3.6.1",
61
61
  "vitest": "3.2.4",
62
- "vue": "3.5.13",
62
+ "vue": "3.5.23",
63
63
  "vue2": "npm:vue@2.7.16"
64
64
  },
65
- "version": "3.0.0-rc.70",
65
+ "version": "3.0.0-rc.72",
66
66
  "type": "module",
67
67
  "private": false,
68
68
  "exports": {
@@ -81,5 +81,5 @@
81
81
  "template",
82
82
  "public"
83
83
  ],
84
- "gitHead": "9aa452ae73e450d285e4ddbd35a4ac8b53427d95"
84
+ "gitHead": "e711cec0d8b1ac5aa4b9e3f3d0a6a994f22b3aa7"
85
85
  }
package/src/index.test.ts CHANGED
@@ -25,6 +25,16 @@ describe('index.ts - Package Entry Point', () => {
25
25
  expect(RouterVueModule.useLink).toBeDefined();
26
26
  expect(typeof RouterVueModule.useLink).toBe('function');
27
27
  });
28
+
29
+ it('should export useRouterViewDepth function', () => {
30
+ expect(RouterVueModule.useRouterViewDepth).toBeDefined();
31
+ expect(typeof RouterVueModule.useRouterViewDepth).toBe('function');
32
+ });
33
+
34
+ it('should export getRouterViewDepth function', () => {
35
+ expect(RouterVueModule.getRouterViewDepth).toBeDefined();
36
+ expect(typeof RouterVueModule.getRouterViewDepth).toBe('function');
37
+ });
28
38
  });
29
39
 
30
40
  describe('Options API Exports', () => {
@@ -74,6 +84,7 @@ describe('index.ts - Package Entry Point', () => {
74
84
  'useProvideRouter',
75
85
  'useLink',
76
86
  'useRouterViewDepth',
87
+ 'getRouterViewDepth',
77
88
  // Options API
78
89
  'getRouter',
79
90
  'getRoute',
@@ -100,6 +111,7 @@ describe('index.ts - Package Entry Point', () => {
100
111
  'useProvideRouter',
101
112
  'useLink',
102
113
  'useRouterViewDepth',
114
+ 'getRouterViewDepth',
103
115
  'getRouter',
104
116
  'getRoute',
105
117
  'RouterLink',
@@ -121,11 +133,15 @@ describe('index.ts - Package Entry Point', () => {
121
133
  // These should throw expected errors when called without proper context
122
134
  expect(() => {
123
135
  RouterVueModule.useRouter();
124
- }).toThrow('useRouter() can only be called during setup()');
136
+ }).toThrow(
137
+ '[@esmx/router-vue] Must be used within setup() or other composition functions'
138
+ );
125
139
 
126
140
  expect(() => {
127
141
  RouterVueModule.useRoute();
128
- }).toThrow('useRoute() can only be called during setup()');
142
+ }).toThrow(
143
+ '[@esmx/router-vue] Must be used within setup() or other composition functions'
144
+ );
129
145
 
130
146
  expect(() => {
131
147
  RouterVueModule.useLink({
@@ -133,31 +149,23 @@ describe('index.ts - Package Entry Point', () => {
133
149
  type: 'push',
134
150
  exact: 'include'
135
151
  });
136
- }).toThrow('useRouter() can only be called during setup()');
152
+ }).toThrow(
153
+ '[@esmx/router-vue] Must be used within setup() or other composition functions'
154
+ );
137
155
  });
138
156
 
139
157
  it('should have correct function signatures for Options API', () => {
140
158
  expect(() => {
141
- try {
142
- RouterVueModule.getRouter({} as Record<string, unknown>);
143
- } catch (error: unknown) {
144
- // Expected to throw context error when called without router
145
- expect((error as Error).message).toContain(
146
- 'Router context not found'
147
- );
148
- }
149
- }).not.toThrow();
159
+ RouterVueModule.getRouter({} as Record<string, unknown>);
160
+ }).toThrow(
161
+ '[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component.'
162
+ );
150
163
 
151
164
  expect(() => {
152
- try {
153
- RouterVueModule.getRoute({} as Record<string, unknown>);
154
- } catch (error: unknown) {
155
- // Expected to throw context error when called without router
156
- expect((error as Error).message).toContain(
157
- 'Router context not found'
158
- );
159
- }
160
- }).not.toThrow();
165
+ RouterVueModule.getRoute({} as Record<string, unknown>);
166
+ }).toThrow(
167
+ '[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component.'
168
+ );
161
169
  });
162
170
  });
163
171
 
@@ -200,7 +208,7 @@ describe('index.ts - Package Entry Point', () => {
200
208
  // Test plugin install signature - should throw for null input
201
209
  expect(() => {
202
210
  RouterPlugin.install(null);
203
- }).toThrow();
211
+ }).toThrow('[@esmx/router-vue] Invalid Vue app instance');
204
212
  });
205
213
  });
206
214
 
@@ -221,6 +229,8 @@ describe('index.ts - Package Entry Point', () => {
221
229
  'useRoute',
222
230
  'useProvideRouter',
223
231
  'useLink',
232
+ 'useRouterViewDepth',
233
+ 'getRouterViewDepth',
224
234
  'getRouter',
225
235
  'getRoute'
226
236
  ];
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ export {
7
7
  useProvideRouter,
8
8
  useLink,
9
9
  useRouterViewDepth,
10
+ getRouterViewDepth,
10
11
  getRoute,
11
12
  getRouter
12
13
  } from './use';
@@ -45,7 +45,7 @@ describe('plugin.ts - RouterPlugin', () => {
45
45
  router = new Router({
46
46
  mode: RouterMode.memory,
47
47
  routes,
48
- base: new URL('http://localhost:3000/')
48
+ base: new URL('http://localhost:8000/')
49
49
  });
50
50
 
51
51
  await router.replace('/');
@@ -88,13 +88,13 @@ describe('plugin.ts - RouterPlugin', () => {
88
88
  it('should throw error for null app instance', () => {
89
89
  expect(() => {
90
90
  RouterPlugin.install(null);
91
- }).toThrow();
91
+ }).toThrow('[@esmx/router-vue] Invalid Vue app instance');
92
92
  });
93
93
 
94
94
  it('should throw error for undefined app instance', () => {
95
95
  expect(() => {
96
96
  RouterPlugin.install(undefined);
97
- }).toThrow();
97
+ }).toThrow('[@esmx/router-vue] Invalid Vue app instance');
98
98
  });
99
99
  });
100
100
 
package/src/plugin.ts CHANGED
@@ -71,6 +71,10 @@ export const RouterPlugin = {
71
71
  * @param app Vue application instance (Vue 3) or Vue constructor (Vue 2)
72
72
  */
73
73
  install(app: unknown): void {
74
+ if (!app) {
75
+ throw new Error('[@esmx/router-vue] Invalid Vue app instance');
76
+ }
77
+
74
78
  const vueApp = app as VueApp;
75
79
  const target = vueApp.config?.globalProperties || vueApp.prototype;
76
80
 
@@ -52,7 +52,7 @@ describe('router-link.ts - RouterLink Component', () => {
52
52
  root: '#test-app',
53
53
  routes,
54
54
  mode: RouterMode.memory,
55
- base: new URL('http://localhost:3000/')
55
+ base: new URL('http://localhost:8000/')
56
56
  });
57
57
 
58
58
  // Initialize router and wait for it to be ready
@@ -80,7 +80,7 @@ describe('router-view.ts - RouterView Component', () => {
80
80
  root: '#test-app',
81
81
  routes,
82
82
  mode: RouterMode.memory,
83
- base: new URL('http://localhost:3000/')
83
+ base: new URL('http://localhost:8000/')
84
84
  });
85
85
 
86
86
  // Initialize router to root path and wait for it to be ready
@@ -201,7 +201,7 @@ describe('router-view.ts - RouterView Component', () => {
201
201
  root: '#test-app',
202
202
  routes,
203
203
  mode: RouterMode.memory,
204
- base: new URL('http://localhost:3000/')
204
+ base: new URL('http://localhost:8000/')
205
205
  });
206
206
 
207
207
  // Initialize the router and wait for it to be ready
@@ -334,7 +334,7 @@ describe('router-view.ts - RouterView Component', () => {
334
334
  root: '#test-app',
335
335
  routes: nestedRoutes,
336
336
  mode: RouterMode.memory,
337
- base: new URL('http://localhost:3000/')
337
+ base: new URL('http://localhost:8000/')
338
338
  });
339
339
 
340
340
  // Initialize the router and wait for it to be ready
@@ -411,7 +411,7 @@ describe('router-view.ts - RouterView Component', () => {
411
411
  root: '#test-app',
412
412
  routes: routesWithNull,
413
413
  mode: RouterMode.memory,
414
- base: new URL('http://localhost:3000/')
414
+ base: new URL('http://localhost:8000/')
415
415
  });
416
416
 
417
417
  // Initialize the router and wait for it to be ready
@@ -451,7 +451,7 @@ describe('router-view.ts - RouterView Component', () => {
451
451
  }
452
452
  ],
453
453
  mode: RouterMode.memory,
454
- base: new URL('http://localhost:3000/')
454
+ base: new URL('http://localhost:8000/')
455
455
  });
456
456
 
457
457
  // Initialize router with root path
@@ -504,7 +504,7 @@ describe('router-view.ts - RouterView Component', () => {
504
504
  root: '#test-app',
505
505
  routes: malformedRoutes,
506
506
  mode: RouterMode.memory,
507
- base: new URL('http://localhost:3000/')
507
+ base: new URL('http://localhost:8000/')
508
508
  });
509
509
 
510
510
  // Initialize the router and wait for it to be ready
package/src/use.test.ts CHANGED
@@ -4,8 +4,15 @@ import { type Route, Router, RouterMode } from '@esmx/router';
4
4
  */
5
5
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
6
  import { nextTick } from 'vue';
7
- import { createApp, h } from 'vue';
8
- import { useProvideRouter, useRoute, useRouter } from './use';
7
+ import { createApp, defineComponent, getCurrentInstance, h } from 'vue';
8
+ import { RouterView } from './router-view';
9
+ import {
10
+ getRouterViewDepth,
11
+ useProvideRouter,
12
+ useRoute,
13
+ useRouter,
14
+ useRouterViewDepth
15
+ } from './use';
9
16
 
10
17
  describe('Router Vue Integration', () => {
11
18
  let app: ReturnType<typeof createApp>;
@@ -22,7 +29,7 @@ describe('Router Vue Integration', () => {
22
29
  { path: '/user/:id', component: {} },
23
30
  { path: '/new-path', component: {} }
24
31
  ],
25
- base: new URL('http://localhost:3000/')
32
+ base: new URL('http://localhost:8000/')
26
33
  });
27
34
 
28
35
  // Ensure navigation to initial route is complete
@@ -214,4 +221,259 @@ describe('Router Vue Integration', () => {
214
221
  expect(childRoute?.path).toBe('/new-path');
215
222
  });
216
223
  });
224
+
225
+ describe('RouterView Depth', () => {
226
+ it('should get depth in single RouterView', async () => {
227
+ let observedDepth: number | undefined;
228
+
229
+ const LeafProbe = defineComponent({
230
+ setup() {
231
+ const p = getCurrentInstance()!.proxy as any;
232
+ observedDepth = getRouterViewDepth(p);
233
+ return () => h('div');
234
+ }
235
+ });
236
+
237
+ const Level1 = defineComponent({
238
+ setup() {
239
+ return () => h('div', [h(LeafProbe)]);
240
+ }
241
+ });
242
+
243
+ router = new Router({
244
+ mode: RouterMode.memory,
245
+ routes: [{ path: '/level1', component: Level1 }],
246
+ base: new URL('http://localhost:8000/')
247
+ });
248
+
249
+ await router.replace('/level1');
250
+
251
+ const TestApp = defineComponent({
252
+ setup() {
253
+ useProvideRouter(router);
254
+ return () => h('div', [h(RouterView)]);
255
+ }
256
+ });
257
+
258
+ app = createApp(TestApp);
259
+ app.mount('#app');
260
+ await nextTick();
261
+
262
+ expect(observedDepth).toBe(1);
263
+ });
264
+
265
+ it('should get depth in nested RouterView', async () => {
266
+ let observedDepth: number | undefined;
267
+
268
+ const LeafProbe = defineComponent({
269
+ setup() {
270
+ const p = getCurrentInstance()!.proxy as any;
271
+ observedDepth = getRouterViewDepth(p);
272
+ return () => h('div');
273
+ }
274
+ });
275
+
276
+ const Level1 = defineComponent({
277
+ setup() {
278
+ return () => h('div', [h(RouterView)]);
279
+ }
280
+ });
281
+
282
+ const Leaf = defineComponent({
283
+ setup() {
284
+ return () => h('div', [h(LeafProbe)]);
285
+ }
286
+ });
287
+
288
+ router = new Router({
289
+ mode: RouterMode.memory,
290
+ routes: [
291
+ {
292
+ path: '/level1',
293
+ component: Level1,
294
+ children: [{ path: 'leaf', component: Leaf }]
295
+ }
296
+ ],
297
+ base: new URL('http://localhost:8000/')
298
+ });
299
+
300
+ await router.replace('/level1/leaf');
301
+
302
+ const TestApp = defineComponent({
303
+ setup() {
304
+ useProvideRouter(router);
305
+ return () => h('div', [h(RouterView)]);
306
+ }
307
+ });
308
+
309
+ app = createApp(TestApp);
310
+ app.mount('#app');
311
+ await nextTick();
312
+
313
+ expect(observedDepth).toBe(2);
314
+ });
315
+
316
+ it('should get depth in double-nested RouterViews', async () => {
317
+ let observedDepth: number | undefined;
318
+
319
+ const LeafProbe = defineComponent({
320
+ setup() {
321
+ const p = getCurrentInstance()!.proxy as any;
322
+ observedDepth = getRouterViewDepth(p);
323
+ return () => h('div');
324
+ }
325
+ });
326
+
327
+ const Level1 = defineComponent({
328
+ setup() {
329
+ return () => h('div', [h(RouterView)]);
330
+ }
331
+ });
332
+
333
+ const Level2 = defineComponent({
334
+ setup() {
335
+ return () => h('div', [h(RouterView)]);
336
+ }
337
+ });
338
+
339
+ const Leaf = defineComponent({
340
+ setup() {
341
+ return () => h('div', [h(LeafProbe)]);
342
+ }
343
+ });
344
+
345
+ router = new Router({
346
+ mode: RouterMode.memory,
347
+ routes: [
348
+ {
349
+ path: '/level1',
350
+ component: Level1,
351
+ children: [
352
+ {
353
+ path: 'level2',
354
+ component: Level2,
355
+ children: [{ path: 'leaf', component: Leaf }]
356
+ }
357
+ ]
358
+ }
359
+ ],
360
+ base: new URL('http://localhost:8000/')
361
+ });
362
+
363
+ await router.replace('/level1/level2/leaf');
364
+
365
+ const TestApp = defineComponent({
366
+ setup() {
367
+ useProvideRouter(router);
368
+ return () => h('div', [h(RouterView)]);
369
+ }
370
+ });
371
+
372
+ app = createApp(TestApp);
373
+ app.mount('#app');
374
+ await nextTick();
375
+
376
+ expect(observedDepth).toBe(3);
377
+ });
378
+
379
+ it('should throw when no RouterView ancestor exists', async () => {
380
+ let callDepth: (() => void) | undefined;
381
+
382
+ const Probe = defineComponent({
383
+ setup() {
384
+ const p = getCurrentInstance()!.proxy as any;
385
+ callDepth = () => getRouterViewDepth(p);
386
+ return () => h('div');
387
+ }
388
+ });
389
+
390
+ const TestApp = defineComponent({
391
+ setup() {
392
+ useProvideRouter(router);
393
+ return () => h(Probe);
394
+ }
395
+ });
396
+
397
+ app = createApp(TestApp);
398
+ app.mount('#app');
399
+ await nextTick();
400
+
401
+ expect(() => callDepth!()).toThrow(
402
+ new Error(
403
+ '[@esmx/router-vue] RouterView depth not found. Please ensure a RouterView exists in ancestor components.'
404
+ )
405
+ );
406
+ });
407
+
408
+ it('should return 0 for useRouterViewDepth without RouterView', async () => {
409
+ let observed = -1;
410
+
411
+ const Probe = defineComponent({
412
+ setup() {
413
+ observed = useRouterViewDepth();
414
+ return () => h('div');
415
+ }
416
+ });
417
+
418
+ const TestApp = defineComponent({
419
+ setup() {
420
+ useProvideRouter(router);
421
+ return () => h(Probe);
422
+ }
423
+ });
424
+
425
+ app = createApp(TestApp);
426
+ app.mount('#app');
427
+ await nextTick();
428
+
429
+ expect(observed).toBe(0);
430
+ });
431
+
432
+ it('should reflect depth via useRouterViewDepth at each level', async () => {
433
+ let level1Depth = -1;
434
+ let level2Depth = -1;
435
+
436
+ const Level2 = defineComponent({
437
+ setup() {
438
+ level2Depth = useRouterViewDepth();
439
+ return () => h('div');
440
+ }
441
+ });
442
+
443
+ const Level1 = defineComponent({
444
+ setup() {
445
+ level1Depth = useRouterViewDepth();
446
+ return () => h('div', [h(RouterView)]);
447
+ }
448
+ });
449
+
450
+ router = new Router({
451
+ mode: RouterMode.memory,
452
+ routes: [
453
+ {
454
+ path: '/level1',
455
+ component: Level1,
456
+ children: [{ path: 'level2', component: Level2 }]
457
+ }
458
+ ],
459
+ base: new URL('http://localhost:8000/')
460
+ });
461
+
462
+ await router.replace('/level1/level2');
463
+
464
+ const TestApp = defineComponent({
465
+ setup() {
466
+ useProvideRouter(router);
467
+ return () => h('div', [h(RouterView)]);
468
+ }
469
+ });
470
+
471
+ app = createApp(TestApp);
472
+ app.mount('#app');
473
+ await nextTick();
474
+
475
+ expect(level1Depth).toBe(1);
476
+ expect(level2Depth).toBe(2);
477
+ });
478
+ });
217
479
  });
package/src/use.ts CHANGED
@@ -24,21 +24,19 @@ const ROUTER_CONTEXT_KEY = Symbol('router-context');
24
24
  const ROUTER_INJECT_KEY = Symbol('router-inject');
25
25
  const ROUTER_VIEW_DEPTH_KEY = Symbol('router-view-depth');
26
26
 
27
- const ERROR_MESSAGES = {
28
- SETUP_ONLY: (fnName: string) =>
29
- `[@esmx/router-vue] ${fnName}() can only be called during setup()`,
30
- CONTEXT_NOT_FOUND:
31
- '[@esmx/router-vue] Router context not found. ' +
32
- 'Please ensure useProvideRouter() is called in a parent component.'
33
- } as const;
34
-
35
27
  const routerContextProperty =
36
28
  createSymbolProperty<RouterContext>(ROUTER_CONTEXT_KEY);
37
29
 
38
- function getCurrentProxy(functionName: string): VueInstance {
30
+ const routerViewDepthProperty = createSymbolProperty<number>(
31
+ ROUTER_VIEW_DEPTH_KEY
32
+ );
33
+
34
+ function getCurrentProxy(): VueInstance {
39
35
  const instance = getCurrentInstance();
40
36
  if (!instance || !instance.proxy) {
41
- throw new Error(ERROR_MESSAGES.SETUP_ONLY(functionName));
37
+ throw new Error(
38
+ '[@esmx/router-vue] Must be used within setup() or other composition functions'
39
+ );
42
40
  }
43
41
  return instance.proxy;
44
42
  }
@@ -46,7 +44,7 @@ function getCurrentProxy(functionName: string): VueInstance {
46
44
  function findRouterContext(vm?: VueInstance): RouterContext {
47
45
  // If no vm provided, try to get current instance
48
46
  if (!vm) {
49
- vm = getCurrentProxy('findRouterContext');
47
+ vm = getCurrentProxy();
50
48
  }
51
49
 
52
50
  let context = routerContextProperty.get(vm);
@@ -64,7 +62,9 @@ function findRouterContext(vm?: VueInstance): RouterContext {
64
62
  current = current.$parent;
65
63
  }
66
64
 
67
- throw new Error(ERROR_MESSAGES.CONTEXT_NOT_FOUND);
65
+ throw new Error(
66
+ '[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component.'
67
+ );
68
68
  }
69
69
 
70
70
  /**
@@ -143,7 +143,7 @@ export function getRoute(instance?: VueInstance): Route {
143
143
  * Get router context using the optimal method available.
144
144
  * First tries provide/inject (works in setup), then falls back to hierarchy traversal.
145
145
  */
146
- function useRouterContext(functionName: string): RouterContext {
146
+ function useRouterContext(): RouterContext {
147
147
  // First try to get context from provide/inject (works in setup)
148
148
  const injectedContext = inject<RouterContext>(ROUTER_INJECT_KEY);
149
149
  if (injectedContext) {
@@ -151,7 +151,7 @@ function useRouterContext(functionName: string): RouterContext {
151
151
  }
152
152
 
153
153
  // Fallback to component hierarchy traversal (works after mount)
154
- const proxy = getCurrentProxy(functionName);
154
+ const proxy = getCurrentProxy();
155
155
  return findRouterContext(proxy);
156
156
  }
157
157
 
@@ -188,7 +188,7 @@ function useRouterContext(functionName: string): RouterContext {
188
188
  * ```
189
189
  */
190
190
  export function useRouter(): Router {
191
- return useRouterContext('useRouter').router;
191
+ return useRouterContext().router;
192
192
  }
193
193
 
194
194
  /**
@@ -224,7 +224,7 @@ export function useRouter(): Router {
224
224
  * ```
225
225
  */
226
226
  export function useRoute(): Route {
227
- return useRouterContext('useRoute').route;
227
+ return useRouterContext().route;
228
228
  }
229
229
 
230
230
  /**
@@ -257,7 +257,7 @@ export function useRoute(): Route {
257
257
  * ```
258
258
  */
259
259
  export function useProvideRouter(router: Router): void {
260
- const proxy = getCurrentProxy('useProvideRouter');
260
+ const proxy = getCurrentProxy();
261
261
 
262
262
  const dep = ref(0);
263
263
 
@@ -313,13 +313,12 @@ export function useProvideRouter(router: Router): void {
313
313
  * ```
314
314
  */
315
315
  export function _useRouterViewDepth(isRender?: boolean): number {
316
- // Get current RouterView depth from parent RouterView (if any)
317
- // Default to 0 if no parent RouterView is found
318
316
  const depth = inject(ROUTER_VIEW_DEPTH_KEY, 0);
319
317
 
320
318
  if (isRender) {
321
- // Provide depth + 1 to child RouterView components
322
319
  provide(ROUTER_VIEW_DEPTH_KEY, depth + 1);
320
+ const proxy = getCurrentProxy();
321
+ routerViewDepthProperty.set(proxy, depth + 1);
323
322
  }
324
323
 
325
324
  return depth;
@@ -354,6 +353,26 @@ export function useRouterViewDepth(): number {
354
353
  return _useRouterViewDepth();
355
354
  }
356
355
 
356
+ /**
357
+ * Get injected RouterView depth from a Vue instance's ancestors.
358
+ * Traverses parent chain to find the value provided under ROUTER_VIEW_DEPTH_KEY.
359
+ *
360
+ * @param instance - Vue component instance to start from
361
+ * @returns Injected RouterView depth value from nearest ancestor
362
+ * @throws {Error} If no ancestor provided ROUTER_VIEW_DEPTH_KEY
363
+ */
364
+ export function getRouterViewDepth(instance: VueInstance): number {
365
+ let current = instance.$parent;
366
+ while (current) {
367
+ const value = routerViewDepthProperty.get(current);
368
+ if (typeof value === 'number') return value;
369
+ current = current.$parent;
370
+ }
371
+ throw new Error(
372
+ '[@esmx/router-vue] RouterView depth not found. Please ensure a RouterView exists in ancestor components.'
373
+ );
374
+ }
375
+
357
376
  /**
358
377
  * Create reactive link helpers for navigation elements.
359
378
  * Returns computed properties for link attributes, classes, and event handlers.