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 +21 -0
- package/README.md +92 -0
- package/dist/index.d.ts +356 -0
- package/dist/index.js +1028 -0
- package/package.json +82 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1028 @@
|
|
|
1
|
+
import { computed, defineComponent, getCurrentInstance, h, inject, onBeforeUnmount, provide, ref, shallowRef } from "vue";
|
|
2
|
+
import { RouterLink, RouterView, createRouter, routeLocationKey, routerKey, routerViewLocationKey, viewDepthKey } from "vue-router";
|
|
3
|
+
|
|
4
|
+
//#region src/history/storage/types.ts
|
|
5
|
+
function isPromise(value) {
|
|
6
|
+
return value instanceof Promise;
|
|
7
|
+
}
|
|
8
|
+
function resolveValue(value, callback) {
|
|
9
|
+
if (isPromise(value)) value.then(callback);
|
|
10
|
+
else callback(value);
|
|
11
|
+
}
|
|
12
|
+
function mapMaybePromise(value, fn) {
|
|
13
|
+
if (isPromise(value)) return value.then(fn);
|
|
14
|
+
return fn(value);
|
|
15
|
+
}
|
|
16
|
+
function flatMapMaybePromise(value, fn) {
|
|
17
|
+
if (isPromise(value)) return value.then(fn);
|
|
18
|
+
return fn(value);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/history/storage/session-storage-adapter.ts
|
|
23
|
+
const STACK_STORAGE_PREFIX = "__multiRouter_stack_";
|
|
24
|
+
const ACTIVE_CONTEXT_STORAGE_KEY = "__multiRouterActiveContext";
|
|
25
|
+
const ACTIVE_HISTORY_CONTEXT_STORAGE_KEY = "__multiRouterActiveHistoryContext";
|
|
26
|
+
var SessionStorageAdapter = class {
|
|
27
|
+
getStackStorageKey(contextKey) {
|
|
28
|
+
return `${STACK_STORAGE_PREFIX}${contextKey}`;
|
|
29
|
+
}
|
|
30
|
+
saveStack(contextKey, stack) {
|
|
31
|
+
try {
|
|
32
|
+
const data = {
|
|
33
|
+
entries: stack.entries,
|
|
34
|
+
position: stack.position
|
|
35
|
+
};
|
|
36
|
+
sessionStorage.setItem(this.getStackStorageKey(contextKey), JSON.stringify(data));
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.warn("[SessionStorageAdapter] Failed to save stack:", e);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
restoreStack(contextKey) {
|
|
42
|
+
try {
|
|
43
|
+
const stored = sessionStorage.getItem(this.getStackStorageKey(contextKey));
|
|
44
|
+
if (!stored) return null;
|
|
45
|
+
const data = JSON.parse(stored);
|
|
46
|
+
if (data && Array.isArray(data.entries) && data.entries.length > 0) {
|
|
47
|
+
const position = Math.min(Math.max(0, data.position ?? 0), data.entries.length - 1);
|
|
48
|
+
return {
|
|
49
|
+
entries: data.entries,
|
|
50
|
+
position
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.warn("[SessionStorageAdapter] Failed to restore stack:", e);
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
clearStack(contextKey) {
|
|
59
|
+
try {
|
|
60
|
+
sessionStorage.removeItem(this.getStackStorageKey(contextKey));
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.warn("[SessionStorageAdapter] Failed to clear stack:", e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
saveActiveContext(contextKey) {
|
|
66
|
+
try {
|
|
67
|
+
sessionStorage.setItem(ACTIVE_CONTEXT_STORAGE_KEY, contextKey);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
console.warn("[SessionStorageAdapter] Failed to save active context:", e);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
getActiveContext() {
|
|
73
|
+
try {
|
|
74
|
+
return sessionStorage.getItem(ACTIVE_CONTEXT_STORAGE_KEY);
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
saveActiveHistoryContext(contextKey) {
|
|
80
|
+
try {
|
|
81
|
+
sessionStorage.setItem(ACTIVE_HISTORY_CONTEXT_STORAGE_KEY, contextKey);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.warn("[SessionStorageAdapter] Failed to save active history context:", e);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
getActiveHistoryContext() {
|
|
87
|
+
try {
|
|
88
|
+
return sessionStorage.getItem(ACTIVE_HISTORY_CONTEXT_STORAGE_KEY);
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
//#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
|
+
}({});
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/history/storage.ts
|
|
111
|
+
var VirtualStackStorage = class {
|
|
112
|
+
adapter;
|
|
113
|
+
constructor(adapter) {
|
|
114
|
+
this.adapter = adapter ?? new SessionStorageAdapter();
|
|
115
|
+
}
|
|
116
|
+
save(contextKey, stack) {
|
|
117
|
+
return this.adapter.saveStack(contextKey, stack);
|
|
118
|
+
}
|
|
119
|
+
restore(contextKey) {
|
|
120
|
+
return this.adapter.restoreStack(contextKey);
|
|
121
|
+
}
|
|
122
|
+
clear(contextKey) {
|
|
123
|
+
return this.adapter.clearStack(contextKey);
|
|
124
|
+
}
|
|
125
|
+
saveActiveContext(contextKey) {
|
|
126
|
+
return this.adapter.saveActiveContext(contextKey);
|
|
127
|
+
}
|
|
128
|
+
getActiveContext() {
|
|
129
|
+
return this.adapter.getActiveContext();
|
|
130
|
+
}
|
|
131
|
+
saveActiveHistoryContext(contextKey) {
|
|
132
|
+
return this.adapter.saveActiveHistoryContext(contextKey);
|
|
133
|
+
}
|
|
134
|
+
getActiveHistoryContext() {
|
|
135
|
+
return this.adapter.getActiveHistoryContext();
|
|
136
|
+
}
|
|
137
|
+
resolveValue = resolveValue;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/history/virtual-stack.ts
|
|
142
|
+
var VirtualStackManager = class {
|
|
143
|
+
contexts = /* @__PURE__ */ new Map();
|
|
144
|
+
storage;
|
|
145
|
+
constructor(storageAdapter) {
|
|
146
|
+
this.storage = new VirtualStackStorage(storageAdapter);
|
|
147
|
+
}
|
|
148
|
+
has(contextKey) {
|
|
149
|
+
return this.contexts.has(contextKey);
|
|
150
|
+
}
|
|
151
|
+
get(contextKey) {
|
|
152
|
+
return this.contexts.get(contextKey);
|
|
153
|
+
}
|
|
154
|
+
create(contextKey, initialStack, historyEnabled = true) {
|
|
155
|
+
this.contexts.set(contextKey, {
|
|
156
|
+
virtualStack: initialStack,
|
|
157
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
158
|
+
historyEnabled
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
isHistoryEnabled(contextKey) {
|
|
162
|
+
return this.contexts.get(contextKey)?.historyEnabled ?? true;
|
|
163
|
+
}
|
|
164
|
+
remove(contextKey) {
|
|
165
|
+
this.contexts.delete(contextKey);
|
|
166
|
+
this.storage.clear(contextKey);
|
|
167
|
+
}
|
|
168
|
+
clear() {
|
|
169
|
+
this.contexts.clear();
|
|
170
|
+
}
|
|
171
|
+
getLocation(contextKey, fallback) {
|
|
172
|
+
const context = this.contexts.get(contextKey);
|
|
173
|
+
if (!context) return fallback;
|
|
174
|
+
return context.virtualStack.entries[context.virtualStack.position]?.location ?? fallback;
|
|
175
|
+
}
|
|
176
|
+
getState(contextKey) {
|
|
177
|
+
const context = this.contexts.get(contextKey);
|
|
178
|
+
if (!context) return {};
|
|
179
|
+
return context.virtualStack.entries[context.virtualStack.position]?.state ?? {};
|
|
180
|
+
}
|
|
181
|
+
push(contextKey, location, state) {
|
|
182
|
+
const context = this.contexts.get(contextKey);
|
|
183
|
+
if (!context) throw new Error(`[VirtualStackManager] Context "${contextKey}" not found`);
|
|
184
|
+
context.virtualStack.entries = context.virtualStack.entries.slice(0, context.virtualStack.position + 1);
|
|
185
|
+
context.virtualStack.entries.push({
|
|
186
|
+
location,
|
|
187
|
+
state
|
|
188
|
+
});
|
|
189
|
+
context.virtualStack.position = context.virtualStack.entries.length - 1;
|
|
190
|
+
this.save(contextKey);
|
|
191
|
+
return context.virtualStack.position;
|
|
192
|
+
}
|
|
193
|
+
replace(contextKey, location, state) {
|
|
194
|
+
const context = this.contexts.get(contextKey);
|
|
195
|
+
if (!context) throw new Error(`[VirtualStackManager] Context "${contextKey}" not found`);
|
|
196
|
+
context.virtualStack.entries[context.virtualStack.position] = {
|
|
197
|
+
location,
|
|
198
|
+
state
|
|
199
|
+
};
|
|
200
|
+
this.save(contextKey);
|
|
201
|
+
return context.virtualStack.position;
|
|
202
|
+
}
|
|
203
|
+
navigate(contextKey, delta) {
|
|
204
|
+
const context = this.contexts.get(contextKey);
|
|
205
|
+
if (!context) return null;
|
|
206
|
+
const newPosition = context.virtualStack.position + delta;
|
|
207
|
+
if (newPosition < 0 || newPosition >= context.virtualStack.entries.length) return null;
|
|
208
|
+
const from = context.virtualStack.entries[context.virtualStack.position].location;
|
|
209
|
+
context.virtualStack.position = newPosition;
|
|
210
|
+
const to = context.virtualStack.entries[newPosition].location;
|
|
211
|
+
this.save(contextKey);
|
|
212
|
+
return {
|
|
213
|
+
from,
|
|
214
|
+
to,
|
|
215
|
+
newPosition
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
setPosition(contextKey, position) {
|
|
219
|
+
const context = this.contexts.get(contextKey);
|
|
220
|
+
if (!context) return;
|
|
221
|
+
if (position >= 0 && position < context.virtualStack.entries.length) {
|
|
222
|
+
context.virtualStack.position = position;
|
|
223
|
+
this.save(contextKey);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
ensureEntriesUpTo(contextKey, position, fallbackLocation) {
|
|
227
|
+
const context = this.contexts.get(contextKey);
|
|
228
|
+
if (!context) return;
|
|
229
|
+
while (context.virtualStack.entries.length <= position) context.virtualStack.entries.push({
|
|
230
|
+
location: fallbackLocation,
|
|
231
|
+
state: {}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
addListener(contextKey, callback) {
|
|
235
|
+
const context = this.contexts.get(contextKey);
|
|
236
|
+
if (!context) throw new Error(`[VirtualStackManager] Context "${contextKey}" not found`);
|
|
237
|
+
context.listeners.add(callback);
|
|
238
|
+
return () => context.listeners.delete(callback);
|
|
239
|
+
}
|
|
240
|
+
notifyListeners(contextKey, to, from, info) {
|
|
241
|
+
const context = this.contexts.get(contextKey);
|
|
242
|
+
if (!context) return;
|
|
243
|
+
context.listeners.forEach((callback) => callback(to, from, info));
|
|
244
|
+
}
|
|
245
|
+
save(contextKey) {
|
|
246
|
+
const context = this.contexts.get(contextKey);
|
|
247
|
+
if (context) return this.storage.save(contextKey, context.virtualStack);
|
|
248
|
+
}
|
|
249
|
+
restore(contextKey) {
|
|
250
|
+
return this.storage.restore(contextKey);
|
|
251
|
+
}
|
|
252
|
+
saveActiveContext(contextKey) {
|
|
253
|
+
return this.storage.saveActiveContext(contextKey);
|
|
254
|
+
}
|
|
255
|
+
getStoredActiveContext() {
|
|
256
|
+
return this.storage.getActiveContext();
|
|
257
|
+
}
|
|
258
|
+
saveActiveHistoryContext(contextKey) {
|
|
259
|
+
return this.storage.saveActiveHistoryContext(contextKey);
|
|
260
|
+
}
|
|
261
|
+
getStoredActiveHistoryContext() {
|
|
262
|
+
return this.storage.getActiveHistoryContext();
|
|
263
|
+
}
|
|
264
|
+
entries() {
|
|
265
|
+
return this.contexts.entries();
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/history/manager.ts
|
|
271
|
+
var ContextHistoryProxy = class {
|
|
272
|
+
constructor(contextKey, manager) {
|
|
273
|
+
this.contextKey = contextKey;
|
|
274
|
+
this.manager = manager;
|
|
275
|
+
}
|
|
276
|
+
get base() {
|
|
277
|
+
return this.manager.base;
|
|
278
|
+
}
|
|
279
|
+
get location() {
|
|
280
|
+
return this.manager.getContextLocation(this.contextKey);
|
|
281
|
+
}
|
|
282
|
+
get state() {
|
|
283
|
+
return this.manager.getContextState(this.contextKey);
|
|
284
|
+
}
|
|
285
|
+
push(to, data) {
|
|
286
|
+
this.manager.push(this.contextKey, to, data);
|
|
287
|
+
}
|
|
288
|
+
replace(to, data) {
|
|
289
|
+
this.manager.replace(this.contextKey, to, data);
|
|
290
|
+
}
|
|
291
|
+
go(delta, triggerListeners) {
|
|
292
|
+
this.manager.go(this.contextKey, delta, triggerListeners);
|
|
293
|
+
}
|
|
294
|
+
listen(callback) {
|
|
295
|
+
return this.manager.listen(this.contextKey, callback);
|
|
296
|
+
}
|
|
297
|
+
createHref(location) {
|
|
298
|
+
return this.manager.createHref(location);
|
|
299
|
+
}
|
|
300
|
+
destroy() {
|
|
301
|
+
this.manager.removeContextHistory(this.contextKey);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const CONTEXT_KEY_STATE = "__multiRouterContext";
|
|
305
|
+
const STACK_INDEX_STATE = "__multiRouterStackIndex";
|
|
306
|
+
var MultiRouterHistoryManager = class {
|
|
307
|
+
baseHistory;
|
|
308
|
+
stacks;
|
|
309
|
+
activeHistoryContextKey = null;
|
|
310
|
+
historyContextStack = [];
|
|
311
|
+
baseHistoryCleanup = null;
|
|
312
|
+
contextSwitchMode;
|
|
313
|
+
onContextActivate;
|
|
314
|
+
constructor(historyBuilder, options) {
|
|
315
|
+
this.baseHistory = historyBuilder();
|
|
316
|
+
this.stacks = new VirtualStackManager(options?.storageAdapter);
|
|
317
|
+
this.contextSwitchMode = options?.contextSwitchMode ?? "replace";
|
|
318
|
+
this.onContextActivate = options?.onContextActivate;
|
|
319
|
+
this.baseHistoryCleanup = this.baseHistory.listen(this.handlePopState.bind(this));
|
|
320
|
+
}
|
|
321
|
+
get base() {
|
|
322
|
+
return this.baseHistory.base;
|
|
323
|
+
}
|
|
324
|
+
get location() {
|
|
325
|
+
return this.baseHistory.location;
|
|
326
|
+
}
|
|
327
|
+
get state() {
|
|
328
|
+
return this.baseHistory.state;
|
|
329
|
+
}
|
|
330
|
+
createContextHistory(contextKey, options) {
|
|
331
|
+
if (this.stacks.has(contextKey)) return new ContextHistoryProxy(contextKey, this);
|
|
332
|
+
const { location, initialLocation, historyEnabled = true } = options ?? {};
|
|
333
|
+
return flatMapMaybePromise(this.stacks.getStoredActiveContext(), (lastActiveContext) => {
|
|
334
|
+
const isLastActive = lastActiveContext === contextKey;
|
|
335
|
+
if (location) {
|
|
336
|
+
const virtualStack = this.createInitialVirtualStack(location);
|
|
337
|
+
console.debug("[MultiRouterHistory] Created context with forced location", {
|
|
338
|
+
contextKey,
|
|
339
|
+
location
|
|
340
|
+
});
|
|
341
|
+
return this.finalizeContextCreation(contextKey, virtualStack, isLastActive, historyEnabled);
|
|
342
|
+
}
|
|
343
|
+
return mapMaybePromise(this.stacks.restore(contextKey), (restoredStack) => {
|
|
344
|
+
let virtualStack;
|
|
345
|
+
if (restoredStack) {
|
|
346
|
+
if (isLastActive && historyEnabled) {
|
|
347
|
+
const browserUrl = this.baseHistory.location;
|
|
348
|
+
restoredStack.entries[restoredStack.position] = {
|
|
349
|
+
location: browserUrl,
|
|
350
|
+
state: this.baseHistory.state ?? {}
|
|
351
|
+
};
|
|
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
|
+
});
|
|
360
|
+
virtualStack = restoredStack;
|
|
361
|
+
} else if (isLastActive && historyEnabled) {
|
|
362
|
+
const browserUrl = this.baseHistory.location;
|
|
363
|
+
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 });
|
|
377
|
+
}
|
|
378
|
+
return this.finalizeContextCreation(contextKey, virtualStack, isLastActive, historyEnabled);
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
finalizeContextCreation(contextKey, virtualStack, isLastActive, historyEnabled) {
|
|
383
|
+
this.stacks.create(contextKey, virtualStack, historyEnabled);
|
|
384
|
+
if (isLastActive && historyEnabled) {
|
|
385
|
+
this.activeHistoryContextKey = contextKey;
|
|
386
|
+
this.restoreUrlFromVirtualStack(contextKey);
|
|
387
|
+
}
|
|
388
|
+
return new ContextHistoryProxy(contextKey, this);
|
|
389
|
+
}
|
|
390
|
+
tryRestoreActiveHistoryContext(contextKey) {
|
|
391
|
+
return mapMaybePromise(this.stacks.getStoredActiveHistoryContext(), (storedKey) => {
|
|
392
|
+
if (storedKey === contextKey && this.stacks.has(contextKey) && this.stacks.isHistoryEnabled(contextKey)) {
|
|
393
|
+
this.activeHistoryContextKey = contextKey;
|
|
394
|
+
this.restoreUrlFromVirtualStack(contextKey);
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
return false;
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
removeContextHistory(contextKey) {
|
|
401
|
+
this.stacks.remove(contextKey);
|
|
402
|
+
if (this.activeHistoryContextKey === contextKey) this.fallbackToPreviousHistoryContext();
|
|
403
|
+
this.historyContextStack = this.historyContextStack.filter((k) => k !== contextKey);
|
|
404
|
+
}
|
|
405
|
+
setActiveHistoryContext(contextKey) {
|
|
406
|
+
if (!this.stacks.has(contextKey)) throw new Error(`[MultiRouterHistory] Context "${contextKey}" not registered`);
|
|
407
|
+
if (this.activeHistoryContextKey === contextKey) return;
|
|
408
|
+
const previousKey = this.activeHistoryContextKey;
|
|
409
|
+
if (previousKey) {
|
|
410
|
+
this.historyContextStack = this.historyContextStack.filter((k) => k !== previousKey);
|
|
411
|
+
this.historyContextStack.push(previousKey);
|
|
412
|
+
}
|
|
413
|
+
this.activeHistoryContextKey = contextKey;
|
|
414
|
+
this.stacks.saveActiveContext(contextKey);
|
|
415
|
+
this.stacks.saveActiveHistoryContext(contextKey);
|
|
416
|
+
this.restoreUrlFromVirtualStack(contextKey);
|
|
417
|
+
console.debug("[MultiRouterHistory] setActiveHistoryContext", {
|
|
418
|
+
from: previousKey,
|
|
419
|
+
to: contextKey
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
clearActiveHistoryContext(contextKey) {
|
|
423
|
+
if (this.activeHistoryContextKey !== contextKey) return;
|
|
424
|
+
this.fallbackToPreviousHistoryContext();
|
|
425
|
+
}
|
|
426
|
+
saveActiveContext(contextKey) {
|
|
427
|
+
this.stacks.saveActiveContext(contextKey);
|
|
428
|
+
}
|
|
429
|
+
getActiveHistoryContextKey() {
|
|
430
|
+
return this.activeHistoryContextKey;
|
|
431
|
+
}
|
|
432
|
+
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 });
|
|
437
|
+
}
|
|
438
|
+
createInitialVirtualStack(initialLocation) {
|
|
439
|
+
return {
|
|
440
|
+
entries: [{
|
|
441
|
+
location: initialLocation ?? "/",
|
|
442
|
+
state: {}
|
|
443
|
+
}],
|
|
444
|
+
position: 0
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
restoreUrlFromVirtualStack(contextKey) {
|
|
448
|
+
if (this.contextSwitchMode === "none") return;
|
|
449
|
+
const context = this.stacks.get(contextKey);
|
|
450
|
+
if (!context) return;
|
|
451
|
+
const entry = context.virtualStack.entries[context.virtualStack.position];
|
|
452
|
+
if (!entry) return;
|
|
453
|
+
const state = {
|
|
454
|
+
...entry.state,
|
|
455
|
+
[CONTEXT_KEY_STATE]: contextKey,
|
|
456
|
+
[STACK_INDEX_STATE]: context.virtualStack.position
|
|
457
|
+
};
|
|
458
|
+
if (this.contextSwitchMode === "push") if (entry.location !== this.baseHistory.location) this.baseHistory.push(entry.location, state);
|
|
459
|
+
else this.baseHistory.replace(entry.location, state);
|
|
460
|
+
else this.baseHistory.replace(entry.location, state);
|
|
461
|
+
}
|
|
462
|
+
handlePopState(to, from, info) {
|
|
463
|
+
const stateContextKey = this.baseHistory.state?.[CONTEXT_KEY_STATE];
|
|
464
|
+
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
|
+
let ownerContextKey = null;
|
|
477
|
+
let targetStackIndex = null;
|
|
478
|
+
if (stateContextKey && this.stacks.has(stateContextKey)) {
|
|
479
|
+
ownerContextKey = stateContextKey;
|
|
480
|
+
targetStackIndex = stateStackIndex ?? null;
|
|
481
|
+
}
|
|
482
|
+
if (!ownerContextKey) ownerContextKey = this.activeHistoryContextKey;
|
|
483
|
+
if (!ownerContextKey) return;
|
|
484
|
+
const context = this.stacks.get(ownerContextKey);
|
|
485
|
+
let newPosition;
|
|
486
|
+
if (targetStackIndex !== null) newPosition = targetStackIndex;
|
|
487
|
+
else newPosition = context.virtualStack.position + info.delta;
|
|
488
|
+
this.stacks.ensureEntriesUpTo(ownerContextKey, newPosition, to);
|
|
489
|
+
if (newPosition >= 0 && newPosition < context.virtualStack.entries.length) {
|
|
490
|
+
const previousLocation = context.virtualStack.entries[context.virtualStack.position]?.location ?? from;
|
|
491
|
+
this.stacks.setPosition(ownerContextKey, newPosition);
|
|
492
|
+
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
|
+
if (this.onContextActivate) this.onContextActivate(ownerContextKey);
|
|
503
|
+
this.stacks.notifyListeners(ownerContextKey, targetLocation, previousLocation, info);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
push(contextKey, to, data) {
|
|
507
|
+
const stackIndex = this.stacks.push(contextKey, to, data ?? {});
|
|
508
|
+
const historyEnabled = this.stacks.isHistoryEnabled(contextKey);
|
|
509
|
+
if (this.activeHistoryContextKey === contextKey && historyEnabled) this.baseHistory.push(to, {
|
|
510
|
+
...data,
|
|
511
|
+
[CONTEXT_KEY_STATE]: contextKey,
|
|
512
|
+
[STACK_INDEX_STATE]: stackIndex
|
|
513
|
+
});
|
|
514
|
+
console.debug("[MultiRouterHistory] push", {
|
|
515
|
+
contextKey,
|
|
516
|
+
to,
|
|
517
|
+
stackIndex,
|
|
518
|
+
isActive: this.activeHistoryContextKey === contextKey,
|
|
519
|
+
historyEnabled
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
replace(contextKey, to, data) {
|
|
523
|
+
const stackIndex = this.stacks.replace(contextKey, to, data ?? {});
|
|
524
|
+
const historyEnabled = this.stacks.isHistoryEnabled(contextKey);
|
|
525
|
+
if (this.activeHistoryContextKey === contextKey && historyEnabled) this.baseHistory.replace(to, {
|
|
526
|
+
...data,
|
|
527
|
+
[CONTEXT_KEY_STATE]: contextKey,
|
|
528
|
+
[STACK_INDEX_STATE]: stackIndex
|
|
529
|
+
});
|
|
530
|
+
console.debug("[MultiRouterHistory] replace", {
|
|
531
|
+
contextKey,
|
|
532
|
+
to,
|
|
533
|
+
stackIndex,
|
|
534
|
+
isActive: this.activeHistoryContextKey === contextKey,
|
|
535
|
+
historyEnabled
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
go(contextKey, delta, triggerListeners = true) {
|
|
539
|
+
if (!this.stacks.has(contextKey)) throw new Error(`[MultiRouterHistory] Context "${contextKey}" not registered`);
|
|
540
|
+
if (this.activeHistoryContextKey === contextKey) this.baseHistory.go(delta, triggerListeners);
|
|
541
|
+
else {
|
|
542
|
+
const result = this.stacks.navigate(contextKey, delta);
|
|
543
|
+
if (result && triggerListeners) this.stacks.notifyListeners(contextKey, result.to, result.from, {
|
|
544
|
+
type: NavigationType.pop,
|
|
545
|
+
direction: delta < 0 ? NavigationDirection.back : NavigationDirection.forward,
|
|
546
|
+
delta
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
listen(contextKey, callback) {
|
|
551
|
+
return this.stacks.addListener(contextKey, callback);
|
|
552
|
+
}
|
|
553
|
+
getContextLocation(contextKey) {
|
|
554
|
+
return this.stacks.getLocation(contextKey, this.baseHistory.location);
|
|
555
|
+
}
|
|
556
|
+
getContextState(contextKey) {
|
|
557
|
+
return this.stacks.getState(contextKey);
|
|
558
|
+
}
|
|
559
|
+
createHref(location) {
|
|
560
|
+
return this.baseHistory.createHref(location);
|
|
561
|
+
}
|
|
562
|
+
destroy() {
|
|
563
|
+
if (this.baseHistoryCleanup) {
|
|
564
|
+
this.baseHistoryCleanup();
|
|
565
|
+
this.baseHistoryCleanup = null;
|
|
566
|
+
}
|
|
567
|
+
this.stacks.clear();
|
|
568
|
+
this.baseHistory.destroy();
|
|
569
|
+
}
|
|
570
|
+
getLastActiveContextKey() {
|
|
571
|
+
return this.stacks.getStoredActiveContext();
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
//#endregion
|
|
576
|
+
//#region src/contextManager.ts
|
|
577
|
+
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;
|
|
586
|
+
this.makeRouter = makeRouter;
|
|
587
|
+
const { historyBuilder, ...historyOptions } = historyManagerOptions;
|
|
588
|
+
this.historyManager = new MultiRouterHistoryManager(historyBuilder, {
|
|
589
|
+
...historyOptions,
|
|
590
|
+
onContextActivate: (contextKey) => {
|
|
591
|
+
this.setActive(contextKey, false);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
getHistoryManager() {
|
|
596
|
+
return this.historyManager;
|
|
597
|
+
}
|
|
598
|
+
getActiveContext() {
|
|
599
|
+
return this.activeContext.value;
|
|
600
|
+
}
|
|
601
|
+
getActiveContextRef() {
|
|
602
|
+
return this.activeContext;
|
|
603
|
+
}
|
|
604
|
+
getActiveHistoryContext() {
|
|
605
|
+
return this.activeHistoryContext.value;
|
|
606
|
+
}
|
|
607
|
+
getActiveHistoryContextRef() {
|
|
608
|
+
return this.activeHistoryContext;
|
|
609
|
+
}
|
|
610
|
+
setActive(key, updateHistory) {
|
|
611
|
+
const item = this.registered.get(key);
|
|
612
|
+
if (!item) throw new Error(`[MultiRouter] Context "${key}" not found`);
|
|
613
|
+
let modified = false;
|
|
614
|
+
if (this.activeContext.value?.key !== key) {
|
|
615
|
+
this.activeContext.value = {
|
|
616
|
+
key,
|
|
617
|
+
context: item
|
|
618
|
+
};
|
|
619
|
+
modified = true;
|
|
620
|
+
}
|
|
621
|
+
if (updateHistory) {
|
|
622
|
+
this.historyManager.saveActiveContext(key);
|
|
623
|
+
if (item.historyEnabled && this.activeHistoryContext.value?.key !== key) {
|
|
624
|
+
this.activeHistoryContext.value = this.activeContext.value;
|
|
625
|
+
this.historyManager.setActiveHistoryContext(key);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
if (modified) console.debug("[MultiRouterContextManager] setActive", {
|
|
629
|
+
key,
|
|
630
|
+
updateHistory,
|
|
631
|
+
historyEnabled: item.historyEnabled
|
|
632
|
+
});
|
|
633
|
+
return modified;
|
|
634
|
+
}
|
|
635
|
+
clearHistoryContext(key) {
|
|
636
|
+
if (this.activeHistoryContext.value?.key === key) {
|
|
637
|
+
this.historyManager.clearActiveHistoryContext(key);
|
|
638
|
+
const newActiveKey = this.historyManager.getActiveHistoryContextKey();
|
|
639
|
+
if (newActiveKey) {
|
|
640
|
+
const newContext = this.registered.get(newActiveKey);
|
|
641
|
+
if (newContext) this.activeHistoryContext.value = {
|
|
642
|
+
key: newActiveKey,
|
|
643
|
+
context: newContext
|
|
644
|
+
};
|
|
645
|
+
} else this.activeHistoryContext.value = void 0;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
markAsStarted() {
|
|
649
|
+
this.started = true;
|
|
650
|
+
}
|
|
651
|
+
getRouter(key) {
|
|
652
|
+
return this.registered.get(key).router;
|
|
653
|
+
}
|
|
654
|
+
has(key) {
|
|
655
|
+
return this.registered.has(key);
|
|
656
|
+
}
|
|
657
|
+
register(type, key, options) {
|
|
658
|
+
if (!this.types[type]) throw new Error(`[MultiRouter] Context type "${type}" not found`);
|
|
659
|
+
const historyEnabled = options?.historyEnabled ?? true;
|
|
660
|
+
const isDefault = options?.default ?? false;
|
|
661
|
+
return mapMaybePromise(this.historyManager.createContextHistory(key, {
|
|
662
|
+
location: options?.location,
|
|
663
|
+
initialLocation: options?.initialLocation,
|
|
664
|
+
historyEnabled
|
|
665
|
+
}), (history) => {
|
|
666
|
+
const router = this.makeRouter(key, history);
|
|
667
|
+
this.registered.set(key, {
|
|
668
|
+
type,
|
|
669
|
+
router,
|
|
670
|
+
history,
|
|
671
|
+
initialized: false,
|
|
672
|
+
historyEnabled
|
|
673
|
+
});
|
|
674
|
+
router.push(history.location).catch((err) => {
|
|
675
|
+
console.warn("Unexpected error when starting the router:", err);
|
|
676
|
+
});
|
|
677
|
+
router.isReady().then(() => {
|
|
678
|
+
this.markAsStarted();
|
|
679
|
+
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
|
+
}
|
|
687
|
+
});
|
|
688
|
+
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);
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
getContextLocation(key) {
|
|
704
|
+
return this.historyManager.getContextLocation(key);
|
|
705
|
+
}
|
|
706
|
+
getContextHistoryEnabled(key) {
|
|
707
|
+
return this.registered.get(key)?.historyEnabled ?? true;
|
|
708
|
+
}
|
|
709
|
+
unregister(key) {
|
|
710
|
+
if (this.registered.get(key)) {
|
|
711
|
+
console.debug("[MultiRouterContextManager] unregister", { key });
|
|
712
|
+
this.historyManager.removeContextHistory(key);
|
|
713
|
+
this.registered.delete(key);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
initialize(key) {
|
|
717
|
+
this.registered.get(key).initialized = true;
|
|
718
|
+
this.onContextInitListeners.forEach((fn) => fn(key));
|
|
719
|
+
}
|
|
720
|
+
onContextInit(fn) {
|
|
721
|
+
if (this.started) throw new Error("[MultiRouter] adding listener after start is not allowed");
|
|
722
|
+
this.onContextInitListeners.push(fn);
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
//#endregion
|
|
727
|
+
//#region src/symbols.ts
|
|
728
|
+
const multiRouterContextManager = Symbol("multi-router-context-manager");
|
|
729
|
+
const multiRouterContext = Symbol("multi-router-context-key");
|
|
730
|
+
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region src/injectionSymbols.ts
|
|
733
|
+
const multiRouterContextManagerKey = multiRouterContextManager;
|
|
734
|
+
const multiRouterContextKey = multiRouterContext;
|
|
735
|
+
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region src/multi-router.ts
|
|
738
|
+
const START_LOCATION_NORMALIZED = {
|
|
739
|
+
path: "/",
|
|
740
|
+
name: void 0,
|
|
741
|
+
params: {},
|
|
742
|
+
query: {},
|
|
743
|
+
hash: "",
|
|
744
|
+
fullPath: "/",
|
|
745
|
+
matched: [],
|
|
746
|
+
meta: {},
|
|
747
|
+
redirectedFrom: void 0
|
|
748
|
+
};
|
|
749
|
+
const getCurrentInstance$1 = () => getCurrentInstance();
|
|
750
|
+
function installContextAwareRouterResolvers(app, contextManager) {
|
|
751
|
+
if (app._context.provides[routerKey]) throw new Error("Router installed to app, this may cause unexpected behavior");
|
|
752
|
+
function isVueDevtoolsCall() {
|
|
753
|
+
return !!(/* @__PURE__ */ new Error()).stack?.includes("chrome-extension://nhdogjmejiglipccpnnnanhbledajbpd");
|
|
754
|
+
}
|
|
755
|
+
function getInstanceContextKey() {
|
|
756
|
+
const instance = getCurrentInstance$1();
|
|
757
|
+
if (!instance) {
|
|
758
|
+
if (isVueDevtoolsCall()) return null;
|
|
759
|
+
throw new Error("No instance found");
|
|
760
|
+
}
|
|
761
|
+
const contextKey = instance.provides[multiRouterContext];
|
|
762
|
+
if (!contextKey) throw new Error("Context key not found");
|
|
763
|
+
return contextKey;
|
|
764
|
+
}
|
|
765
|
+
const routerProperty = {
|
|
766
|
+
enumerable: true,
|
|
767
|
+
get() {
|
|
768
|
+
const contextKey = getInstanceContextKey();
|
|
769
|
+
if (!contextKey) return null;
|
|
770
|
+
if (!contextManager.has(contextKey)) {
|
|
771
|
+
if (isVueDevtoolsCall()) return null;
|
|
772
|
+
throw new Error(`Router not found for context ${contextKey}`);
|
|
773
|
+
}
|
|
774
|
+
return contextManager.getRouter(contextKey);
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
const routeProperty = {
|
|
778
|
+
enumerable: true,
|
|
779
|
+
get() {
|
|
780
|
+
const contextKey = getInstanceContextKey();
|
|
781
|
+
if (!contextKey || !contextManager.has(contextKey)) return null;
|
|
782
|
+
const currentRoute = contextManager.getRouter(contextKey).currentRoute;
|
|
783
|
+
const reactiveRoute = {};
|
|
784
|
+
for (const key in START_LOCATION_NORMALIZED) Object.defineProperty(reactiveRoute, key, {
|
|
785
|
+
get: () => currentRoute.value[key],
|
|
786
|
+
enumerable: true
|
|
787
|
+
});
|
|
788
|
+
return reactiveRoute;
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
Object.defineProperty(app._context.provides, routerKey, routerProperty);
|
|
792
|
+
Object.defineProperty(app.config.globalProperties, "$router", routerProperty);
|
|
793
|
+
Object.defineProperty(app._context.provides, routeLocationKey, routeProperty);
|
|
794
|
+
Object.defineProperty(app.config.globalProperties, "$route", routeProperty);
|
|
795
|
+
Object.defineProperty(app._context.provides, routerViewLocationKey, {
|
|
796
|
+
enumerable: true,
|
|
797
|
+
configurable: true,
|
|
798
|
+
get() {
|
|
799
|
+
const contextKey = getInstanceContextKey();
|
|
800
|
+
if (!contextKey || !contextManager.has(contextKey)) return null;
|
|
801
|
+
return contextManager.getRouter(contextKey).currentRoute;
|
|
802
|
+
},
|
|
803
|
+
set() {}
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
function installComponents(app) {
|
|
807
|
+
app.component("RouterLink", RouterLink);
|
|
808
|
+
app.component("RouterView", RouterView);
|
|
809
|
+
}
|
|
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
|
+
function createMultiRouter(options) {
|
|
837
|
+
let contextManager;
|
|
838
|
+
return {
|
|
839
|
+
getByContextName: (name) => {
|
|
840
|
+
return contextManager.getRouter(name);
|
|
841
|
+
},
|
|
842
|
+
install: (app) => {
|
|
843
|
+
const makeRouter = (contextKey, history) => {
|
|
844
|
+
const router = createRouter({
|
|
845
|
+
...options,
|
|
846
|
+
history
|
|
847
|
+
});
|
|
848
|
+
Object.assign(router, { contextKey });
|
|
849
|
+
return router;
|
|
850
|
+
};
|
|
851
|
+
contextManager = new MultiRouterManagerInstance(app, options.types, {
|
|
852
|
+
historyBuilder: options.history,
|
|
853
|
+
...options.historyOptions
|
|
854
|
+
}, makeRouter);
|
|
855
|
+
app.provide(multiRouterContextManagerKey, contextManager);
|
|
856
|
+
installComponents(app);
|
|
857
|
+
installContextAwareRouterResolvers(app, contextManager);
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
//#endregion
|
|
863
|
+
//#region src/components/MultiRouterContext.vue?vue&type=script&lang.ts
|
|
864
|
+
const MultiRouterContextInner = defineComponent({
|
|
865
|
+
name: "MultiRouterContextInner",
|
|
866
|
+
props: {
|
|
867
|
+
type: {
|
|
868
|
+
type: String,
|
|
869
|
+
required: true
|
|
870
|
+
},
|
|
871
|
+
name: {
|
|
872
|
+
type: String,
|
|
873
|
+
required: true
|
|
874
|
+
},
|
|
875
|
+
location: {
|
|
876
|
+
type: String,
|
|
877
|
+
required: false
|
|
878
|
+
},
|
|
879
|
+
initialLocation: {
|
|
880
|
+
type: String,
|
|
881
|
+
required: false
|
|
882
|
+
},
|
|
883
|
+
historyEnabled: {
|
|
884
|
+
type: Boolean,
|
|
885
|
+
default: true
|
|
886
|
+
},
|
|
887
|
+
default: {
|
|
888
|
+
type: Boolean,
|
|
889
|
+
default: false
|
|
890
|
+
}
|
|
891
|
+
},
|
|
892
|
+
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
|
+
}
|
|
904
|
+
manager.register(props.type, props.name, {
|
|
905
|
+
location: props.location,
|
|
906
|
+
initialLocation: props.initialLocation,
|
|
907
|
+
historyEnabled: props.historyEnabled,
|
|
908
|
+
default: props.default
|
|
909
|
+
});
|
|
910
|
+
provide(multiRouterContext, props.name);
|
|
911
|
+
provide(viewDepthKey, ref(0));
|
|
912
|
+
onBeforeUnmount(() => {
|
|
913
|
+
manager.unregister(props.name);
|
|
914
|
+
});
|
|
915
|
+
return () => slots.default?.();
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
var MultiRouterContext_vue_vue_type_script_lang_default = defineComponent({
|
|
919
|
+
name: "MultiRouterContext",
|
|
920
|
+
props: {
|
|
921
|
+
type: {
|
|
922
|
+
type: String,
|
|
923
|
+
required: true
|
|
924
|
+
},
|
|
925
|
+
name: {
|
|
926
|
+
type: String,
|
|
927
|
+
required: true
|
|
928
|
+
},
|
|
929
|
+
location: {
|
|
930
|
+
type: String,
|
|
931
|
+
required: false
|
|
932
|
+
},
|
|
933
|
+
initialLocation: {
|
|
934
|
+
type: String,
|
|
935
|
+
required: false
|
|
936
|
+
},
|
|
937
|
+
historyEnabled: {
|
|
938
|
+
type: Boolean,
|
|
939
|
+
default: true
|
|
940
|
+
},
|
|
941
|
+
default: {
|
|
942
|
+
type: Boolean,
|
|
943
|
+
default: false
|
|
944
|
+
}
|
|
945
|
+
},
|
|
946
|
+
setup(props, { slots }) {
|
|
947
|
+
return () => h(MultiRouterContextInner, {
|
|
948
|
+
key: `${props.name}:${props.location ?? ""}`,
|
|
949
|
+
type: props.type,
|
|
950
|
+
name: props.name,
|
|
951
|
+
location: props.location,
|
|
952
|
+
initialLocation: props.initialLocation,
|
|
953
|
+
historyEnabled: props.historyEnabled,
|
|
954
|
+
default: props.default
|
|
955
|
+
}, slots.default);
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
//#endregion
|
|
960
|
+
//#region src/components/MultiRouterContext.vue
|
|
961
|
+
var MultiRouterContext_default = MultiRouterContext_vue_vue_type_script_lang_default;
|
|
962
|
+
|
|
963
|
+
//#endregion
|
|
964
|
+
//#region src/components/MultiRouterContextActivator.vue?vue&type=script&lang.ts
|
|
965
|
+
var MultiRouterContextActivator_vue_vue_type_script_lang_default = defineComponent({
|
|
966
|
+
props: { as: {
|
|
967
|
+
type: String,
|
|
968
|
+
default: null
|
|
969
|
+
} },
|
|
970
|
+
setup(props, { slots }) {
|
|
971
|
+
const contextKey = inject(multiRouterContextKey);
|
|
972
|
+
const manager = inject(multiRouterContextManagerKey);
|
|
973
|
+
if (!contextKey || !manager) {
|
|
974
|
+
console.warn("[MultiRouterContextActivator] Must be used within MultiRouterContext");
|
|
975
|
+
return () => slots.default?.();
|
|
976
|
+
}
|
|
977
|
+
const onActivate = (e) => {
|
|
978
|
+
e.stopPropagation();
|
|
979
|
+
if (manager.setActive(contextKey, true)) console.debug("[MultiRouterContextActivator] activated", contextKey);
|
|
980
|
+
};
|
|
981
|
+
return () => {
|
|
982
|
+
const children = slots.default?.();
|
|
983
|
+
if (!props.as) {
|
|
984
|
+
if (children && children.length === 1) return h(children[0], { onMousedown: onActivate });
|
|
985
|
+
return h("span", { onMousedown: onActivate }, children);
|
|
986
|
+
}
|
|
987
|
+
return h(props.as, { onMousedown: onActivate }, children);
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
//#endregion
|
|
993
|
+
//#region src/components/MultiRouterContextActivator.vue
|
|
994
|
+
var MultiRouterContextActivator_default = MultiRouterContextActivator_vue_vue_type_script_lang_default;
|
|
995
|
+
|
|
996
|
+
//#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 };
|