vue-multi-router 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # vue-multi-router
2
+
3
+ Vue 3 Multi Router that allows you to have multiple routers in your application.
4
+
5
+ [![npm downloads](https://img.shields.io/npm/dm/vue-multi-router.svg)](https://www.npmjs.com/package/vue-multi-router)
6
+ [![TypeScript](https://badgen.net/badge/icon/TypeScript?icon=typescript&label)](https://www.typescriptlang.org/)
7
+ [![Vue 3](https://img.shields.io/badge/vue-3.x-brightgreen.svg)](https://vuejs.org/)
8
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/vue-multi-router)](https://bundlephobia.com/package/vue-multi-router)
9
+ [![GitHub issues](https://img.shields.io/github/issues/lviobio/vue-multi-router)](https://github.com/lviobio/vue-multi-router/issues)
10
+ [![GitHub License](https://img.shields.io/github/license/lviobio/vue-multi-router)](https://github.com/lviobio/vue-multi-router)
11
+ ![CI](https://github.com/lviobio/vue-multi-router/actions/workflows/ci.yml/badge.svg)
12
+ ![Coverage](https://github.com/lviobio/vue-multi-router/actions/workflows/coverage.yml/badge.svg)
13
+ [![codecov](https://codecov.io/gh/lviobio/vue-multi-router/branch/main/graph/badge.svg)](https://codecov.io/gh/lviobio/vue-multi-router)
14
+ [![Live Demo](https://img.shields.io/badge/demo-live-brightgreen)](https://lviobio.github.io/vue-multi-router/)
15
+
16
+ ## Live Demo
17
+
18
+ 🚀 **[Try the interactive playground](https://lviobio.github.io/vue-multi-router)**
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install vue-multi-router
24
+ ```
25
+
26
+ ## Features
27
+
28
+ wip
29
+
30
+ ## Basic Usage
31
+
32
+ wip
33
+
34
+ ## API Reference
35
+
36
+ wip
37
+
38
+ ## Examples
39
+
40
+ wip
41
+
42
+ ## Peer Dependencies
43
+
44
+ - `vue`: ^3.5.0
45
+ - `vue-router`: ^4.0.0
46
+
47
+ ## License
48
+
49
+ MIT
50
+
51
+ ## Development
52
+
53
+ ### Running Playground Locally
54
+
55
+ ```bash
56
+ # Development mode (hot reload)
57
+ npm run play
58
+
59
+ # Production preview
60
+ npm run build:playground
61
+ npm run preview:playground
62
+ ```
63
+
64
+ ### Building
65
+
66
+ ```bash
67
+ # Build library
68
+ npm run build
69
+
70
+ # Build playground for deployment
71
+ npm run build:playground
72
+ ```
73
+
74
+ ### Testing & Quality
75
+
76
+ ```bash
77
+ # Run all checks
78
+ npm run check
79
+
80
+ # Type checking
81
+ npm run ts:check
82
+
83
+ # Linting
84
+ npm run lint
85
+
86
+ # Formatting
87
+ npm run format
88
+ ```
89
+
90
+ ## Contributing
91
+
92
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,356 @@
1
+ import * as vue6 from "vue";
2
+ import { App, InjectionKey, PropType } from "vue";
3
+ import * as vue_router0 from "vue-router";
4
+ import { Router, RouterHistory, RouterOptions } from "vue-router";
5
+
6
+ //#region src/history/types.d.ts
7
+ type HistoryLocation = string;
8
+ type HistoryState = Record<string, any>;
9
+ type HistoryBuilder = () => RouterHistory;
10
+ declare enum NavigationType {
11
+ pop = "pop",
12
+ push = "push",
13
+ }
14
+ declare enum NavigationDirection {
15
+ back = "back",
16
+ forward = "forward",
17
+ unknown = "",
18
+ }
19
+ interface NavigationInformation {
20
+ type: NavigationType;
21
+ direction: NavigationDirection;
22
+ delta: number;
23
+ }
24
+ interface NavigationCallback {
25
+ (to: HistoryLocation, from: HistoryLocation, information: NavigationInformation): void;
26
+ }
27
+ interface VirtualStackEntry {
28
+ location: HistoryLocation;
29
+ state: HistoryState;
30
+ }
31
+ interface VirtualStack {
32
+ entries: VirtualStackEntry[];
33
+ position: number;
34
+ }
35
+ //#endregion
36
+ //#region src/history/storage/types.d.ts
37
+ type MaybePromise<T> = T | Promise<T>;
38
+ interface StoredVirtualStack {
39
+ entries: Array<{
40
+ location: string;
41
+ state: Record<string, any>;
42
+ }>;
43
+ position: number;
44
+ }
45
+ interface ContextStorageAdapter {
46
+ saveStack(contextKey: string, stack: VirtualStack): MaybePromise<void>;
47
+ restoreStack(contextKey: string): MaybePromise<StoredVirtualStack | null>;
48
+ clearStack(contextKey: string): MaybePromise<void>;
49
+ saveActiveContext(contextKey: string): MaybePromise<void>;
50
+ getActiveContext(): MaybePromise<string | null>;
51
+ saveActiveHistoryContext(contextKey: string): MaybePromise<void>;
52
+ getActiveHistoryContext(): MaybePromise<string | null>;
53
+ }
54
+ //#endregion
55
+ //#region src/history/manager.d.ts
56
+ /**
57
+ * Defines how the browser URL is updated when switching between contexts.
58
+ *
59
+ * - `'none'`: URL is not updated when switching contexts. URL changes only on push/replace.
60
+ * This gives precise back/forward navigation matching the number of push operations.
61
+ *
62
+ * - `'replace'`: URL is updated using history.replace(). This changes the URL immediately
63
+ * but overwrites the current history entry's state. May cause issues with forward navigation
64
+ * if the previous context had unsaved state.
65
+ *
66
+ * - `'push'`: URL is updated using history.push() when the new context's URL differs from current.
67
+ * This preserves all history entries but adds extra back steps when switching between
68
+ * contexts with different URLs.
69
+ */
70
+ type ContextSwitchMode = 'none' | 'replace' | 'push';
71
+ interface MultiRouterHistoryManagerOptions {
72
+ /**
73
+ * Adapter for persisting context history state.
74
+ * @default SessionStorageAdapter
75
+ */
76
+ storageAdapter?: ContextStorageAdapter;
77
+ /**
78
+ * How to update browser URL when switching contexts.
79
+ * @default 'replace'
80
+ */
81
+ contextSwitchMode?: ContextSwitchMode;
82
+ /**
83
+ * Callback called when a popstate event requires activating a different context.
84
+ * This happens when navigating back/forward to a history entry owned by another context.
85
+ */
86
+ onContextActivate?: (contextKey: string) => void;
87
+ }
88
+ declare class MultiRouterHistoryManager {
89
+ private baseHistory;
90
+ private stacks;
91
+ private activeHistoryContextKey;
92
+ private historyContextStack;
93
+ private baseHistoryCleanup;
94
+ private contextSwitchMode;
95
+ private onContextActivate?;
96
+ constructor(historyBuilder: HistoryBuilder, options?: MultiRouterHistoryManagerOptions);
97
+ get base(): string;
98
+ get location(): HistoryLocation;
99
+ get state(): HistoryState;
100
+ createContextHistory(contextKey: string, options?: {
101
+ location?: string;
102
+ initialLocation?: string;
103
+ historyEnabled?: boolean;
104
+ }): MaybePromise<RouterHistory>;
105
+ private finalizeContextCreation;
106
+ tryRestoreActiveHistoryContext(contextKey: string): MaybePromise<boolean>;
107
+ removeContextHistory(contextKey: string): void;
108
+ setActiveHistoryContext(contextKey: string): void;
109
+ clearActiveHistoryContext(contextKey: string): void;
110
+ saveActiveContext(contextKey: string): void;
111
+ getActiveHistoryContextKey(): string | null;
112
+ private fallbackToPreviousHistoryContext;
113
+ private createInitialVirtualStack;
114
+ private restoreUrlFromVirtualStack;
115
+ private handlePopState;
116
+ push(contextKey: string, to: HistoryLocation, data?: HistoryState): void;
117
+ replace(contextKey: string, to: HistoryLocation, data?: HistoryState): void;
118
+ go(contextKey: string, delta: number, triggerListeners?: boolean): void;
119
+ listen(contextKey: string, callback: NavigationCallback): () => void;
120
+ getContextLocation(contextKey: string): HistoryLocation;
121
+ getContextState(contextKey: string): HistoryState;
122
+ createHref(location: HistoryLocation): string;
123
+ destroy(): void;
124
+ getLastActiveContextKey(): MaybePromise<string | null>;
125
+ }
126
+ //#endregion
127
+ //#region src/types.d.ts
128
+ type Wip = true;
129
+ interface ContextTypeOptions {
130
+ canUseAsHistoryContext: boolean;
131
+ single: boolean;
132
+ }
133
+ type ContextTypes = Record<string, ContextTypeOptions>;
134
+ //#endregion
135
+ //#region src/multi-router.d.ts
136
+ type MultiRouterInterface = {
137
+ getByContextName: (name: string) => Router;
138
+ install: (app: App) => void;
139
+ };
140
+ declare const contextTemplateWindows: {
141
+ window: {
142
+ canUseAsHistoryContext: true;
143
+ single: false;
144
+ };
145
+ };
146
+ declare const contextTemplateTabs: {
147
+ tab: {
148
+ canUseAsHistoryContext: true;
149
+ single: false;
150
+ };
151
+ };
152
+ declare const contextTemplateMainWithWindows: {
153
+ window: {
154
+ canUseAsHistoryContext: true;
155
+ single: false;
156
+ };
157
+ main: {
158
+ canUseAsHistoryContext: true;
159
+ single: true;
160
+ };
161
+ };
162
+ declare const contextTemplateDesktopWithWindows: {
163
+ window: {
164
+ canUseAsHistoryContext: true;
165
+ single: false;
166
+ };
167
+ desktop: {
168
+ canUseAsHistoryContext: false;
169
+ single: true;
170
+ };
171
+ };
172
+ declare const contextTemplateTabsWithWindows: {
173
+ window: {
174
+ canUseAsHistoryContext: true;
175
+ single: false;
176
+ };
177
+ tab: {
178
+ canUseAsHistoryContext: true;
179
+ single: false;
180
+ };
181
+ };
182
+ type CustomRouterOptions = Omit<RouterOptions, 'history'> & {
183
+ history: () => RouterHistory;
184
+ historyOptions?: MultiRouterHistoryManagerOptions;
185
+ types: ContextTypes;
186
+ };
187
+ declare function createMultiRouter(options: CustomRouterOptions): MultiRouterInterface;
188
+ //#endregion
189
+ //#region src/components/MultiRouterContext.vue.d.ts
190
+ declare const _default: typeof __VLS_export$1;
191
+ declare const __VLS_export$1: vue6.DefineComponent<vue6.ExtractPropTypes<{
192
+ type: {
193
+ type: StringConstructor;
194
+ required: true;
195
+ };
196
+ name: {
197
+ type: StringConstructor;
198
+ required: true;
199
+ };
200
+ location: {
201
+ type: StringConstructor;
202
+ required: false;
203
+ };
204
+ initialLocation: {
205
+ type: StringConstructor;
206
+ required: false;
207
+ };
208
+ /**
209
+ * Whether this context should store its navigation history in the browser history.
210
+ * When false, navigation within this context won't affect browser back/forward.
211
+ * @default true
212
+ */
213
+ historyEnabled: {
214
+ type: BooleanConstructor;
215
+ default: boolean;
216
+ };
217
+ /**
218
+ * Whether this context should be activated by default if no prior active context exists.
219
+ * Only one context should have this set to true.
220
+ * @default false
221
+ */
222
+ default: {
223
+ type: BooleanConstructor;
224
+ default: boolean;
225
+ };
226
+ }>, () => vue6.VNode<vue6.RendererNode, vue6.RendererElement, {
227
+ [key: string]: any;
228
+ }>, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<vue6.ExtractPropTypes<{
229
+ type: {
230
+ type: StringConstructor;
231
+ required: true;
232
+ };
233
+ name: {
234
+ type: StringConstructor;
235
+ required: true;
236
+ };
237
+ location: {
238
+ type: StringConstructor;
239
+ required: false;
240
+ };
241
+ initialLocation: {
242
+ type: StringConstructor;
243
+ required: false;
244
+ };
245
+ /**
246
+ * Whether this context should store its navigation history in the browser history.
247
+ * When false, navigation within this context won't affect browser back/forward.
248
+ * @default true
249
+ */
250
+ historyEnabled: {
251
+ type: BooleanConstructor;
252
+ default: boolean;
253
+ };
254
+ /**
255
+ * Whether this context should be activated by default if no prior active context exists.
256
+ * Only one context should have this set to true.
257
+ * @default false
258
+ */
259
+ default: {
260
+ type: BooleanConstructor;
261
+ default: boolean;
262
+ };
263
+ }>> & Readonly<{}>, {
264
+ historyEnabled: boolean;
265
+ default: boolean;
266
+ }, {}, {}, {}, string, vue6.ComponentProvideOptions, true, {}, any>;
267
+ //#endregion
268
+ //#region src/components/MultiRouterContextActivator.vue.d.ts
269
+ declare const _default$1: typeof __VLS_export;
270
+ declare const __VLS_export: vue6.DefineComponent<vue6.ExtractPropTypes<{
271
+ as: {
272
+ type: PropType<string | null>;
273
+ default: null;
274
+ };
275
+ }>, (() => vue6.VNode<vue6.RendererNode, vue6.RendererElement, {
276
+ [key: string]: any;
277
+ }>[] | undefined) | (() => vue6.VNode<vue6.RendererNode, vue6.RendererElement, {
278
+ [key: string]: any;
279
+ }>), {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<vue6.ExtractPropTypes<{
280
+ as: {
281
+ type: PropType<string | null>;
282
+ default: null;
283
+ };
284
+ }>> & Readonly<{}>, {
285
+ as: string | null;
286
+ }, {}, {}, {}, string, vue6.ComponentProvideOptions, true, {}, any>;
287
+ //#endregion
288
+ //#region src/contextManager.d.ts
289
+ type ContextInterface = {
290
+ type: string;
291
+ router: Router;
292
+ history: RouterHistory;
293
+ initialized: boolean;
294
+ historyEnabled: boolean;
295
+ };
296
+ interface ActiveContextInterface {
297
+ key: string;
298
+ context: ContextInterface;
299
+ }
300
+ type ContextInitListener = (key: string) => void;
301
+ type MakeRouterFn = (contextKey: string, history: RouterHistory) => Router;
302
+ type HistoryManagerOptions = {
303
+ historyBuilder: HistoryBuilder;
304
+ } & MultiRouterHistoryManagerOptions;
305
+ declare class MultiRouterManagerInstance {
306
+ private types;
307
+ private makeRouter;
308
+ private started;
309
+ private activeContext;
310
+ private activeHistoryContext;
311
+ private registered;
312
+ private onContextInitListeners;
313
+ private readonly historyManager;
314
+ constructor(app: App, types: ContextTypes, historyManagerOptions: HistoryManagerOptions, makeRouter: MakeRouterFn);
315
+ getHistoryManager(): MultiRouterHistoryManager;
316
+ getActiveContext(): ActiveContextInterface | undefined;
317
+ getActiveContextRef(): vue6.ShallowRef<ActiveContextInterface | undefined, ActiveContextInterface | undefined>;
318
+ getActiveHistoryContext(): ActiveContextInterface | undefined;
319
+ getActiveHistoryContextRef(): vue6.ShallowRef<ActiveContextInterface | undefined, ActiveContextInterface | undefined>;
320
+ setActive(key: string, updateHistory: boolean): boolean;
321
+ clearHistoryContext(key: string): void;
322
+ markAsStarted(): void;
323
+ getRouter(key: string): Router;
324
+ has(key: string): boolean;
325
+ register(type: string, key: string, options?: {
326
+ location?: string;
327
+ initialLocation?: string;
328
+ historyEnabled?: boolean;
329
+ default?: boolean;
330
+ }): MaybePromise<void>;
331
+ getContextLocation(key: string): string | undefined;
332
+ getContextHistoryEnabled(key: string): boolean;
333
+ unregister(key: string): void;
334
+ initialize(key: string): void;
335
+ onContextInit(fn: ContextInitListener): void;
336
+ }
337
+ //#endregion
338
+ //#region src/composables/useMultiRouterContext.d.ts
339
+ declare function useMultiRouterContext(): {
340
+ manager: MultiRouterManagerInstance;
341
+ contextKey: string;
342
+ router: vue6.ComputedRef<Router>;
343
+ route: vue6.ComputedRef<vue_router0.RouteLocationNormalizedLoadedGeneric>;
344
+ isActive: vue6.ComputedRef<boolean>;
345
+ isHistoryActive: vue6.ComputedRef<boolean>;
346
+ activeContextKey: vue6.ComputedRef<string | undefined>;
347
+ activeHistoryContextKey: vue6.ComputedRef<string | undefined>;
348
+ historyEnabled: vue6.ComputedRef<boolean>;
349
+ activate: (updateHistory?: boolean) => void;
350
+ };
351
+ //#endregion
352
+ //#region src/injectionSymbols.d.ts
353
+ declare const multiRouterContextManagerKey: InjectionKey<MultiRouterManagerInstance>;
354
+ declare const multiRouterContextKey: InjectionKey<string>;
355
+ //#endregion
356
+ export { type ContextSwitchMode, ContextTypeOptions, ContextTypes, type HistoryBuilder, type HistoryLocation, type HistoryState, _default as MultiRouterContext, _default$1 as MultiRouterContextActivator, type MultiRouterHistoryManagerOptions, type NavigationCallback, type NavigationInformation, type VirtualStack, Wip, contextTemplateDesktopWithWindows, contextTemplateMainWithWindows, contextTemplateTabs, contextTemplateTabsWithWindows, contextTemplateWindows, createMultiRouter, multiRouterContextKey, multiRouterContextManagerKey, useMultiRouterContext };