@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/src/types.ts ADDED
@@ -0,0 +1,341 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { MatchFunction } from 'path-to-regexp';
3
+ import type { Route } from './route';
4
+ import type { Router } from './router';
5
+
6
+ // Re-export Route type for backward compatibility
7
+ export type { Route };
8
+
9
+ // ============================================================================
10
+ // Utility types
11
+ // ============================================================================
12
+ export type Awaitable<T> = T | Promise<T>;
13
+
14
+ // ============================================================================
15
+ // Core enums
16
+ // ============================================================================
17
+ export enum RouterMode {
18
+ history = 'history',
19
+ memory = 'memory'
20
+ }
21
+
22
+ export enum RouteType {
23
+ push = 'push',
24
+ replace = 'replace',
25
+ restartApp = 'restartApp',
26
+ go = 'go',
27
+ forward = 'forward',
28
+ back = 'back',
29
+ unknown = 'unknown',
30
+ pushWindow = 'pushWindow',
31
+ replaceWindow = 'replaceWindow',
32
+ pushLayer = 'pushLayer'
33
+ }
34
+
35
+ // ============================================================================
36
+ // Hook function types
37
+ // ============================================================================
38
+ export type RouteConfirmHookResult =
39
+ | void
40
+ | false
41
+ | RouteLocationInput
42
+ | RouteHandleHook;
43
+
44
+ export type RouteConfirmHook = (
45
+ to: Route,
46
+ from: Route | null,
47
+ router: Router
48
+ ) => Awaitable<RouteConfirmHookResult>;
49
+
50
+ export type RouteVerifyHook = (
51
+ to: Route,
52
+ from: Route | null,
53
+ router: Router
54
+ ) => Awaitable<boolean>;
55
+
56
+ export type RouteHandleHook = (
57
+ to: Route,
58
+ from: Route | null,
59
+ router: Router
60
+ ) => Awaitable<RouteHandleResult>;
61
+
62
+ export type RouteNotifyHook = (
63
+ to: Route,
64
+ from: Route | null,
65
+ router: Router
66
+ ) => void;
67
+
68
+ // ============================================================================
69
+ // Basic data types
70
+ // ============================================================================
71
+ export type RouteMeta = Record<string | symbol, unknown>;
72
+ export type RouteState = Record<string, unknown>;
73
+ export type RouteHandleResult = unknown | null | void;
74
+
75
+ /**
76
+ * Route matching type
77
+ * - 'route': Route-level matching, compare if route configurations are the same
78
+ * - 'exact': Exact matching, compare if paths are exactly the same
79
+ * - 'include': Include matching, check if current path contains target path
80
+ */
81
+ export type RouteMatchType = 'route' | 'exact' | 'include';
82
+
83
+ // ============================================================================
84
+ // Route location and config types
85
+ // ============================================================================
86
+ export interface RouteLocation {
87
+ path?: string;
88
+ url?: string | URL;
89
+ params?: Record<string, string>;
90
+ query?: Record<string, string | undefined>;
91
+ queryArray?: Record<string, string[] | undefined>;
92
+ hash?: string;
93
+ state?: RouteState;
94
+ keepScrollPosition?: boolean;
95
+ statusCode?: number | null;
96
+ layer?: RouteLayerOptions | null;
97
+ confirm?: RouteConfirmHook | null;
98
+ }
99
+ export type RouteLocationInput = RouteLocation | string;
100
+
101
+ export interface RouteConfig {
102
+ /** Pass a URL-encoded path */
103
+ path: string;
104
+ component?: unknown;
105
+ children?: RouteConfig[];
106
+ redirect?: RouteLocationInput | RouteConfirmHook;
107
+ meta?: RouteMeta;
108
+ app?: string | RouterMicroAppCallback;
109
+ asyncComponent?: () => Promise<unknown>;
110
+ beforeEnter?: RouteConfirmHook;
111
+ beforeUpdate?: RouteConfirmHook;
112
+ beforeLeave?: RouteConfirmHook;
113
+
114
+ /**
115
+ * Route override function for hybrid app development
116
+ *
117
+ * Note: Override is not executed during initial route loading
118
+ *
119
+ * @param to Target route
120
+ * @param from Source route
121
+ * @returns Function to execute instead of default routing, or void for default
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * override: (to, from) => {
126
+ * if (isInApp()) {
127
+ * return () => JSBridge.openNative();
128
+ * }
129
+ * }
130
+ * ```
131
+ */
132
+ override?: RouteConfirmHook;
133
+ }
134
+
135
+ export interface RouteParsedConfig extends RouteConfig {
136
+ compilePath: string;
137
+ children: RouteParsedConfig[];
138
+ match: MatchFunction;
139
+ compile: (params?: Record<string, string>) => string;
140
+ }
141
+
142
+ export interface RouteMatchResult {
143
+ readonly matches: readonly RouteParsedConfig[];
144
+ readonly params: Record<string, string | string[] | undefined>;
145
+ }
146
+
147
+ export type RouteMatcher = (targetURL: URL, baseURL: URL) => RouteMatchResult;
148
+
149
+ /**
150
+ * Route constructor options interface
151
+ */
152
+ export interface RouteOptions {
153
+ /** Router parsed options */
154
+ options?: RouterParsedOptions;
155
+ /** Route type */
156
+ toType?: RouteType;
157
+ /** Target route location */
158
+ toInput?: RouteLocationInput;
159
+ /** Source URL */
160
+ from?: URL | null;
161
+ }
162
+
163
+ // ============================================================================
164
+ // Router Layer types
165
+ // ============================================================================
166
+ export interface RouteLayerOptions {
167
+ /**
168
+ * Layer zIndex value
169
+ * If not set, will automatically use incremental layer value (1000 + increment)
170
+ */
171
+ zIndex?: number;
172
+ /**
173
+ * Verification hook function before route closure
174
+ * @returns Return true to allow closure, false to prevent closure
175
+ */
176
+ shouldClose?: RouteVerifyHook;
177
+ /**
178
+ * Whether to automatically record route history
179
+ * @default true
180
+ */
181
+ autoPush?: boolean;
182
+ /**
183
+ * Route navigation mode control
184
+ * - When autoPush is true:
185
+ * - true: Use push mode (add new history record)
186
+ * - false: Use replace mode (replace current history record)
187
+ * @default true
188
+ */
189
+ push?: boolean;
190
+ /**
191
+ * Router options for creating the layer instance
192
+ * These options will be merged with the default router configuration
193
+ */
194
+ routerOptions?: RouterLayerOptions;
195
+ }
196
+
197
+ export type RouteLayerResult =
198
+ | { type: 'close'; route: Route }
199
+ | { type: 'push'; route: Route }
200
+ | { type: 'success'; route: Route; data?: any };
201
+
202
+ /**
203
+ * Router options for creating layer instances
204
+ * Excludes handler functions and layer fields which are handled internally by createLayer
205
+ */
206
+ export type RouterLayerOptions = Omit<
207
+ RouterOptions,
208
+ 'handleBackBoundary' | 'handleLayerClose' | 'layer'
209
+ >;
210
+
211
+ // ============================================================================
212
+ // Router MicroApp types
213
+ // ============================================================================
214
+ export interface RouterMicroAppOptions {
215
+ mount: (el: HTMLElement) => void;
216
+ unmount: () => void;
217
+ renderToString?: () => Awaitable<string>;
218
+ }
219
+
220
+ export type RouterMicroAppCallback = (router: Router) => RouterMicroAppOptions;
221
+
222
+ export type RouterMicroApp =
223
+ | Record<string, RouterMicroAppCallback | undefined>
224
+ | RouterMicroAppCallback;
225
+
226
+ // ============================================================================
227
+ // Router core types
228
+ // ============================================================================
229
+ export interface RouterOptions {
230
+ /**
231
+ * Application mounting container
232
+ * - Can be a DOM selector string (e.g., '#app', '.container', '[data-mount]')
233
+ * - Can be an HTMLElement object
234
+ * - Defaults to '#root'
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * // Using ID selector
239
+ * new Router({ root: '#my-app' })
240
+ *
241
+ * // Using class selector
242
+ * new Router({ root: '.app-container' })
243
+ *
244
+ * // Using attribute selector
245
+ * new Router({ root: '[data-router-mount]' })
246
+ *
247
+ * // Passing DOM element directly
248
+ * const element = document.getElementById('app');
249
+ * new Router({ root: element })
250
+ * ```
251
+ */
252
+ root?: string | HTMLElement;
253
+ context?: Record<string | symbol, unknown>;
254
+ routes?: RouteConfig[];
255
+ mode?: RouterMode;
256
+ /** Optional in browser, but required on server side */
257
+ base?: URL;
258
+ req?: IncomingMessage | null;
259
+ res?: ServerResponse | null;
260
+ apps?: RouterMicroApp;
261
+ normalizeURL?: (to: URL, from: URL | null) => URL;
262
+ fallback?: RouteHandleHook;
263
+
264
+ rootStyle?: Partial<CSSStyleDeclaration> | false;
265
+ layer?: boolean;
266
+ zIndex?: number;
267
+ handleBackBoundary?: (router: Router) => void;
268
+ handleLayerClose?: (router: Router, data?: any) => void;
269
+ }
270
+
271
+ export interface RouterParsedOptions extends Readonly<Required<RouterOptions>> {
272
+ readonly matcher: RouteMatcher;
273
+ }
274
+
275
+ // ============================================================================
276
+ // RouterLink types
277
+ // ============================================================================
278
+
279
+ /**
280
+ * Router link navigation types
281
+ */
282
+ export type RouterLinkType =
283
+ | 'push'
284
+ | 'replace'
285
+ | 'pushWindow'
286
+ | 'replaceWindow'
287
+ | 'pushLayer';
288
+
289
+ /**
290
+ * Router link attributes generated by the source code
291
+ */
292
+ export interface RouterLinkAttributes {
293
+ // Always generated
294
+ href: string;
295
+ class: string;
296
+
297
+ // Conditionally generated
298
+ target?: '_blank';
299
+ rel?: string;
300
+ }
301
+
302
+ /**
303
+ * Framework-agnostic link configuration interface
304
+ */
305
+ export interface RouterLinkProps {
306
+ to: RouteLocationInput;
307
+ type?: RouterLinkType;
308
+ /**
309
+ * @deprecated Use type='replace' instead
310
+ */
311
+ replace?: boolean;
312
+ exact?: RouteMatchType;
313
+ activeClass?: string;
314
+ event?: string | string[];
315
+ tag?: string;
316
+ layerOptions?: RouteLayerOptions;
317
+ }
318
+
319
+ /**
320
+ * Framework-agnostic link resolution result
321
+ */
322
+ export interface RouterLinkResolved {
323
+ // Basic information
324
+ route: Route;
325
+ type: RouterLinkType;
326
+ isActive: boolean;
327
+ isExactActive: boolean;
328
+ isExternal: boolean;
329
+ tag: string;
330
+
331
+ // Element attributes
332
+ attributes: RouterLinkAttributes;
333
+
334
+ // Navigation function
335
+ navigate: (e?: MouseEvent) => Promise<void>;
336
+
337
+ // Event handling
338
+ getEventHandlers: (
339
+ nameTransform?: (eventType: string) => string
340
+ ) => Record<string, (e: MouseEvent) => Promise<void>>;
341
+ }