@esmx/router 3.0.0-rc.18 → 3.0.0-rc.20

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.
Files changed (158) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +70 -0
  3. package/README.zh-CN.md +70 -0
  4. package/dist/error.d.ts +23 -0
  5. package/dist/error.mjs +61 -0
  6. package/dist/increment-id.d.ts +7 -0
  7. package/dist/increment-id.mjs +11 -0
  8. package/dist/index.d.ts +5 -3
  9. package/dist/index.mjs +14 -3
  10. package/dist/index.test.mjs +8 -0
  11. package/dist/location.d.ts +15 -0
  12. package/dist/location.mjs +53 -0
  13. package/dist/location.test.d.ts +8 -0
  14. package/dist/location.test.mjs +370 -0
  15. package/dist/matcher.d.ts +3 -0
  16. package/dist/matcher.mjs +44 -0
  17. package/dist/matcher.test.mjs +1492 -0
  18. package/dist/micro-app.d.ts +18 -0
  19. package/dist/micro-app.dom.test.d.ts +1 -0
  20. package/dist/micro-app.dom.test.mjs +532 -0
  21. package/dist/micro-app.mjs +80 -0
  22. package/dist/navigation.d.ts +43 -0
  23. package/dist/navigation.mjs +143 -0
  24. package/dist/navigation.test.d.ts +1 -0
  25. package/dist/navigation.test.mjs +681 -0
  26. package/dist/options.d.ts +4 -0
  27. package/dist/options.mjs +88 -0
  28. package/dist/route-task.d.ts +40 -0
  29. package/dist/route-task.mjs +75 -0
  30. package/dist/route-task.test.d.ts +1 -0
  31. package/dist/route-task.test.mjs +673 -0
  32. package/dist/route-transition.d.ts +53 -0
  33. package/dist/route-transition.mjs +307 -0
  34. package/dist/route-transition.test.d.ts +1 -0
  35. package/dist/route-transition.test.mjs +146 -0
  36. package/dist/route.d.ts +72 -0
  37. package/dist/route.mjs +194 -0
  38. package/dist/route.test.d.ts +1 -0
  39. package/dist/route.test.mjs +1664 -0
  40. package/dist/router-back.test.d.ts +1 -0
  41. package/dist/router-back.test.mjs +361 -0
  42. package/dist/router-forward.test.d.ts +1 -0
  43. package/dist/router-forward.test.mjs +376 -0
  44. package/dist/router-go.test.d.ts +1 -0
  45. package/dist/router-go.test.mjs +73 -0
  46. package/dist/router-guards-cleanup.test.d.ts +1 -0
  47. package/dist/router-guards-cleanup.test.mjs +437 -0
  48. package/dist/router-link.d.ts +10 -0
  49. package/dist/router-link.mjs +126 -0
  50. package/dist/router-push.test.d.ts +1 -0
  51. package/dist/router-push.test.mjs +115 -0
  52. package/dist/router-replace.test.d.ts +1 -0
  53. package/dist/router-replace.test.mjs +114 -0
  54. package/dist/router-resolve.test.d.ts +1 -0
  55. package/dist/router-resolve.test.mjs +393 -0
  56. package/dist/router-restart-app.dom.test.d.ts +1 -0
  57. package/dist/router-restart-app.dom.test.mjs +616 -0
  58. package/dist/router-window-navigation.test.d.ts +1 -0
  59. package/dist/router-window-navigation.test.mjs +359 -0
  60. package/dist/router.d.ts +109 -102
  61. package/dist/router.mjs +260 -361
  62. package/dist/types.d.ts +246 -0
  63. package/dist/types.mjs +18 -0
  64. package/dist/util.d.ts +26 -0
  65. package/dist/util.mjs +53 -0
  66. package/dist/util.test.d.ts +1 -0
  67. package/dist/util.test.mjs +1020 -0
  68. package/package.json +10 -13
  69. package/src/error.ts +84 -0
  70. package/src/increment-id.ts +12 -0
  71. package/src/index.test.ts +9 -0
  72. package/src/index.ts +54 -3
  73. package/src/location.test.ts +406 -0
  74. package/src/location.ts +96 -0
  75. package/src/matcher.test.ts +1685 -0
  76. package/src/matcher.ts +59 -0
  77. package/src/micro-app.dom.test.ts +708 -0
  78. package/src/micro-app.ts +101 -0
  79. package/src/navigation.test.ts +858 -0
  80. package/src/navigation.ts +195 -0
  81. package/src/options.ts +131 -0
  82. package/src/route-task.test.ts +901 -0
  83. package/src/route-task.ts +105 -0
  84. package/src/route-transition.test.ts +178 -0
  85. package/src/route-transition.ts +425 -0
  86. package/src/route.test.ts +2014 -0
  87. package/src/route.ts +308 -0
  88. package/src/router-back.test.ts +487 -0
  89. package/src/router-forward.test.ts +506 -0
  90. package/src/router-go.test.ts +91 -0
  91. package/src/router-guards-cleanup.test.ts +595 -0
  92. package/src/router-link.ts +235 -0
  93. package/src/router-push.test.ts +140 -0
  94. package/src/router-replace.test.ts +139 -0
  95. package/src/router-resolve.test.ts +475 -0
  96. package/src/router-restart-app.dom.test.ts +783 -0
  97. package/src/router-window-navigation.test.ts +457 -0
  98. package/src/router.ts +289 -470
  99. package/src/types.ts +341 -0
  100. package/src/util.test.ts +1262 -0
  101. package/src/util.ts +116 -0
  102. package/dist/history/abstract.d.ts +0 -29
  103. package/dist/history/abstract.mjs +0 -107
  104. package/dist/history/base.d.ts +0 -79
  105. package/dist/history/base.mjs +0 -275
  106. package/dist/history/html.d.ts +0 -30
  107. package/dist/history/html.mjs +0 -183
  108. package/dist/history/index.d.ts +0 -7
  109. package/dist/history/index.mjs +0 -16
  110. package/dist/matcher/create-matcher.d.ts +0 -5
  111. package/dist/matcher/create-matcher.mjs +0 -218
  112. package/dist/matcher/create-matcher.spec.mjs +0 -0
  113. package/dist/matcher/index.d.ts +0 -1
  114. package/dist/matcher/index.mjs +0 -1
  115. package/dist/task-pipe/index.d.ts +0 -1
  116. package/dist/task-pipe/index.mjs +0 -1
  117. package/dist/task-pipe/task.d.ts +0 -30
  118. package/dist/task-pipe/task.mjs +0 -66
  119. package/dist/types/index.d.ts +0 -694
  120. package/dist/types/index.mjs +0 -6
  121. package/dist/utils/bom.d.ts +0 -5
  122. package/dist/utils/bom.mjs +0 -10
  123. package/dist/utils/encoding.d.ts +0 -48
  124. package/dist/utils/encoding.mjs +0 -44
  125. package/dist/utils/guards.d.ts +0 -9
  126. package/dist/utils/guards.mjs +0 -12
  127. package/dist/utils/index.d.ts +0 -7
  128. package/dist/utils/index.mjs +0 -27
  129. package/dist/utils/path.d.ts +0 -60
  130. package/dist/utils/path.mjs +0 -282
  131. package/dist/utils/path.spec.mjs +0 -27
  132. package/dist/utils/scroll.d.ts +0 -25
  133. package/dist/utils/scroll.mjs +0 -59
  134. package/dist/utils/utils.d.ts +0 -16
  135. package/dist/utils/utils.mjs +0 -11
  136. package/dist/utils/warn.d.ts +0 -2
  137. package/dist/utils/warn.mjs +0 -12
  138. package/src/history/abstract.ts +0 -149
  139. package/src/history/base.ts +0 -408
  140. package/src/history/html.ts +0 -228
  141. package/src/history/index.ts +0 -20
  142. package/src/matcher/create-matcher.spec.ts +0 -3
  143. package/src/matcher/create-matcher.ts +0 -292
  144. package/src/matcher/index.ts +0 -1
  145. package/src/task-pipe/index.ts +0 -1
  146. package/src/task-pipe/task.ts +0 -97
  147. package/src/types/index.ts +0 -858
  148. package/src/utils/bom.ts +0 -14
  149. package/src/utils/encoding.ts +0 -153
  150. package/src/utils/guards.ts +0 -25
  151. package/src/utils/index.ts +0 -27
  152. package/src/utils/path.spec.ts +0 -32
  153. package/src/utils/path.ts +0 -418
  154. package/src/utils/scroll.ts +0 -120
  155. package/src/utils/utils.ts +0 -30
  156. package/src/utils/warn.ts +0 -13
  157. /package/dist/{matcher/create-matcher.spec.d.ts → index.test.d.ts} +0 -0
  158. /package/dist/{utils/path.spec.d.ts → matcher.test.d.ts} +0 -0
