vue-multi-router 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { computed, defineComponent, getCurrentInstance, h, inject, onBeforeUnmount, provide, ref, shallowRef } from "vue";
1
+ import { computed, defineComponent, getCurrentInstance, h, inject, onBeforeUnmount, provide, shallowRef, watch } from "vue";
2
2
  import { RouterLink, RouterView, createRouter, routeLocationKey, routerKey, routerViewLocationKey, viewDepthKey } from "vue-router";
3
3
 
4
4
  //#region src/history/storage/types.ts
@@ -23,6 +23,8 @@ function flatMapMaybePromise(value, fn) {
23
23
  const STACK_STORAGE_PREFIX = "__multiRouter_stack_";
24
24
  const ACTIVE_CONTEXT_STORAGE_KEY = "__multiRouterActiveContext";
25
25
  const ACTIVE_HISTORY_CONTEXT_STORAGE_KEY = "__multiRouterActiveHistoryContext";
26
+ const CONTEXT_STACK_STORAGE_KEY = "__multiRouterContextStack";
27
+ const HISTORY_CONTEXT_STACK_STORAGE_KEY = "__multiRouterHistoryContextStack";
26
28
  var SessionStorageAdapter = class {
27
29
  getStackStorageKey(contextKey) {
28
30
  return `${STACK_STORAGE_PREFIX}${contextKey}`;
@@ -34,9 +36,7 @@ var SessionStorageAdapter = class {
34
36
  position: stack.position
35
37
  };
36
38
  sessionStorage.setItem(this.getStackStorageKey(contextKey), JSON.stringify(data));
37
- } catch (e) {
38
- console.warn("[SessionStorageAdapter] Failed to save stack:", e);
39
- }
39
+ } catch (e) {}
40
40
  }
41
41
  restoreStack(contextKey) {
42
42
  try {
@@ -50,24 +50,18 @@ var SessionStorageAdapter = class {
50
50
  position
51
51
  };
52
52
  }
53
- } catch (e) {
54
- console.warn("[SessionStorageAdapter] Failed to restore stack:", e);
55
- }
53
+ } catch (e) {}
56
54
  return null;
57
55
  }
58
56
  clearStack(contextKey) {
59
57
  try {
60
58
  sessionStorage.removeItem(this.getStackStorageKey(contextKey));
61
- } catch (e) {
62
- console.warn("[SessionStorageAdapter] Failed to clear stack:", e);
63
- }
59
+ } catch (e) {}
64
60
  }
65
61
  saveActiveContext(contextKey) {
66
62
  try {
67
63
  sessionStorage.setItem(ACTIVE_CONTEXT_STORAGE_KEY, contextKey);
68
- } catch (e) {
69
- console.warn("[SessionStorageAdapter] Failed to save active context:", e);
70
- }
64
+ } catch (e) {}
71
65
  }
72
66
  getActiveContext() {
73
67
  try {
@@ -76,12 +70,15 @@ var SessionStorageAdapter = class {
76
70
  return null;
77
71
  }
78
72
  }
73
+ clearActiveContext() {
74
+ try {
75
+ sessionStorage.removeItem(ACTIVE_CONTEXT_STORAGE_KEY);
76
+ } catch (e) {}
77
+ }
79
78
  saveActiveHistoryContext(contextKey) {
80
79
  try {
81
80
  sessionStorage.setItem(ACTIVE_HISTORY_CONTEXT_STORAGE_KEY, contextKey);
82
- } catch (e) {
83
- console.warn("[SessionStorageAdapter] Failed to save active history context:", e);
84
- }
81
+ } catch (e) {}
85
82
  }
86
83
  getActiveHistoryContext() {
87
84
  try {
@@ -90,21 +87,56 @@ var SessionStorageAdapter = class {
90
87
  return null;
91
88
  }
92
89
  }
90
+ clearActiveHistoryContext() {
91
+ try {
92
+ sessionStorage.removeItem(ACTIVE_HISTORY_CONTEXT_STORAGE_KEY);
93
+ } catch (e) {}
94
+ }
95
+ saveContextStack(stack) {
96
+ try {
97
+ sessionStorage.setItem(CONTEXT_STACK_STORAGE_KEY, JSON.stringify(stack));
98
+ } catch (e) {}
99
+ }
100
+ getContextStack() {
101
+ try {
102
+ const stored = sessionStorage.getItem(CONTEXT_STACK_STORAGE_KEY);
103
+ if (!stored) return [];
104
+ const parsed = JSON.parse(stored);
105
+ return Array.isArray(parsed) ? parsed : [];
106
+ } catch {
107
+ return [];
108
+ }
109
+ }
110
+ saveHistoryContextStack(stack) {
111
+ try {
112
+ sessionStorage.setItem(HISTORY_CONTEXT_STACK_STORAGE_KEY, JSON.stringify(stack));
113
+ } catch (e) {}
114
+ }
115
+ getHistoryContextStack() {
116
+ try {
117
+ const stored = sessionStorage.getItem(HISTORY_CONTEXT_STACK_STORAGE_KEY);
118
+ if (!stored) return [];
119
+ const parsed = JSON.parse(stored);
120
+ return Array.isArray(parsed) ? parsed : [];
121
+ } catch {
122
+ return [];
123
+ }
124
+ }
93
125
  };
94
126
 
