@esmx/router 3.0.0-rc.12 → 3.0.0-rc.120
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/README.md +158 -0
- package/README.zh-CN.md +158 -0
- package/dist/error.d.ts +23 -0
- package/dist/error.mjs +64 -0
- package/dist/increment-id.d.ts +7 -0
- package/dist/increment-id.mjs +16 -0
- package/dist/index.d.ts +14 -3
- package/dist/index.mjs +13 -3
- package/dist/location.d.ts +22 -0
- package/dist/location.mjs +64 -0
- package/dist/matcher.d.ts +4 -0
- package/dist/matcher.mjs +49 -0
- package/dist/micro-app.d.ts +20 -0
- package/dist/micro-app.mjs +132 -0
- package/dist/navigation.d.ts +45 -0
- package/dist/navigation.mjs +153 -0
- package/dist/options.d.ts +4 -0
- package/dist/options.mjs +95 -0
- package/dist/route-task.d.ts +40 -0
- package/dist/route-task.mjs +77 -0
- package/dist/route-transition.d.ts +54 -0
- package/dist/route-transition.mjs +362 -0
- package/dist/route.d.ts +77 -0
- package/dist/route.mjs +223 -0
- package/dist/router-link.d.ts +10 -0
- package/dist/router-link.mjs +142 -0
- package/dist/router.d.ts +113 -102
- package/dist/router.mjs +321 -354
- package/dist/scroll.d.ts +33 -0
- package/dist/scroll.mjs +50 -0
- package/dist/types.d.ts +312 -0
- package/dist/types.mjs +18 -0
- package/dist/util.d.ts +32 -0
- package/dist/util.mjs +100 -0
- package/package.json +42 -15
- package/src/error.ts +84 -0
- package/src/increment-id.ts +12 -0
- package/src/index.ts +67 -3
- package/src/location.ts +124 -0
- package/src/matcher.ts +71 -0
- package/src/micro-app.ts +153 -0
- package/src/navigation.ts +202 -0
- package/src/options.ts +136 -0
- package/src/route-task.ts +102 -0
- package/src/route-transition.ts +480 -0
- package/src/route.ts +335 -0
- package/src/router-link.ts +241 -0
- package/src/router.ts +351 -467
- package/src/scroll.ts +106 -0
- package/src/types.ts +415 -0
- package/src/util.ts +184 -0
- package/dist/history/abstract.d.ts +0 -29
- package/dist/history/abstract.mjs +0 -107
- package/dist/history/base.d.ts +0 -79
- package/dist/history/base.mjs +0 -275
- package/dist/history/html.d.ts +0 -22
- package/dist/history/html.mjs +0 -181
- package/dist/history/index.d.ts +0 -7
- package/dist/history/index.mjs +0 -16
- package/dist/matcher/create-matcher.d.ts +0 -5
- package/dist/matcher/create-matcher.mjs +0 -218
- package/dist/matcher/create-matcher.spec.d.ts +0 -1
- package/dist/matcher/create-matcher.spec.mjs +0 -0
- package/dist/matcher/index.d.ts +0 -1
- package/dist/matcher/index.mjs +0 -1
- package/dist/task-pipe/index.d.ts +0 -1
- package/dist/task-pipe/index.mjs +0 -1
- package/dist/task-pipe/task.d.ts +0 -30
- package/dist/task-pipe/task.mjs +0 -66
- package/dist/utils/bom.d.ts +0 -5
- package/dist/utils/bom.mjs +0 -10
- package/dist/utils/encoding.d.ts +0 -48
- package/dist/utils/encoding.mjs +0 -44
- package/dist/utils/guards.d.ts +0 -9
- package/dist/utils/guards.mjs +0 -12
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.mjs +0 -27
- package/dist/utils/path.d.ts +0 -60
- package/dist/utils/path.mjs +0 -264
- package/dist/utils/path.spec.d.ts +0 -1
- package/dist/utils/path.spec.mjs +0 -30
- package/dist/utils/scroll.d.ts +0 -25
- package/dist/utils/scroll.mjs +0 -59
- package/dist/utils/utils.d.ts +0 -16
- package/dist/utils/utils.mjs +0 -11
- package/dist/utils/warn.d.ts +0 -2
- package/dist/utils/warn.mjs +0 -12
- package/src/history/abstract.ts +0 -149
- package/src/history/base.ts +0 -408
- package/src/history/html.ts +0 -231
- package/src/history/index.ts +0 -20
- package/src/matcher/create-matcher.spec.ts +0 -3
- package/src/matcher/create-matcher.ts +0 -293
- package/src/matcher/index.ts +0 -1
- package/src/task-pipe/index.ts +0 -1
- package/src/task-pipe/task.ts +0 -97
- package/src/utils/bom.ts +0 -14
- package/src/utils/encoding.ts +0 -153
- package/src/utils/guards.ts +0 -25
- package/src/utils/index.ts +0 -27
- package/src/utils/path.spec.ts +0 -44
- package/src/utils/path.ts +0 -397
- package/src/utils/scroll.ts +0 -120
- package/src/utils/utils.ts +0 -30
- package/src/utils/warn.ts +0 -13
package/dist/router.mjs
CHANGED
|
@@ -1,399 +1,366 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { LAYER_ID } from "./increment-id.mjs";
|
|
5
|
+
import { MicroApp } from "./micro-app.mjs";
|
|
6
|
+
import { Navigation } from "./navigation.mjs";
|
|
7
|
+
import { parsedOptions } from "./options.mjs";
|
|
8
|
+
import { Route } from "./route.mjs";
|
|
9
|
+
import { RouteTransition } from "./route-transition.mjs";
|
|
10
|
+
import { createLinkResolver } from "./router-link.mjs";
|
|
11
|
+
import { RouterMode, RouteType } from "./types.mjs";
|
|
4
12
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
isNotNullish,
|
|
14
|
+
isPlainObject,
|
|
15
|
+
isRouteMatched,
|
|
16
|
+
validateSsrRootElement
|
|
17
|
+
} from "./util.mjs";
|
|
18
|
+
const LAYER_SKIP_TYPES = /* @__PURE__ */ new Set([
|
|
19
|
+
RouteType.pushWindow,
|
|
20
|
+
RouteType.replaceWindow,
|
|
21
|
+
RouteType.replace,
|
|
22
|
+
RouteType.restartApp,
|
|
23
|
+
RouteType.pushLayer
|
|
24
|
+
]);
|
|
14
25
|
export class Router {
|
|
15
|
-
/**
|
|
16
|
-
* 当前路由对象的上级路由对象
|
|
17
|
-
*/
|
|
18
|
-
parent = null;
|
|
19
|
-
/* 路由配置 */
|
|
20
|
-
options;
|
|
21
|
-
/**
|
|
22
|
-
* 路由固定前置路径
|
|
23
|
-
* 需要注意的是如果使用函数返回 base,需要尽量保证相同的路径返回相同base
|
|
24
|
-
*/
|
|
25
|
-
base;
|
|
26
|
-
/* 路由模式 */
|
|
27
|
-
mode;
|
|
28
|
-
/* 路由匹配器 */
|
|
29
|
-
matcher;
|
|
30
|
-
/* 路由history类 */
|
|
31
|
-
history;
|
|
32
|
-
/* 滚动行为 */
|
|
33
|
-
scrollBehavior;
|
|
34
|
-
/* 当前路由信息 */
|
|
35
|
-
route = {
|
|
36
|
-
href: "",
|
|
37
|
-
origin: "",
|
|
38
|
-
host: "",
|
|
39
|
-
protocol: "",
|
|
40
|
-
hostname: "",
|
|
41
|
-
port: "",
|
|
42
|
-
pathname: "",
|
|
43
|
-
search: "",
|
|
44
|
-
hash: "",
|
|
45
|
-
params: {},
|
|
46
|
-
query: {},
|
|
47
|
-
queryArray: {},
|
|
48
|
-
state: {},
|
|
49
|
-
meta: {},
|
|
50
|
-
base: "",
|
|
51
|
-
path: "",
|
|
52
|
-
fullPath: "",
|
|
53
|
-
matched: []
|
|
54
|
-
};
|
|
55
26
|
constructor(options) {
|
|
27
|
+
__publicField(this, "options");
|
|
28
|
+
__publicField(this, "parsedOptions");
|
|
29
|
+
__publicField(this, "isLayer");
|
|
30
|
+
__publicField(this, "navigation");
|
|
31
|
+
__publicField(this, "microApp", new MicroApp());
|
|
32
|
+
// Route transition manager
|
|
33
|
+
__publicField(this, "transition", new RouteTransition(this));
|
|
56
34
|
this.options = options;
|
|
57
|
-
this.
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
this.history = createHistory({
|
|
68
|
-
router: this,
|
|
69
|
-
mode: this.mode
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/* 更新路由 */
|
|
73
|
-
updateRoute(route) {
|
|
74
|
-
var _a, _b, _c, _d, _e, _f;
|
|
75
|
-
const curAppType = (_b = (_a = this.route) == null ? void 0 : _a.matched[0]) == null ? void 0 : _b.appType;
|
|
76
|
-
const appType = (_c = route.matched[0]) == null ? void 0 : _c.appType;
|
|
77
|
-
this.applyRoute(route);
|
|
78
|
-
const curRegisterConfig = curAppType && this.registeredConfigMap[curAppType];
|
|
79
|
-
const registerConfig = appType && this.registeredConfigMap[appType];
|
|
80
|
-
if (registerConfig) {
|
|
81
|
-
const { mounted, generator } = registerConfig;
|
|
82
|
-
if (!mounted) {
|
|
83
|
-
registerConfig.config = generator(this);
|
|
84
|
-
(_d = registerConfig.config) == null ? void 0 : _d.mount();
|
|
85
|
-
registerConfig.mounted = true;
|
|
86
|
-
this.layerMap[this.layerId] = {
|
|
87
|
-
router: this,
|
|
88
|
-
config: registerConfig.config,
|
|
89
|
-
destroyed: false
|
|
90
|
-
};
|
|
91
|
-
if (!this.layerConfigList.find(
|
|
92
|
-
(item) => item.id === this.layerId
|
|
93
|
-
)) {
|
|
94
|
-
this.layerConfigList.push({
|
|
95
|
-
id: this.layerId,
|
|
96
|
-
depth: 0
|
|
97
|
-
});
|
|
98
|
-
}
|
|
35
|
+
this.parsedOptions = parsedOptions(options);
|
|
36
|
+
this.isLayer = this.parsedOptions.layer;
|
|
37
|
+
this.navigation = new Navigation(
|
|
38
|
+
this.parsedOptions,
|
|
39
|
+
(url, state) => {
|
|
40
|
+
this.transition.to(RouteType.unknown, {
|
|
41
|
+
url,
|
|
42
|
+
state
|
|
43
|
+
});
|
|
99
44
|
}
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
if (curAppType !== appType && curRegisterConfig) {
|
|
103
|
-
(_f = curRegisterConfig.config) == null ? void 0 : _f.destroy();
|
|
104
|
-
curRegisterConfig.mounted = false;
|
|
105
|
-
}
|
|
45
|
+
);
|
|
106
46
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
} else {
|
|
114
|
-
url = normalizePath(fullPath);
|
|
47
|
+
get route() {
|
|
48
|
+
const route = this.transition.route;
|
|
49
|
+
if (route === null) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
"No active route found. Please navigate to a route first using router.push() or router.replace()."
|
|
52
|
+
);
|
|
115
53
|
}
|
|
116
|
-
|
|
117
|
-
hash,
|
|
118
|
-
host,
|
|
119
|
-
hostname,
|
|
120
|
-
href,
|
|
121
|
-
origin,
|
|
122
|
-
pathname,
|
|
123
|
-
port,
|
|
124
|
-
protocol,
|
|
125
|
-
query
|
|
126
|
-
} = new URLParse(url);
|
|
127
|
-
Object.assign(
|
|
128
|
-
this.route,
|
|
129
|
-
{
|
|
130
|
-
href,
|
|
131
|
-
origin,
|
|
132
|
-
host,
|
|
133
|
-
protocol,
|
|
134
|
-
hostname,
|
|
135
|
-
port,
|
|
136
|
-
pathname,
|
|
137
|
-
search: query,
|
|
138
|
-
hash
|
|
139
|
-
},
|
|
140
|
-
route
|
|
141
|
-
);
|
|
54
|
+
return route;
|
|
142
55
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return this.history.resolve(location2);
|
|
56
|
+
get context() {
|
|
57
|
+
return this.parsedOptions.context;
|
|
146
58
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
async init(options = {}) {
|
|
59
|
+
get data() {
|
|
60
|
+
return this.parsedOptions.data;
|
|
61
|
+
}
|
|
62
|
+
get appId() {
|
|
63
|
+
return this.parsedOptions.appId;
|
|
64
|
+
}
|
|
65
|
+
get mode() {
|
|
66
|
+
return this.parsedOptions.mode;
|
|
67
|
+
}
|
|
68
|
+
get base() {
|
|
69
|
+
return this.parsedOptions.base;
|
|
70
|
+
}
|
|
71
|
+
get req() {
|
|
161
72
|
var _a;
|
|
162
|
-
|
|
163
|
-
await this.history.init({
|
|
164
|
-
replace
|
|
165
|
-
});
|
|
166
|
-
const layerId = getLatestLayerId();
|
|
167
|
-
this.layerId = layerId;
|
|
168
|
-
let layerMap = {};
|
|
169
|
-
let layerConfigList = [];
|
|
170
|
-
if (parent && route) {
|
|
171
|
-
const appType = (_a = route.matched[0]) == null ? void 0 : _a.appType;
|
|
172
|
-
if (!appType) return;
|
|
173
|
-
const registerConfig = parent.registeredConfigMap[appType];
|
|
174
|
-
if (!registerConfig) return;
|
|
175
|
-
parent.freeze();
|
|
176
|
-
this.registeredConfigMap = parent.registeredConfigMap;
|
|
177
|
-
const { generator } = registerConfig;
|
|
178
|
-
const config = generator(this);
|
|
179
|
-
config.mount();
|
|
180
|
-
config.updated();
|
|
181
|
-
layerMap = parent.layerMap;
|
|
182
|
-
layerMap[layerId] = {
|
|
183
|
-
router: this,
|
|
184
|
-
config,
|
|
185
|
-
destroyed: false
|
|
186
|
-
};
|
|
187
|
-
layerConfigList = parent.layerConfigList;
|
|
188
|
-
}
|
|
189
|
-
if (!layerConfigList.find((item) => item.id === layerId)) {
|
|
190
|
-
layerConfigList.push({
|
|
191
|
-
id: layerId,
|
|
192
|
-
depth: 0
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
this.parent = parent;
|
|
196
|
-
this.layerMap = layerMap;
|
|
197
|
-
this.layerConfigList = layerConfigList;
|
|
73
|
+
return (_a = this.parsedOptions.req) != null ? _a : null;
|
|
198
74
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
async destroy() {
|
|
75
|
+
get res() {
|
|
76
|
+
var _a;
|
|
77
|
+
return (_a = this.parsedOptions.res) != null ? _a : null;
|
|
203
78
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/* app配置注册 */
|
|
207
|
-
register(name, config) {
|
|
208
|
-
this.registeredConfigMap[name] = {
|
|
209
|
-
generator: config,
|
|
210
|
-
mounted: false
|
|
211
|
-
};
|
|
79
|
+
push(toInput) {
|
|
80
|
+
return this.transition.to(RouteType.push, toInput);
|
|
212
81
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
beforeEach: [],
|
|
216
|
-
afterEach: []
|
|
217
|
-
};
|
|
218
|
-
/* 注册全局路由前置守卫 */
|
|
219
|
-
beforeEach(guard) {
|
|
220
|
-
this.guards.beforeEach.push(guard);
|
|
82
|
+
replace(toInput) {
|
|
83
|
+
return this.transition.to(RouteType.replace, toInput);
|
|
221
84
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const i = this.guards.beforeEach.findIndex((item) => item === guard);
|
|
225
|
-
this.guards.beforeEach.splice(i, 1);
|
|
85
|
+
pushWindow(toInput) {
|
|
86
|
+
return this.transition.to(RouteType.pushWindow, toInput);
|
|
226
87
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
this.guards.afterEach.push(guard);
|
|
88
|
+
replaceWindow(toInput) {
|
|
89
|
+
return this.transition.to(RouteType.replaceWindow, toInput);
|
|
230
90
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
91
|
+
restartApp(toInput) {
|
|
92
|
+
return this.transition.to(
|
|
93
|
+
RouteType.restartApp,
|
|
94
|
+
toInput != null ? toInput : this.route.url.href
|
|
95
|
+
);
|
|
235
96
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
97
|
+
async back() {
|
|
98
|
+
const result = await this.navigation.go(-1);
|
|
99
|
+
if (result === null) {
|
|
100
|
+
this.parsedOptions.handleBackBoundary(this);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
return this.transition.to(RouteType.back, {
|
|
104
|
+
url: result.url,
|
|
105
|
+
state: result.state
|
|
106
|
+
});
|
|
239
107
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
await this.
|
|
108
|
+
async go(index) {
|
|
109
|
+
if (index === 0) return null;
|
|
110
|
+
const result = await this.navigation.go(index);
|
|
111
|
+
if (result === null) {
|
|
112
|
+
if (index < 0) {
|
|
113
|
+
this.parsedOptions.handleBackBoundary(this);
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
return this.transition.to(RouteType.go, {
|
|
118
|
+
url: result.url,
|
|
119
|
+
state: result.state
|
|
120
|
+
});
|
|
243
121
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
*/
|
|
252
|
-
layerConfigList = [];
|
|
253
|
-
/**
|
|
254
|
-
* 路由弹层id与路由实例的map
|
|
255
|
-
*/
|
|
256
|
-
layerMap = {};
|
|
257
|
-
/**
|
|
258
|
-
* 路由是否冻结
|
|
259
|
-
*/
|
|
260
|
-
isFrozen = false;
|
|
261
|
-
/**
|
|
262
|
-
* 路由冻结方法
|
|
263
|
-
*/
|
|
264
|
-
freeze() {
|
|
265
|
-
this.isFrozen = true;
|
|
122
|
+
async forward() {
|
|
123
|
+
const result = await this.navigation.go(1);
|
|
124
|
+
if (result === null) return null;
|
|
125
|
+
return this.transition.to(RouteType.forward, {
|
|
126
|
+
url: result.url,
|
|
127
|
+
state: result.state
|
|
128
|
+
});
|
|
266
129
|
}
|
|
267
130
|
/**
|
|
268
|
-
*
|
|
131
|
+
* Parse route location without performing actual navigation
|
|
132
|
+
*
|
|
133
|
+
* This method is used to parse route configuration and return the corresponding route object,
|
|
134
|
+
* but does not trigger actual page navigation. It is mainly used for the following scenarios:
|
|
135
|
+
* - Generate link URLs without jumping
|
|
136
|
+
* - Pre-check route matching
|
|
137
|
+
* - Get route parameters, meta information, etc.
|
|
138
|
+
* - Test the validity of route configuration
|
|
139
|
+
*
|
|
140
|
+
* @param toInput Target route location, can be a string path or route configuration object
|
|
141
|
+
* @returns Parsed route object containing complete route information
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* // Parse string path
|
|
146
|
+
* const route = router.resolve('/user/123');
|
|
147
|
+
* const url = route.url.href; // Get complete URL
|
|
148
|
+
*
|
|
149
|
+
* // Parse named route
|
|
150
|
+
* const userRoute = router.resolve({
|
|
151
|
+
* name: 'user',
|
|
152
|
+
* params: { id: '123' }
|
|
153
|
+
* });
|
|
154
|
+
* console.log(userRoute.params.id); // '123'
|
|
155
|
+
*
|
|
156
|
+
* // Check route validity
|
|
157
|
+
* const testRoute = router.resolve('/some/path');
|
|
158
|
+
* if (testRoute.matched.length > 0) {
|
|
159
|
+
* // Route matched successfully
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
269
162
|
*/
|
|
270
|
-
|
|
271
|
-
|
|
163
|
+
resolve(toInput, toType) {
|
|
164
|
+
var _a, _b;
|
|
165
|
+
return new Route({
|
|
166
|
+
options: this.parsedOptions,
|
|
167
|
+
toType,
|
|
168
|
+
toInput,
|
|
169
|
+
from: (_b = (_a = this.transition.route) == null ? void 0 : _a.url) != null ? _b : null
|
|
170
|
+
});
|
|
272
171
|
}
|
|
273
172
|
/**
|
|
274
|
-
*
|
|
275
|
-
*
|
|
173
|
+
* Check if the route matches the current route
|
|
174
|
+
*
|
|
175
|
+
* @param toRoute Target route object to compare
|
|
176
|
+
* @param matchType Match type
|
|
177
|
+
* - 'route': Route-level matching, compare if route configurations are the same
|
|
178
|
+
* - 'exact': Exact matching, compare if paths are completely the same
|
|
179
|
+
* - 'include': Include matching, check if current path contains target path
|
|
180
|
+
* @returns Whether it matches
|
|
276
181
|
*/
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (!inBrowser) {
|
|
282
|
-
this.push(location2);
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
const router = createRouter({
|
|
286
|
-
...this.options,
|
|
287
|
-
initUrl: route.fullPath
|
|
288
|
-
});
|
|
289
|
-
await router.init({ parent: this, route, replace: false });
|
|
182
|
+
isRouteMatched(toRoute, matchType = "include") {
|
|
183
|
+
const currentRoute = this.transition.route;
|
|
184
|
+
if (!currentRoute) return false;
|
|
185
|
+
return isRouteMatched(currentRoute, toRoute, matchType);
|
|
290
186
|
}
|
|
291
187
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
188
|
+
* Resolve router link configuration and return complete link data
|
|
189
|
+
*
|
|
190
|
+
* This method analyzes router link properties and returns a comprehensive
|
|
191
|
+
* link resolution result including route information, navigation functions,
|
|
192
|
+
* HTML attributes, and event handlers. It's primarily used for:
|
|
193
|
+
* - Framework-agnostic link component implementation
|
|
194
|
+
* - Generating link attributes and navigation handlers
|
|
195
|
+
* - Computing active states and CSS classes
|
|
196
|
+
* - Creating event handlers for different frameworks
|
|
197
|
+
*
|
|
198
|
+
* @param props Router link configuration properties
|
|
199
|
+
* @returns Complete link resolution result with all necessary data
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```typescript
|
|
203
|
+
* // Basic link resolution
|
|
204
|
+
* const linkData = router.resolveLink({
|
|
205
|
+
* to: '/user/123',
|
|
206
|
+
* type: 'push'
|
|
207
|
+
* });
|
|
208
|
+
*
|
|
209
|
+
* // Access resolved data
|
|
210
|
+
* console.log(linkData.route.path); // '/user/123'
|
|
211
|
+
* console.log(linkData.attributes.href); // Full href URL
|
|
212
|
+
* console.log(linkData.isActive); // Active state
|
|
213
|
+
*
|
|
214
|
+
* // Use navigation function
|
|
215
|
+
* linkData.navigate(); // Programmatic navigation
|
|
216
|
+
*
|
|
217
|
+
* // Get event handlers for React
|
|
218
|
+
* const handlers = linkData.createEventHandlers(name => `on${name.charAt(0).toUpperCase() + name.slice(1)}`);
|
|
219
|
+
* // handlers.onClick for React
|
|
220
|
+
* ```
|
|
295
221
|
*/
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
222
|
+
resolveLink(props) {
|
|
223
|
+
return createLinkResolver(this, props);
|
|
224
|
+
}
|
|
225
|
+
async createLayer(toInput) {
|
|
226
|
+
var _a;
|
|
227
|
+
const layerOptions = isPlainObject(toInput) && toInput.layer || {};
|
|
228
|
+
const zIndex = (_a = layerOptions.zIndex) != null ? _a : this.parsedOptions.zIndex + LAYER_ID.next();
|
|
229
|
+
let promiseResolve;
|
|
230
|
+
let promise = new Promise((resolve) => {
|
|
231
|
+
promiseResolve = resolve;
|
|
301
232
|
});
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
233
|
+
const router = new Router({
|
|
234
|
+
rootStyle: {
|
|
235
|
+
position: "fixed",
|
|
236
|
+
top: "0",
|
|
237
|
+
left: "0",
|
|
238
|
+
width: "100%",
|
|
239
|
+
height: "100%",
|
|
240
|
+
zIndex: String(zIndex),
|
|
241
|
+
background: "rgba(0,0,0,.6)",
|
|
242
|
+
display: "flex",
|
|
243
|
+
alignItems: "center",
|
|
244
|
+
justifyContent: "center"
|
|
245
|
+
},
|
|
246
|
+
...this.options,
|
|
247
|
+
context: this.parsedOptions.context,
|
|
248
|
+
mode: RouterMode.memory,
|
|
249
|
+
appId: void 0,
|
|
250
|
+
...layerOptions.routerOptions,
|
|
251
|
+
handleBackBoundary(router2) {
|
|
252
|
+
router2.destroy();
|
|
253
|
+
promiseResolve({
|
|
254
|
+
type: "close",
|
|
255
|
+
route: router2.route
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
handleLayerClose(router2, data) {
|
|
259
|
+
router2.destroy();
|
|
260
|
+
if (isNotNullish(data)) {
|
|
261
|
+
promiseResolve({
|
|
262
|
+
type: "success",
|
|
263
|
+
route: router2.route,
|
|
264
|
+
data
|
|
265
|
+
});
|
|
266
|
+
} else {
|
|
267
|
+
promiseResolve({
|
|
268
|
+
type: "close",
|
|
269
|
+
route: router2.route
|
|
270
|
+
});
|
|
314
271
|
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
}
|
|
272
|
+
},
|
|
273
|
+
layer: true
|
|
318
274
|
});
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (
|
|
326
|
-
|
|
275
|
+
const initRoute = await router.replace(toInput);
|
|
276
|
+
router.afterEach(async (to, from) => {
|
|
277
|
+
if (LAYER_SKIP_TYPES.has(to.type)) return;
|
|
278
|
+
let keepAlive = false;
|
|
279
|
+
if (layerOptions.keepAlive === "exact") {
|
|
280
|
+
keepAlive = to.path === initRoute.path;
|
|
281
|
+
} else if (layerOptions.keepAlive === "include") {
|
|
282
|
+
keepAlive = to.path.startsWith(initRoute.path);
|
|
283
|
+
} else if (typeof layerOptions.keepAlive === "function") {
|
|
284
|
+
keepAlive = await layerOptions.keepAlive(to, from, router);
|
|
327
285
|
} else {
|
|
328
|
-
|
|
286
|
+
if (layerOptions.shouldClose) {
|
|
287
|
+
console.warn(
|
|
288
|
+
"[esmx-router] RouteLayerOptions.shouldClose is deprecated. Use keepAlive instead. Note: shouldClose returns true to close, keepAlive returns true to keep alive."
|
|
289
|
+
);
|
|
290
|
+
keepAlive = !await layerOptions.shouldClose(
|
|
291
|
+
to,
|
|
292
|
+
from,
|
|
293
|
+
router
|
|
294
|
+
);
|
|
295
|
+
} else {
|
|
296
|
+
keepAlive = to.path === initRoute.path;
|
|
297
|
+
}
|
|
329
298
|
}
|
|
330
|
-
|
|
331
|
-
destroyList.forEach((id) => {
|
|
332
|
-
const layer = this.layerMap[id];
|
|
333
|
-
if (!layer.destroyed) {
|
|
334
|
-
const { router, config } = layer;
|
|
335
|
-
config.destroy();
|
|
299
|
+
if (!keepAlive) {
|
|
336
300
|
router.destroy();
|
|
337
|
-
|
|
338
|
-
|
|
301
|
+
promiseResolve({
|
|
302
|
+
type: "push",
|
|
303
|
+
route: to
|
|
304
|
+
});
|
|
339
305
|
}
|
|
340
306
|
});
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const state = {
|
|
363
|
-
...history.state,
|
|
364
|
-
[StateLayerConfigKey]: stateConfigList
|
|
307
|
+
if (layerOptions.push) {
|
|
308
|
+
router.navigation.pushHistoryState(
|
|
309
|
+
router.route.state,
|
|
310
|
+
router.route.url
|
|
311
|
+
);
|
|
312
|
+
promise = promise.then(async (result) => {
|
|
313
|
+
await this.navigation.backHistoryState();
|
|
314
|
+
return result;
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
if (layerOptions.autoPush) {
|
|
318
|
+
promise = promise.then(async (result) => {
|
|
319
|
+
if (result.type === "push") {
|
|
320
|
+
await this.push(result.route.url.href);
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
promise,
|
|
327
|
+
router
|
|
365
328
|
};
|
|
366
|
-
window.history.replaceState(state, "", route.fullPath);
|
|
367
329
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
pushWindow(location2) {
|
|
372
|
-
this.history.pushWindow(location2);
|
|
330
|
+
async pushLayer(toInput) {
|
|
331
|
+
const result = await this.transition.to(RouteType.pushLayer, toInput);
|
|
332
|
+
return result.handleResult;
|
|
373
333
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
replaceWindow(location2) {
|
|
378
|
-
this.history.replaceWindow(location2);
|
|
334
|
+
closeLayer(data) {
|
|
335
|
+
if (!this.isLayer) return;
|
|
336
|
+
this.parsedOptions.handleLayerClose(this, data);
|
|
379
337
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
338
|
+
async renderToString(throwError = false) {
|
|
339
|
+
var _a, _b;
|
|
340
|
+
try {
|
|
341
|
+
const result = await ((_b = (_a = this.microApp.app) == null ? void 0 : _a.renderToString) == null ? void 0 : _b.call(_a));
|
|
342
|
+
const trimmed = result == null ? void 0 : result.trim();
|
|
343
|
+
const hasContent = trimmed && trimmed.length > 0;
|
|
344
|
+
if (hasContent && process.env.NODE_ENV !== "production") {
|
|
345
|
+
validateSsrRootElement(trimmed);
|
|
346
|
+
}
|
|
347
|
+
const ssrAttr = hasContent ? " data-ssr" : "";
|
|
348
|
+
return '<div id="'.concat(this.appId, '"').concat(ssrAttr, ">").concat(result != null ? result : "", "</div>");
|
|
349
|
+
} catch (e) {
|
|
350
|
+
if (throwError) throw e;
|
|
351
|
+
else console.error("[@esmx/router] SSR render failed:", e);
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
383
354
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
this.history.forward();
|
|
355
|
+
beforeEach(guard) {
|
|
356
|
+
return this.transition.beforeEach(guard);
|
|
387
357
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
this.history.back();
|
|
358
|
+
afterEach(guard) {
|
|
359
|
+
return this.transition.afterEach(guard);
|
|
391
360
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
361
|
+
destroy() {
|
|
362
|
+
this.transition.destroy();
|
|
363
|
+
this.navigation.destroy();
|
|
364
|
+
this.microApp.destroy();
|
|
395
365
|
}
|
|
396
366
|
}
|
|
397
|
-
export function createRouter(options) {
|
|
398
|
-
return new Router(options);
|
|
399
|
-
}
|