package/dist/router.mjs CHANGED
@@ -1,399 +1,298 @@
1
- import URLParse from "url-parse";
2
- import { createHistory } from "./history/index.mjs";
3
- import { createRouterMatcher } from "./matcher/index.mjs";
4
- import {
5
- RouterMode,
6
- StateLayerConfigKey
7
- } from "./types/index.mjs";
8
- import { inBrowser, normalizePath, regexDomain } from "./utils/index.mjs";
9
- const baseValue = Number(Date.now());
10
- let layerIdOffset = 0;
11
- function getLatestLayerId() {
12
- return baseValue + ++layerIdOffset;
13
- }
1
+ import { LAYER_ID } from "./increment-id.mjs";
2
+ import { MicroApp } from "./micro-app.mjs";
3
+ import { Navigation } from "./navigation.mjs";
4
+ import { parsedOptions } from "./options.mjs";
5
+ import { Route } from "./route.mjs";
6
+ import { RouteTransition } from "./route-transition.mjs";
7
+ import { createLinkResolver } from "./router-link.mjs";
8
+ import { RouteType, RouterMode } from "./types.mjs";
9
+ import { isNotNullish, isPlainObject, isRouteMatched } from "./util.mjs";
14
10
  export class Router {
15
- /**
16
- * 当前路由对象的上级路由对象
17
- */
18
- parent = null;
19
- /* 路由配置 */
20
11
  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
- constructor(options) {
56
- this.options = options;
57
- this.matcher = createRouterMatcher(options.routes || []);
58
- this.mode = options.mode || (inBrowser ? RouterMode.HISTORY : RouterMode.ABSTRACT);
59
- this.base = options.base || "";
60
- this.scrollBehavior = options.scrollBehavior || ((to, from, savedPosition) => {
61
- if (savedPosition) return savedPosition;
62
- return {
63
- left: 0,
64
- top: 0
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
- }
99
- }
100
- (_e = registerConfig.config) == null ? void 0 : _e.updated();
101
- }
102
- if (curAppType !== appType && curRegisterConfig) {
103
- (_f = curRegisterConfig.config) == null ? void 0 : _f.destroy();
104
- curRegisterConfig.mounted = false;
12
+ parsedOptions;
13
+ isLayer;
14
+ navigation;
15
+ microApp = new MicroApp();
16
+ // Route transition manager
17
+ transition = new RouteTransition(this);
18
+ get route() {
19
+ const route = this.transition.route;
20
+ if (route === null) {
21
+ throw new Error(
22
+ "No active route found. Please navigate to a route first using router.push() or router.replace()."
23
+ );
105
24
  }
25
+ return route;
106
26
  }
107
- /* 应用路由 */
108
- applyRoute(route) {
109
- let url = "";
110
- const { fullPath } = route;
111
- if (inBrowser && !regexDomain.test(fullPath)) {
112
- url = normalizePath(fullPath, location.origin);
113
- } else {
114
- url = normalizePath(fullPath);
115
- }
116
- const {
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
- );
27
+ get root() {
28
+ return this.parsedOptions.root;
142
29
  }
143
- /* 解析路由 */
144
- resolve(location2) {
145
- return this.history.resolve(location2);
30
+ get req() {
31
+ return this.parsedOptions.req ?? null;
146
32
  }
147
- /**
148
- * 新增单个路由匹配规则
149
- */
150
- // addRoutes(routes: RouteConfig[]) {
151
- // this.matcher.addRoutes(routes);
152
- // }
153
- /**
154
- * 新增多个路由匹配规则
155
- */
156
- // addRoute(route: RouteConfig): void {
157
- // this.matcher.addRoute(route);
158
- // }
159
- /* 初始化 */
160
- async init(options = {}) {
161
- var _a;
162
- const { parent = null, route, replace = true } = options;
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;
33
+ get res() {
34
+ return this.parsedOptions.res ?? null;
198
35
  }
199
- /**
200
- * 卸载方法
201
- */
202
- async destroy() {
36
+ constructor(options) {
37
+ this.options = options;
38
+ this.parsedOptions = parsedOptions(options);
39
+ this.isLayer = this.parsedOptions.layer;
40
+ this.navigation = new Navigation(
41
+ this.parsedOptions,
42
+ (url, state) => {
43
+ this.transition.to(RouteType.unknown, {
44
+ url,
45
+ state
46
+ });
47
+ }
48
+ );
203
49
  }
204
- /* 已注册的app配置 */
205
- registeredConfigMap = {};
206
- /* app配置注册 */
207
- register(name, config) {
208
- this.registeredConfigMap[name] = {
209
- generator: config,
210
- mounted: false
211
- };
50
+ push(toInput) {
51
+ return this.transition.to(RouteType.push, toInput);
212
52
  }
213
- /* 全局路由守卫 */
214
- guards = {
215
- beforeEach: [],
216
- afterEach: []
217
- };
218
- /* 注册全局路由前置守卫 */
219
- beforeEach(guard) {
220
- this.guards.beforeEach.push(guard);
53
+ replace(toInput) {
54
+ return this.transition.to(RouteType.replace, toInput);
221
55
  }
222
- /* 卸载全局路由前置守卫 */
223
- unBindBeforeEach(guard) {
224
- const i = this.guards.beforeEach.findIndex((item) => item === guard);
225
- this.guards.beforeEach.splice(i, 1);
56
+ pushWindow(toInput) {
57
+ return this.transition.to(RouteType.pushWindow, toInput);
226
58
  }
227
- /* 注册全局路由后置守卫 */
228
- afterEach(guard) {
229
- this.guards.afterEach.push(guard);
59
+ replaceWindow(toInput) {
60
+ return this.transition.to(RouteType.replaceWindow, toInput);
230
61
  }
231
- /* 卸载全局路由后置守卫 */
232
- unBindAfterEach(guard) {
233
- const i = this.guards.afterEach.findIndex((item) => item === guard);
234
- this.guards.afterEach.splice(i, 1);
62
+ restartApp(toInput) {
63
+ return this.transition.to(
64
+ RouteType.restartApp,
65
+ toInput ?? this.route.url.href
66
+ );
235
67
  }
236
- /* 路由跳转方法,会创建新的历史记录 */
237
- async push(location2) {
238
- await this.history.push(location2);
68
+ async back() {
69
+ const result = await this.navigation.go(-1);
70
+ if (result === null) {
71
+ this.parsedOptions.handleBackBoundary(this);
72
+ return null;
73
+ }
74
+ return this.transition.to(RouteType.back, {
75
+ url: result.url,
76
+ state: result.state
77
+ });
239
78
  }
240
- /* 路由跳转方法,会替换当前的历史记录 */
241
- async replace(location2) {
242
- await this.history.replace(location2);
79
+ async go(index) {
80
+ if (index === 0) return null;
81
+ const result = await this.navigation.go(index);
82
+ if (result === null) {
83
+ if (index < 0) {
84
+ this.parsedOptions.handleBackBoundary(this);
85
+ }
86
+ return null;
87
+ }
88
+ return this.transition.to(RouteType.go, {
89
+ url: result.url,
90
+ state: result.state
91
+ });
243
92
  }
244
- /**
245
- * 当前路由弹层id,用于区分不同的路由弹层
246
- */
247
- layerId = 0;
248
- /**
249
- * 路由弹层配置
250
- * key为路由弹层id
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;
93
+ async forward() {
94
+ const result = await this.navigation.go(1);
95
+ if (result === null) return null;
96
+ return this.transition.to(RouteType.forward, {
97
+ url: result.url,
98
+ state: result.state
99
+ });
266
100
  }
267
101
  /**
268
- * 路由解冻方法
102
+ * Parse route location without performing actual navigation
103
+ *
104
+ * This method is used to parse route configuration and return the corresponding route object,
105
+ * but does not trigger actual page navigation. It is mainly used for the following scenarios:
106
+ * - Generate link URLs without jumping
107
+ * - Pre-check route matching
108
+ * - Get route parameters, meta information, etc.
109
+ * - Test the validity of route configuration
110
+ *
111
+ * @param toInput Target route location, can be a string path or route configuration object
112
+ * @returns Parsed route object containing complete route information
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * // Parse string path
117
+ * const route = router.resolve('/user/123');
118
+ * const url = route.url.href; // Get complete URL
119
+ *
120
+ * // Parse named route
121
+ * const userRoute = router.resolve({
122
+ * name: 'user',
123
+ * params: { id: '123' }
124
+ * });
125
+ * console.log(userRoute.params.id); // '123'
126
+ *
127
+ * // Check route validity
128
+ * const testRoute = router.resolve('/some/path');
129
+ * if (testRoute.matched.length > 0) {
130
+ * // Route matched successfully
131
+ * }
132
+ * ```
269
133
  */
270
- unfreeze() {
271
- this.isFrozen = false;
134
+ resolve(toInput, toType) {
135
+ var _a;
136
+ return new Route({
137
+ options: this.parsedOptions,
138
+ toType,
139
+ toInput,
140
+ from: ((_a = this.transition.route) == null ? void 0 : _a.url) ?? null
141
+ });
272
142
  }
273
143
  /**
274
- * 打开路由弹层方法,会创建新的路由实例并调用注册的 register 方法
275
- * 服务端会使用 push 作为替代
144
+ * Check if the route matches the current route
145
+ *
146
+ * @param targetRoute Target route object to compare
147
+ * @param matchType Match type
148
+ * - 'route': Route-level matching, compare if route configurations are the same
149
+ * - 'exact': Exact matching, compare if paths are completely the same
150
+ * - 'include': Include matching, check if current path contains target path
151
+ * @returns Whether it matches
276
152
  */
277
- async pushLayer(location2) {
278
- if (this.isFrozen) return;
279
- const route = this.resolve(location2);
280
- if (route.fullPath === this.route.fullPath) return;
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 });
153
+ isRouteMatched(targetRoute, matchType = "include") {
154
+ const currentRoute = this.transition.route;
155
+ if (!currentRoute) return false;
156
+ return isRouteMatched(currentRoute, targetRoute, matchType);
290
157
  }
291
158
  /**
292
- * 更新路由弹层方法
293
- * @param state 参数为history.state
294
- * @description 没有传入 state 时使用当前配置更新 history.state,传入了 state 时使用传入的 state 更新当前配置
159
+ * Resolve router link configuration and return complete link data
160
+ *
161
+ * This method analyzes router link properties and returns a comprehensive
162
+ * link resolution result including route information, navigation functions,
163
+ * HTML attributes, and event handlers. It's primarily used for:
164
+ * - Framework-agnostic link component implementation
165
+ * - Generating link attributes and navigation handlers
166
+ * - Computing active states and CSS classes
167
+ * - Creating event handlers for different frameworks
168
+ *
169
+ * @param props Router link configuration properties
170
+ * @returns Complete link resolution result with all necessary data
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * // Basic link resolution
175
+ * const linkData = router.resolveLink({
176
+ * to: '/user/123',
177
+ * type: 'push'
178
+ * });
179
+ *
180
+ * // Access resolved data
181
+ * console.log(linkData.route.path); // '/user/123'
182
+ * console.log(linkData.attributes.href); // Full href URL
183
+ * console.log(linkData.isActive); // Active state
184
+ *
185
+ * // Use navigation function
186
+ * linkData.navigate(); // Programmatic navigation
187
+ *
188
+ * // Get event handlers for React
189
+ * const handlers = linkData.getEventHandlers(name => `on${name.charAt(0).toUpperCase() + name.slice(1)}`);
190
+ * // handlers.onClick for React
191
+ * ```
295
192
  */
296
- checkLayerState(state) {
297
- const stateLayerConfigList = state[StateLayerConfigKey] || [];
298
- const layerConfigList = Object.keys(this.layerMap).map(Number);
299
- const stateLayerIdList = stateLayerConfigList.map(({ id }) => id).filter((id) => {
300
- return layerConfigList.includes(id);
193
+ resolveLink(props) {
194
+ return createLinkResolver(this, props);
195
+ }
196
+ async createLayer(toInput) {
197
+ const layerOptions = (isPlainObject(toInput) ? toInput.layer : null) || {};
198
+ const zIndex = layerOptions.zIndex ?? this.parsedOptions.zIndex + LAYER_ID.next();
199
+ let promiseResolve;
200
+ const promise = new Promise((resolve) => {
201
+ promiseResolve = resolve;
301
202
  });
302
- if (stateLayerIdList.length === 0) {
303
- return false;
304
- }
305
- if (stateLayerIdList.length === 1 && stateLayerIdList[0] === this.layerId) {
306
- return false;
307
- }
308
- const createList = [];
309
- const destroyList = [];
310
- Object.entries(this.layerMap).forEach(([key, value]) => {
311
- if (stateLayerIdList.includes(Number(key))) {
312
- if (value.destroyed) {
313
- createList.push(Number(key));
203
+ const router = new Router({
204
+ ...this.options,
205
+ mode: RouterMode.memory,
206
+ rootStyle: {
207
+ position: "fixed",
208
+ top: "0",
209
+ left: "0",
210
+ width: "100%",
211
+ height: "100%",
212
+ zIndex: String(zIndex),
213
+ background: "rgba(0,0,0,.6)",
214
+ display: "flex",
215
+ alignItems: "center",
216
+ justifyContent: "center"
217
+ },
218
+ root: void 0,
219
+ ...layerOptions.routerOptions,
220
+ handleBackBoundary(router2) {
221
+ router2.destroy();
222
+ promiseResolve({
223
+ type: "close",
224
+ route: router2.route
225
+ });
226
+ },
227
+ handleLayerClose(router2, data) {
228
+ router2.destroy();
229
+ if (isNotNullish(data)) {
230
+ promiseResolve({
231
+ type: "success",
232
+ route: router2.route,
233
+ data
234
+ });
235
+ } else {
236
+ promiseResolve({
237
+ type: "close",
238
+ route: router2.route
239
+ });
314
240
  }
315
- } else {
316
- destroyList.push(Number(key));
317
- }
318
- });
319
- if (createList.length === 0 && destroyList.length === 0) {
320
- return false;
321
- }
322
- const activeId = Math.max(...stateLayerIdList);
323
- layerConfigList.forEach((id) => {
324
- const { router } = this.layerMap[id];
325
- if (activeId === id) {
326
- router.unfreeze();
327
- } else {
328
- router.freeze();
329
- }
330
- });
331
- destroyList.forEach((id) => {
332
- const layer = this.layerMap[id];
333
- if (!layer.destroyed) {
334
- const { router, config } = layer;
335
- config.destroy();
336
- router.destroy();
337
- router.freeze();
338
- layer.destroyed = true;
339
- }
241
+ },
242
+ layer: true
340
243
  });
341
- createList.forEach((id) => {
342
- const layer = this.layerMap[id];
343
- if (layer.destroyed) {
344
- const { router, config } = layer;
345
- config.mount();
346
- router.unfreeze();
347
- layer.destroyed = false;
244
+ await router.replace(toInput);
245
+ router.afterEach((to, from) => {
246
+ if (layerOptions.shouldClose) {
247
+ const result = layerOptions.shouldClose(to, from, router);
248
+ if (result === false) {
249
+ router.destroy();
250
+ promiseResolve({
251
+ type: "push",
252
+ route: to
253
+ });
254
+ }
348
255
  }
349
256
  });
350
- this.layerConfigList = stateLayerConfigList;
351
- return true;
352
- }
353
- updateLayerState(route) {
354
- const layerConfig = this.layerConfigList.find((item) => {
355
- return item.id === this.layerId;
356
- });
357
- if (layerConfig) layerConfig.depth++;
358
- const stateConfigList = this.layerConfigList.filter(({ id }) => {
359
- var _a;
360
- return !((_a = this.layerMap[id]) == null ? void 0 : _a.destroyed);
361
- });
362
- const state = {
363
- ...history.state,
364
- [StateLayerConfigKey]: stateConfigList
257
+ if (layerOptions.push) {
258
+ router.navigation.pushHistoryState(
259
+ router.route.state,
260
+ router.route.url
261
+ );
262
+ }
263
+ return {
264
+ promise,
265
+ router
365
266
  };
366
- window.history.replaceState(state, "", route.fullPath);
367
267
  }
368
- /**
369
- * 新开浏览器窗口的方法,在服务端会调用 push 作为替代
370
- */
371
- pushWindow(location2) {
372
- this.history.pushWindow(location2);
268
+ async pushLayer(toInput) {
269
+ const result = await this.transition.to(RouteType.pushLayer, toInput);
270
+ return result.handleResult;
373
271
  }
374
- /**
375
- * 替换当前浏览器窗口的方法,在服务端会调用 replace 作为替代
376
- */
377
- replaceWindow(location2) {
378
- this.history.replaceWindow(location2);
272
+ closeLayer(data) {
273
+ if (!this.isLayer) return;
274
+ this.parsedOptions.handleLayerClose(this, data);
379
275
  }
380
- /* 前往特定路由历史记录的方法,可以在历史记录前后移动 */
381
- go(delta = 0) {
382
- this.history.go(delta);
276
+ async renderToString(throwError = false) {
277
+ var _a, _b;
278
+ try {
279
+ const result = await ((_b = (_a = this.microApp.app) == null ? void 0 : _a.renderToString) == null ? void 0 : _b.call(_a));
280
+ return result ?? null;
281
+ } catch (e) {
282
+ if (throwError) throw e;
283
+ else console.error(e);
284
+ return null;
285
+ }
383
286
  }
384
- /* 路由历史记录前进方法 */
385
- forward() {
386
- this.history.forward();
287
+ beforeEach(guard) {
288
+ return this.transition.beforeEach(guard);
387
289
  }
388
- /* 路由历史记录后退方法 */
389
- back() {
390
- this.history.back();
290
+ afterEach(guard) {
291
+ return this.transition.afterEach(guard);
391
292
  }
392
- /* 根据获取当前所有活跃的路由Record对象 */
393
- getRoutes() {
394
- return this.matcher.getRoutes();
293
+ destroy() {
294
+ this.transition.destroy();
295
+ this.navigation.destroy();
296
+ this.microApp.destroy();
395
297
  }
396
298
  }
397
- export function createRouter(options) {
398
- return new Router(options);
399
- }