95
127
  //#endregion
96
128
  //#region src/history/types.ts
97
- let NavigationType = /* @__PURE__ */ function(NavigationType$1) {
98
- NavigationType$1["pop"] = "pop";
99
- NavigationType$1["push"] = "push";
100
- return NavigationType$1;
101
- }({});
102
- let NavigationDirection = /* @__PURE__ */ function(NavigationDirection$1) {
103
- NavigationDirection$1["back"] = "back";
104
- NavigationDirection$1["forward"] = "forward";
105
- NavigationDirection$1["unknown"] = "";
106
- return NavigationDirection$1;
107
- }({});
129
+ var NavigationType = /* @__PURE__ */ ((NavigationType2) => {
130
+ NavigationType2["pop"] = "pop";
131
+ NavigationType2["push"] = "push";
132
+ return NavigationType2;
133
+ })(NavigationType || {});
134
+ var NavigationDirection = /* @__PURE__ */ ((NavigationDirection2) => {
135
+ NavigationDirection2["back"] = "back";
136
+ NavigationDirection2["forward"] = "forward";
137
+ NavigationDirection2["unknown"] = "";
138
+ return NavigationDirection2;
139
+ })(NavigationDirection || {});
108
140
 
109
141
  //#endregion
110
142
  //#region src/history/storage.ts
@@ -134,6 +166,24 @@ var VirtualStackStorage = class {
134
166
  getActiveHistoryContext() {
135
167
  return this.adapter.getActiveHistoryContext();
136
168
  }
169
+ clearActiveContext() {
170
+ return this.adapter.clearActiveContext();
171
+ }
172
+ clearActiveHistoryContext() {
173
+ return this.adapter.clearActiveHistoryContext();
174
+ }
175
+ saveContextStack(stack) {
176
+ return this.adapter.saveContextStack(stack);
177
+ }
178
+ getContextStack() {
179
+ return this.adapter.getContextStack();
180
+ }
181
+ saveHistoryContextStack(stack) {
182
+ return this.adapter.saveHistoryContextStack(stack);
183
+ }
184
+ getHistoryContextStack() {
185
+ return this.adapter.getHistoryContextStack();
186
+ }
137
187
  resolveValue = resolveValue;
138
188
  };
139
189
 
@@ -261,6 +311,24 @@ var VirtualStackManager = class {
261
311
  getStoredActiveHistoryContext() {
262
312
  return this.storage.getActiveHistoryContext();
263
313
  }
314
+ clearActiveContext() {
315
+ return this.storage.clearActiveContext();
316
+ }
317
+ clearActiveHistoryContext() {
318
+ return this.storage.clearActiveHistoryContext();
319
+ }
320
+ saveContextStack(stack) {
321
+ return this.storage.saveContextStack(stack);
322
+ }
323
+ getContextStack() {
324
+ return this.storage.getContextStack();
325
+ }
326
+ saveHistoryContextStack(stack) {
327
+ return this.storage.saveHistoryContextStack(stack);
328
+ }
329
+ getHistoryContextStack() {
330
+ return this.storage.getHistoryContextStack();
331
+ }
264
332
  entries() {
265
333
  return this.contexts.entries();
266
334
  }
@@ -308,6 +376,7 @@ var MultiRouterHistoryManager = class {
308
376
  stacks;
309
377
  activeHistoryContextKey = null;
310
378
  historyContextStack = [];
379
+ contextStack = [];
311
380
  baseHistoryCleanup = null;
312
381
  contextSwitchMode;
313
382
  onContextActivate;
@@ -317,6 +386,15 @@ var MultiRouterHistoryManager = class {
317
386
  this.contextSwitchMode = options?.contextSwitchMode ?? "replace";
318
387
  this.onContextActivate = options?.onContextActivate;
319
388
  this.baseHistoryCleanup = this.baseHistory.listen(this.handlePopState.bind(this));
389
+ this.restoreContextStacks();
390
+ }
391
+ restoreContextStacks() {
392
+ mapMaybePromise(this.stacks.getContextStack(), (stack) => {
393
+ this.contextStack = stack;
394
+ });
395
+ mapMaybePromise(this.stacks.getHistoryContextStack(), (stack) => {
396
+ this.historyContextStack = stack;
397
+ });
320
398
  }
321
399
  get base() {
322
400
  return this.baseHistory.base;
@@ -334,10 +412,6 @@ var MultiRouterHistoryManager = class {
334
412
  const isLastActive = lastActiveContext === contextKey;
335
413
  if (location) {
336
414
  const virtualStack = this.createInitialVirtualStack(location);
337
- console.debug("[MultiRouterHistory] Created context with forced location", {
338
- contextKey,
339
- location
340
- });
341
415
  return this.finalizeContextCreation(contextKey, virtualStack, isLastActive, historyEnabled);
342
416
  }
343
417
  return mapMaybePromise(this.stacks.restore(contextKey), (restoredStack) => {
@@ -349,31 +423,15 @@ var MultiRouterHistoryManager = class {
349
423
  location: browserUrl,
350
424
  state: this.baseHistory.state ?? {}
351
425
  };
352
- console.debug("[MultiRouterHistory] Restored from storage with browser URL", {
353
- contextKey,
354
- browserUrl
355
- });
356
- } else console.debug("[MultiRouterHistory] Restored from storage", {
357
- contextKey,
358
- historyEnabled
359
- });
426
+ }
360
427
  virtualStack = restoredStack;
361
428
  } else if (isLastActive && historyEnabled) {
362
429
  const browserUrl = this.baseHistory.location;
363
430
  virtualStack = this.createInitialVirtualStack(browserUrl);
364
- console.debug("[MultiRouterHistory] Created with browser URL (last active)", {
365
- contextKey,
366
- browserUrl
367
- });
368
- } else if (initialLocation) {
369
- virtualStack = this.createInitialVirtualStack(initialLocation);
370
- console.debug("[MultiRouterHistory] Created with initialLocation", {
371
- contextKey,
372
- initialLocation
373
- });
374
- } else {
375
- virtualStack = this.createInitialVirtualStack();
376
- console.debug("[MultiRouterHistory] Created with default location", { contextKey });
431
+ } else if (initialLocation) virtualStack = this.createInitialVirtualStack(initialLocation);
432
+ else {
433
+ const browserUrl = this.baseHistory.location;
434
+ virtualStack = this.createInitialVirtualStack(browserUrl);
377
435
  }
378
436
  return this.finalizeContextCreation(contextKey, virtualStack, isLastActive, historyEnabled);
379
437
  });
@@ -401,6 +459,9 @@ var MultiRouterHistoryManager = class {
401
459
  this.stacks.remove(contextKey);
402
460
  if (this.activeHistoryContextKey === contextKey) this.fallbackToPreviousHistoryContext();
403
461
  this.historyContextStack = this.historyContextStack.filter((k) => k !== contextKey);
462
+ this.stacks.saveHistoryContextStack(this.historyContextStack);
463
+ this.contextStack = this.contextStack.filter((k) => k !== contextKey);
464
+ this.stacks.saveContextStack(this.contextStack);
404
465
  }
405
466
  setActiveHistoryContext(contextKey) {
406
467
  if (!this.stacks.has(contextKey)) throw new Error(`[MultiRouterHistory] Context "${contextKey}" not registered`);
@@ -410,14 +471,12 @@ var MultiRouterHistoryManager = class {
410
471
  this.historyContextStack = this.historyContextStack.filter((k) => k !== previousKey);
411
472
  this.historyContextStack.push(previousKey);
412
473
  }
474
+ this.historyContextStack = this.historyContextStack.filter((k) => k !== contextKey);
475
+ this.stacks.saveHistoryContextStack(this.historyContextStack);
413
476
  this.activeHistoryContextKey = contextKey;
414
477
  this.stacks.saveActiveContext(contextKey);
415
478
  this.stacks.saveActiveHistoryContext(contextKey);
416
479
  this.restoreUrlFromVirtualStack(contextKey);
417
- console.debug("[MultiRouterHistory] setActiveHistoryContext", {
418
- from: previousKey,
419
- to: contextKey
420
- });
421
480
  }
422
481
  clearActiveHistoryContext(contextKey) {
423
482
  if (this.activeHistoryContextKey !== contextKey) return;
@@ -426,14 +485,57 @@ var MultiRouterHistoryManager = class {
426
485
  saveActiveContext(contextKey) {
427
486
  this.stacks.saveActiveContext(contextKey);
428
487
  }
488
+ /**
489
+ * Push the current active context to the context stack before switching to a new one.
490
+ * This allows fallback to the previous context when the current one is removed.
491
+ */
492
+ pushToContextStack(contextKey) {
493
+ this.contextStack = this.contextStack.filter((k) => k !== contextKey);
494
+ this.contextStack.push(contextKey);
495
+ this.stacks.saveContextStack(this.contextStack);
496
+ }
497
+ /**
498
+ * Get the previous context from the stack (for fallback when current context is removed).
499
+ * Returns null if no previous context exists.
500
+ */
501
+ popFromContextStack() {
502
+ const previousKey = this.contextStack.pop() ?? null;
503
+ this.stacks.saveContextStack(this.contextStack);
504
+ return previousKey;
505
+ }
506
+ /**
507
+ * Remove a context from the context stack (when the context is unregistered).
508
+ */
509
+ removeFromContextStack(contextKey) {
510
+ this.contextStack = this.contextStack.filter((k) => k !== contextKey);
511
+ this.stacks.saveContextStack(this.contextStack);
512
+ }
513
+ /**
514
+ * Clear the active context from storage (when no contexts are left).
515
+ */
516
+ clearActiveContext() {
517
+ this.stacks.clearActiveContext();
518
+ }
429
519
  getActiveHistoryContextKey() {
430
520
  return this.activeHistoryContextKey;
431
521
  }
432
522
  fallbackToPreviousHistoryContext() {
433
- const previousKey = this.historyContextStack.pop();
434
- if (previousKey && this.stacks.has(previousKey)) this.activeHistoryContextKey = previousKey;
435
- else this.activeHistoryContextKey = null;
436
- console.debug("[MultiRouterHistory] fallbackToPreviousHistoryContext", { to: this.activeHistoryContextKey });
523
+ let previousKey = this.historyContextStack.pop();
524
+ while (previousKey && !this.stacks.has(previousKey)) previousKey = this.historyContextStack.pop();
525
+ if (!previousKey) {
526
+ for (const [key, context] of this.stacks.entries()) if (context.historyEnabled) {
527
+ previousKey = key;
528
+ break;
529
+ }
530
+ }
531
+ if (previousKey && this.stacks.has(previousKey)) {
532
+ this.activeHistoryContextKey = previousKey;
533
+ this.stacks.saveActiveHistoryContext(previousKey);
534
+ } else {
535
+ this.activeHistoryContextKey = null;
536
+ this.stacks.clearActiveHistoryContext();
537
+ }
538
+ this.stacks.saveHistoryContextStack(this.historyContextStack);
437
539
  }
438
540
  createInitialVirtualStack(initialLocation) {
439
541
  return {
@@ -462,17 +564,6 @@ var MultiRouterHistoryManager = class {
462
564
  handlePopState(to, from, info) {
463
565
  const stateContextKey = this.baseHistory.state?.[CONTEXT_KEY_STATE];
464
566
  const stateStackIndex = this.baseHistory.state?.[STACK_INDEX_STATE];
465
- console.debug("[MultiRouterHistory] popstate raw", {
466
- stateContextKey,
467
- stateStackIndex,
468
- browserTo: to,
469
- browserFrom: from,
470
- delta: info.delta,
471
- virtualStacks: Object.fromEntries(Array.from(this.stacks.entries()).map(([k, v]) => [k, {
472
- position: v.virtualStack.position,
473
- entries: v.virtualStack.entries.map((e) => e.location)
474
- }]))
475
- });
476
567
  let ownerContextKey = null;
477
568
  let targetStackIndex = null;
478
569
  if (stateContextKey && this.stacks.has(stateContextKey)) {
@@ -490,15 +581,6 @@ var MultiRouterHistoryManager = class {
490
581
  const previousLocation = context.virtualStack.entries[context.virtualStack.position]?.location ?? from;
491
582
  this.stacks.setPosition(ownerContextKey, newPosition);
492
583
  const targetLocation = context.virtualStack.entries[newPosition]?.location ?? to;
493
- console.debug("[MultiRouterHistory] popstate result", {
494
- ownerContext: ownerContextKey,
495
- activeContext: this.activeHistoryContextKey,
496
- browserUrl: to,
497
- contextUrl: targetLocation,
498
- targetStackIndex: newPosition,
499
- previousLocation,
500
- delta: info.delta
501
- });
502
584
  if (this.onContextActivate) this.onContextActivate(ownerContextKey);
503
585
  this.stacks.notifyListeners(ownerContextKey, targetLocation, previousLocation, info);
504
586
  }
@@ -511,13 +593,6 @@ var MultiRouterHistoryManager = class {
511
593
  [CONTEXT_KEY_STATE]: contextKey,
512
594
  [STACK_INDEX_STATE]: stackIndex
513
595
  });
514
- console.debug("[MultiRouterHistory] push", {
515
- contextKey,
516
- to,
517
- stackIndex,
518
- isActive: this.activeHistoryContextKey === contextKey,
519
- historyEnabled
520
- });
521
596
  }
522
597
  replace(contextKey, to, data) {
523
598
  const stackIndex = this.stacks.replace(contextKey, to, data ?? {});
@@ -527,13 +602,6 @@ var MultiRouterHistoryManager = class {
527
602
  [CONTEXT_KEY_STATE]: contextKey,
528
603
  [STACK_INDEX_STATE]: stackIndex
529
604
  });
530
- console.debug("[MultiRouterHistory] replace", {
531
- contextKey,
532
- to,
533
- stackIndex,
534
- isActive: this.activeHistoryContextKey === contextKey,
535
- historyEnabled
536
- });
537
605
  }
538
606
  go(contextKey, delta, triggerListeners = true) {
539
607
  if (!this.stacks.has(contextKey)) throw new Error(`[MultiRouterHistory] Context "${contextKey}" not registered`);
@@ -575,23 +643,27 @@ var MultiRouterHistoryManager = class {
575
643
  //#endregion
576
644
  //#region src/contextManager.ts
577
645
  var MultiRouterManagerInstance = class {
578
- started = false;
579
- activeContext = shallowRef();
580
- activeHistoryContext = shallowRef();
581
- registered = /* @__PURE__ */ new Map();
582
- onContextInitListeners = [];
583
- historyManager;
584
- constructor(app, types, historyManagerOptions, makeRouter) {
585
- this.types = types;
646
+ constructor(app, historyManagerOptions, makeRouter) {
586
647
  this.makeRouter = makeRouter;
587
648
  const { historyBuilder, ...historyOptions } = historyManagerOptions;
588
649
  this.historyManager = new MultiRouterHistoryManager(historyBuilder, {
589
650
  ...historyOptions,
590
651
  onContextActivate: (contextKey) => {
591
652
  this.setActive(contextKey, false);
653
+ const context = this.registered.get(contextKey);
654
+ if (context?.historyEnabled && this.activeHistoryContext.value?.key !== contextKey) this.activeHistoryContext.value = {
655
+ key: contextKey,
656
+ context
657
+ };
592
658
  }
593
659
  });
594
660
  }
661
+ started = false;
662
+ activeContext = shallowRef();
663
+ activeHistoryContext = shallowRef();
664
+ registered = /* @__PURE__ */ new Map();
665
+ onContextInitListeners = [];
666
+ historyManager;
595
667
  getHistoryManager() {
596
668
  return this.historyManager;
597
669
  }
@@ -612,6 +684,8 @@ var MultiRouterManagerInstance = class {
612
684
  if (!item) throw new Error(`[MultiRouter] Context "${key}" not found`);
613
685
  let modified = false;
614
686
  if (this.activeContext.value?.key !== key) {
687
+ if (this.activeContext.value?.key) this.historyManager.pushToContextStack(this.activeContext.value.key);
688
+ this.historyManager.removeFromContextStack(key);
615
689
  this.activeContext.value = {
616
690
  key,
617
691
  context: item
@@ -625,11 +699,7 @@ var MultiRouterManagerInstance = class {
625
699
  this.historyManager.setActiveHistoryContext(key);
626
700
  }
627
701
  }
628
- if (modified) console.debug("[MultiRouterContextManager] setActive", {
629
- key,
630
- updateHistory,
631
- historyEnabled: item.historyEnabled
632
- });
702
+ if (modified) {}
633
703
  return modified;
634
704
  }
635
705
  clearHistoryContext(key) {
@@ -655,7 +725,6 @@ var MultiRouterManagerInstance = class {
655
725
  return this.registered.has(key);
656
726
  }
657
727
  register(type, key, options) {
658
- if (!this.types[type]) throw new Error(`[MultiRouter] Context type "${type}" not found`);
659
728
  const historyEnabled = options?.historyEnabled ?? true;
660
729
  const isDefault = options?.default ?? false;
661
730
  return mapMaybePromise(this.historyManager.createContextHistory(key, {
@@ -671,30 +740,20 @@ var MultiRouterManagerInstance = class {
671
740
  initialized: false,
672
741
  historyEnabled
673
742
  });
674
- router.push(history.location).catch((err) => {
675
- console.warn("Unexpected error when starting the router:", err);
676
- });
743
+ router.push(history.location).catch((err) => {});
677
744
  router.isReady().then(() => {
678
745
  this.markAsStarted();
679
746
  mapMaybePromise(this.historyManager.tryRestoreActiveHistoryContext(key), (restored) => {
680
- if (restored && !this.activeHistoryContext.value) {
681
- console.debug("[MultiRouterContextManager] Restored activeHistoryContext", { key });
682
- this.activeHistoryContext.value = {
683
- key,
684
- context: this.registered.get(key)
685
- };
686
- }
747
+ if (restored && !this.activeHistoryContext.value) this.activeHistoryContext.value = {
748
+ key,
749
+ context: this.registered.get(key)
750
+ };
687
751
  });
688
752
  mapMaybePromise(this.historyManager.getLastActiveContextKey(), (resolvedLastActiveKey) => {
689
- if (resolvedLastActiveKey === key && !this.activeContext.value) {
690
- console.debug("[MultiRouterContextManager] Auto-activating last active context", { key });
691
- this.setActive(key, true);
692
- } else if (isDefault && !resolvedLastActiveKey && !this.activeContext.value) {
693
- console.debug("[MultiRouterContextManager] Activating default context", {
694
- key,
695
- historyEnabled
696
- });
697
- this.setActive(key, true);
753
+ if (resolvedLastActiveKey === key && !this.activeContext.value) this.setActive(key, true);
754
+ else if (!this.activeContext.value) {
755
+ if (!(resolvedLastActiveKey && this.registered.has(resolvedLastActiveKey))) if (isDefault || !resolvedLastActiveKey) this.setActive(key, true);
756
+ else this.activateFromStackOrFallback(key);
698
757
  }
699
758
  });
700
759
  });
@@ -708,11 +767,41 @@ var MultiRouterManagerInstance = class {
708
767
  }
709
768
  unregister(key) {
710
769
  if (this.registered.get(key)) {
711
- console.debug("[MultiRouterContextManager] unregister", { key });
770
+ if (this.activeContext.value?.key === key) this.fallbackToPreviousContext();
771
+ if (this.activeHistoryContext.value?.key === key) this.clearHistoryContext(key);
712
772
  this.historyManager.removeContextHistory(key);
713
773
  this.registered.delete(key);
714
774
  }
715
775
  }
776
+ activateFromStackOrFallback(fallbackKey) {
777
+ if (this.activeContext.value) return;
778
+ let contextKey = this.historyManager.popFromContextStack();
779
+ while (contextKey && !this.registered.has(contextKey)) contextKey = this.historyManager.popFromContextStack();
780
+ if (!contextKey) contextKey = fallbackKey;
781
+ if (contextKey && this.registered.has(contextKey)) this.setActive(contextKey, true);
782
+ }
783
+ fallbackToPreviousContext() {
784
+ let previousKey = this.historyManager.popFromContextStack();
785
+ while (previousKey && !this.registered.has(previousKey)) previousKey = this.historyManager.popFromContextStack();
786
+ if (!previousKey) {
787
+ const historyContextKey = this.activeHistoryContext.value?.key;
788
+ if (historyContextKey && this.registered.has(historyContextKey)) previousKey = historyContextKey;
789
+ }
790
+ if (!previousKey && this.registered.size > 0) previousKey = this.registered.keys().next().value ?? null;
791
+ if (previousKey) {
792
+ const previousContext = this.registered.get(previousKey);
793
+ if (previousContext) {
794
+ this.activeContext.value = {
795
+ key: previousKey,
796
+ context: previousContext
797
+ };
798
+ this.historyManager.saveActiveContext(previousKey);
799
+ return;
800
+ }
801
+ }
802
+ this.activeContext.value = void 0;
803
+ this.historyManager.clearActiveContext();
804
+ }
716
805
  initialize(key) {
717
806
  this.registered.get(key).initialized = true;
718
807
  this.onContextInitListeners.forEach((fn) => fn(key));
@@ -725,13 +814,15 @@ var MultiRouterManagerInstance = class {
725
814
 
726
815
  //#endregion
727
816
  //#region src/symbols.ts
728
- const multiRouterContextManager = Symbol("multi-router-context-manager");
729
- const multiRouterContext = Symbol("multi-router-context-key");
817
+ const multiRouterContextManager = /* @__PURE__ */ Symbol("multi-router-context-manager");
818
+ const multiRouterContext = /* @__PURE__ */ Symbol("multi-router-context-key");
730
819
 
731
820
  //#endregion
732
821
  //#region src/injectionSymbols.ts
733
822
  const multiRouterContextManagerKey = multiRouterContextManager;
734
823
  const multiRouterContextKey = multiRouterContext;
824
+ const multiRouterContextActivateCallbacksKey = /* @__PURE__ */ Symbol("multi-router-context-activated-callbacks");
825
+ const multiRouterOriginalDepthKey = /* @__PURE__ */ Symbol();
735
826
 
736
827
  //#endregion
737
828
  //#region src/multi-router.ts
@@ -792,6 +883,24 @@ function installContextAwareRouterResolvers(app, contextManager) {
792
883
  Object.defineProperty(app.config.globalProperties, "$router", routerProperty);
793
884
  Object.defineProperty(app._context.provides, routeLocationKey, routeProperty);
794
885
  Object.defineProperty(app.config.globalProperties, "$route", routeProperty);
886
+ Object.defineProperty(app._context.provides, viewDepthKey, {
887
+ enumerable: true,
888
+ configurable: true,
889
+ get() {
890
+ const instance = getCurrentInstance$1();
891
+ const originalDepthRef = instance?.provides[multiRouterOriginalDepthKey];
892
+ return computed(() => {
893
+ const originalDepth = originalDepthRef?.value || 0;
894
+ const indexOfLastRoot = (instance?.provides[routerViewLocationKey].value).matched.findLastIndex((route) => route.meta.multiRouterRoot);
895
+ if (originalDepth < indexOfLastRoot) return indexOfLastRoot;
896
+ return originalDepth;
897
+ });
898
+ },
899
+ set(value) {
900
+ const instance = getCurrentInstance$1();
901
+ instance.provides[multiRouterOriginalDepthKey] = value;
902
+ }
903
+ });
795
904
  Object.defineProperty(app._context.provides, routerViewLocationKey, {
796
905
  enumerable: true,
797
906
  configurable: true,
@@ -807,32 +916,6 @@ function installComponents(app) {
807
916
  app.component("RouterLink", RouterLink);
808
917
  app.component("RouterView", RouterView);
809
918
  }
810
- const contextTemplateWindows = { window: {
811
- canUseAsHistoryContext: true,
812
- single: false
813
- } };
814
- const contextTemplateTabs = { tab: {
815
- canUseAsHistoryContext: true,
816
- single: false
817
- } };
818
- const contextTemplateMainWithWindows = {
819
- main: {
820
- canUseAsHistoryContext: true,
821
- single: true
822
- },
823
- ...contextTemplateWindows
824
- };
825
- const contextTemplateDesktopWithWindows = {
826
- desktop: {
827
- canUseAsHistoryContext: false,
828
- single: true
829
- },
830
- ...contextTemplateWindows
831
- };
832
- const contextTemplateTabsWithWindows = {
833
- ...contextTemplateTabs,
834
- ...contextTemplateWindows
835
- };
836
919
  function createMultiRouter(options) {
837
920
  let contextManager;
838
921
  return {
@@ -848,7 +931,7 @@ function createMultiRouter(options) {
848
931
  Object.assign(router, { contextKey });
849
932
  return router;
850
933
  };
851
- contextManager = new MultiRouterManagerInstance(app, options.types, {
934
+ contextManager = new MultiRouterManagerInstance(app, {
852
935
  historyBuilder: options.history,
853
936
  ...options.historyOptions
854
937
  }, makeRouter);
@@ -859,8 +942,76 @@ function createMultiRouter(options) {
859
942
  };
860
943
  }
861
944
 
945
+ //#endregion
946
+ //#region src/composables/useMultiRouter.ts
947
+ function useMultiRouter() {
948
+ const manager = inject(multiRouterContextManagerKey);
949
+ if (!manager) throw new Error("[useMultiRouter] Must be used within MultiRouterContextProvider");
950
+ const activeContextKey = computed(() => manager.getActiveContextRef().value?.key);
951
+ const activeHistoryContextKey = computed(() => manager.getActiveHistoryContextRef().value?.key);
952
+ const setActive = (contextKey, updateHistory = true) => {
953
+ manager.setActive(contextKey, updateHistory);
954
+ };
955
+ const hasContext = (contextKey) => {
956
+ return manager.has(contextKey);
957
+ };
958
+ return {
959
+ manager,
960
+ activeContextKey,
961
+ activeHistoryContextKey,
962
+ setActive,
963
+ hasContext
964
+ };
965
+ }
966
+
967
+ //#endregion
968
+ //#region src/composables/useMultiRouterContext.ts
969
+ function useMultiRouterContext() {
970
+ const { manager, activeContextKey, activeHistoryContextKey, setActive, hasContext } = useMultiRouter();
971
+ const contextKey = inject(multiRouterContextKey);
972
+ if (!contextKey) throw new Error("[useMultiRouterContext] Must be used within MultiRouterContext");
973
+ const isActive = computed(() => activeContextKey.value === contextKey);
974
+ const isHistoryActive = computed(() => activeHistoryContextKey.value === contextKey);
975
+ const historyEnabled = computed(() => manager.getContextHistoryEnabled(contextKey));
976
+ const activate = (updateHistory = true) => {
977
+ setActive(contextKey, updateHistory);
978
+ };
979
+ return {
980
+ manager,
981
+ contextKey,
982
+ isActive,
983
+ isHistoryActive,
984
+ activeContextKey,
985
+ activeHistoryContextKey,
986
+ historyEnabled,
987
+ activate,
988
+ setActive,
989
+ hasContext
990
+ };
991
+ }
992
+
993
+ //#endregion
994
+ //#region src/hooks.ts
995
+ function onMultiRouterContextActivate(callback) {
996
+ const { isActive, contextKey } = useMultiRouterContext();
997
+ const multiRouterActivateCallbacks = inject(multiRouterContextActivateCallbacksKey);
998
+ if (!multiRouterActivateCallbacks) return;
999
+ if (isActive.value) callback(contextKey);
1000
+ multiRouterActivateCallbacks.push(callback);
1001
+ onBeforeUnmount(() => {
1002
+ multiRouterActivateCallbacks.splice(multiRouterActivateCallbacks.indexOf(callback), 1);
1003
+ });
1004
+ }
1005
+
862
1006
  //#endregion
863
1007
  //#region src/components/MultiRouterContext.vue?vue&type=script&lang.ts
1008
+ function withContextActivateCallbacks(name, activeContextKey) {
1009
+ const multiRouterActivatedCallbacks = [];
1010
+ provide(multiRouterContextActivateCallbacksKey, multiRouterActivatedCallbacks);
1011
+ watch(activeContextKey, (newName) => {
1012
+ if (newName === name) multiRouterActivatedCallbacks.forEach((callback) => callback(name));
1013
+ });
1014
+ }
864
1015
  const MultiRouterContextInner = defineComponent({
865
1016
  name: "MultiRouterContextInner",
866
1017
  props: {
@@ -887,20 +1038,19 @@ const MultiRouterContextInner = defineComponent({
887
1038
  default: {
888
1039
  type: Boolean,
889
1040
  default: false
1041
+ },
1042
+ activator: {
1043
+ type: Boolean,
1044
+ default: true
1045
+ },
1046
+ preventClass: {
1047
+ type: String,
1048
+ default: null
890
1049
  }
891
1050
  },
892
1051
  setup(props, { slots }) {
893
- const manager = inject(multiRouterContextManagerKey);
894
- console.debug("[MultiRouterContext] setup", {
895
- type: props.type,
896
- name: props.name,
897
- location: props.location,
898
- initialLocation: props.initialLocation
899
- });
900
- if (manager.has(props.name)) {
901
- console.warn(`[MultiRouterContext] Context "${props.name}" already registered, skipping`);
902
- return () => slots.default?.();
903
- }
1052
+ const { manager, activeContextKey } = useMultiRouter();
1053
+ if (manager.has(props.name)) return () => slots.default?.();
904
1054
  manager.register(props.type, props.name, {
905
1055
  location: props.location,
906
1056
  initialLocation: props.initialLocation,
@@ -908,11 +1058,25 @@ const MultiRouterContextInner = defineComponent({
908
1058
  default: props.default
909
1059
  });
910
1060
  provide(multiRouterContext, props.name);
911
- provide(viewDepthKey, ref(0));
1061
+ withContextActivateCallbacks(props.name, activeContextKey);
912
1062
  onBeforeUnmount(() => {
913
1063
  manager.unregister(props.name);
914
1064
  });
915
- return () => slots.default?.();
1065
+ if (!props.activator) return () => slots.default?.();
1066
+ const onActivate = (e) => {
1067
+ e.stopPropagation();
1068
+ let shouldActivate = true;
1069
+ const target = e.target;
1070
+ if (props.preventClass && target?.closest("." + props.preventClass)) shouldActivate = false;
1071
+ if (shouldActivate) {
1072
+ if (manager.setActive(props.name, true)) {}
1073
+ }
1074
+ };
1075
+ return () => {
1076
+ const children = slots.default?.();
1077
+ if (children && children.length === 1) return h(children[0], { onMousedown: onActivate });
1078
+ return h("div", { onMousedown: onActivate }, children);
1079
+ };
916
1080
  }
917
1081
  });
918
1082
  var MultiRouterContext_vue_vue_type_script_lang_default = defineComponent({
@@ -941,6 +1105,14 @@ var MultiRouterContext_vue_vue_type_script_lang_default = defineComponent({
941
1105
  default: {
942
1106
  type: Boolean,
943
1107
  default: false
1108
+ },
1109
+ activator: {
1110
+ type: Boolean,
1111
+ default: true
1112
+ },
1113
+ preventClass: {
1114
+ type: String,
1115
+ default: null
944
1116
  }
945
1117
  },
946
1118
  setup(props, { slots }) {
@@ -951,7 +1123,9 @@ var MultiRouterContext_vue_vue_type_script_lang_default = defineComponent({
951
1123
  location: props.location,
952
1124
  initialLocation: props.initialLocation,
953
1125
  historyEnabled: props.historyEnabled,
954
- default: props.default
1126
+ default: props.default,
1127
+ activator: props.activator,
1128
+ preventClass: props.preventClass
955
1129
  }, slots.default);
956
1130
  }
957
1131
  });
@@ -963,26 +1137,35 @@ var MultiRouterContext_default = MultiRouterContext_vue_vue_type_script_lang_def
963
1137
  //#endregion
964
1138
  //#region src/components/MultiRouterContextActivator.vue?vue&type=script&lang.ts
965
1139
  var MultiRouterContextActivator_vue_vue_type_script_lang_default = defineComponent({
966
- props: { as: {
967
- type: String,
968
- default: null
969
- } },
1140
+ props: {
1141
+ as: {
1142
+ type: String,
1143
+ default: null
1144
+ },
1145
+ preventClass: {
1146
+ type: String,
1147
+ default: null,
1148
+ required: false
1149
+ }
1150
+ },
970
1151
  setup(props, { slots }) {
971
1152
  const contextKey = inject(multiRouterContextKey);
972
1153
  const manager = inject(multiRouterContextManagerKey);
973
- if (!contextKey || !manager) {
974
- console.warn("[MultiRouterContextActivator] Must be used within MultiRouterContext");
975
- return () => slots.default?.();
976
- }
1154
+ if (!contextKey || !manager) return () => slots.default?.();
977
1155
  const onActivate = (e) => {
978
1156
  e.stopPropagation();
979
- if (manager.setActive(contextKey, true)) console.debug("[MultiRouterContextActivator] activated", contextKey);
1157
+ let shouldActivate = true;
1158
+ const target = e.target;
1159
+ if (props.preventClass && target?.closest("." + props.preventClass)) shouldActivate = false;
1160
+ if (shouldActivate) {
1161
+ if (manager.setActive(contextKey, true)) {}
1162
+ }
980
1163
  };
981
1164
  return () => {
982
1165
  const children = slots.default?.();
983
1166
  if (!props.as) {
984
1167
  if (children && children.length === 1) return h(children[0], { onMousedown: onActivate });
985
- return h("span", { onMousedown: onActivate }, children);
1168
+ return h("div", { onMousedown: onActivate }, children);
986
1169
  }
987
1170
  return h(props.as, { onMousedown: onActivate }, children);
988
1171
  };
@@ -994,35 +1177,4 @@ var MultiRouterContextActivator_vue_vue_type_script_lang_default = defineCompone
994
1177
  var MultiRouterContextActivator_default = MultiRouterContextActivator_vue_vue_type_script_lang_default;
995
1178
 
996
1179
  //#endregion
997
- //#region src/composables/useMultiRouterContext.ts
998
- function useMultiRouterContext() {
999
- const manager = inject(multiRouterContextManagerKey);
1000
- const contextKey = inject(multiRouterContextKey);
1001
- if (!manager) throw new Error("[useMultiRouterContext] Must be used within MultiRouterContextProvider");
1002
- if (!contextKey) throw new Error("[useMultiRouterContext] Must be used within MultiRouterContext");
1003
- const router = computed(() => manager.getRouter(contextKey));
1004
- const route = computed(() => router.value.currentRoute.value);
1005
- const isActive = computed(() => manager.getActiveContextRef().value?.key === contextKey);
1006
- const activeContextKey = computed(() => manager.getActiveContextRef().value?.key);
1007
- const activeHistoryContextKey = computed(() => manager.getActiveHistoryContextRef().value?.key);
1008
- const isHistoryActive = computed(() => manager.getActiveHistoryContextRef().value?.key === contextKey);
1009
- const historyEnabled = computed(() => manager.getContextHistoryEnabled(contextKey));
1010
- const activate = (updateHistory = true) => {
1011
- manager.setActive(contextKey, updateHistory);
1012
- };
1013
- return {
1014
- manager,
1015
- contextKey,
1016
- router,
1017
- route,
1018
- isActive,
1019
- isHistoryActive,
1020
- activeContextKey,
1021
- activeHistoryContextKey,
1022
- historyEnabled,
1023
- activate
1024
- };
1025
- }
1026
-
1027
- //#endregion
1028
- export { MultiRouterContext_default as MultiRouterContext, MultiRouterContextActivator_default as MultiRouterContextActivator, contextTemplateDesktopWithWindows, contextTemplateMainWithWindows, contextTemplateTabs, contextTemplateTabsWithWindows, contextTemplateWindows, createMultiRouter, multiRouterContextKey, multiRouterContextManagerKey, useMultiRouterContext };
1180
+ export { MultiRouterContext_default as MultiRouterContext, MultiRouterContextActivator_default as MultiRouterContextActivator, createMultiRouter, multiRouterContextKey, multiRouterContextManagerKey, onMultiRouterContextActivate, useMultiRouter, useMultiRouterContext };