@xfe-repo/web-router 1.2.5 → 1.2.7

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/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { History } from 'history';
2
1
  import { LoadableComponent, loadableReady } from '@loadable/component';
2
+ import { History } from 'history';
3
3
  import { ParsedQuery } from '@xfe-repo/web-utils/tools';
4
4
  import React, { ReactElement, PropsWithChildren, ComponentType } from 'react';
5
5
  import { RegisterComponentStatic } from '@xfe-repo/web-register';
@@ -22,6 +22,12 @@ declare const routerIndexRegx: RegExp;
22
22
  declare const routerDynamicRegx: RegExp;
23
23
  declare const getRoutes: (config: GetRoutesConfig) => RouteConfig[];
24
24
 
25
+ type LinkProps = Omit<LinkProps$1, 'to'> & {
26
+ to: string;
27
+ preload?: boolean;
28
+ };
29
+ declare const Link: React.MemoExoticComponent<(props: LinkProps) => react_jsx_runtime.JSX.Element>;
30
+
25
31
  type RouterProps = PropsWithChildren<{
26
32
  navigator: NavigatorType;
27
33
  routes: RouteConfig[];
@@ -30,11 +36,60 @@ type RouterProps = PropsWithChildren<{
30
36
  }>;
31
37
  declare const Router: React.MemoExoticComponent<(props: RouterProps) => react_jsx_runtime.JSX.Element>;
32
38
 
33
- type LinkProps = Omit<LinkProps$1, 'to'> & {
34
- to: string;
35
- preload?: boolean;
36
- };
37
- declare const Link: React.MemoExoticComponent<(props: LinkProps) => react_jsx_runtime.JSX.Element>;
39
+ /**
40
+ * History API 拦截器
41
+ *
42
+ * 劫持 history.pushState 和 history.replaceState 方法,
43
+ * 在调用原始方法后触发标准化的 historychange 事件。
44
+ *
45
+ * @example
46
+ * // 监听 URL 变化
47
+ * window.addEventListener('historychange', (event) => {
48
+ * console.log('URL changed:', event.detail.url)
49
+ * })
50
+ */
51
+ /** 自定义事件名称 */
52
+ declare const HISTORY_CHANGE_EVENT = "historychange";
53
+ /** History 变化事件详情 */
54
+ interface HistoryChangeEventDetail {
55
+ /** 变化类型 */
56
+ type: 'pushState' | 'replaceState' | 'popstate';
57
+ /** 完整 URL */
58
+ url: string;
59
+ /** 路径部分 */
60
+ pathname: string;
61
+ /** 查询参数部分 */
62
+ search: string;
63
+ /** hash 部分 */
64
+ hash: string;
65
+ /** history state */
66
+ state: any;
67
+ /** 时间戳 */
68
+ timestamp: number;
69
+ }
70
+ /** History 变化事件类型 */
71
+ interface HistoryChangeEvent extends CustomEvent<HistoryChangeEventDetail> {
72
+ type: typeof HISTORY_CHANGE_EVENT;
73
+ }
74
+ /**
75
+ * 初始化 history 拦截器
76
+ *
77
+ * 劫持 history.pushState 和 history.replaceState 方法,
78
+ * 在调用原始方法后触发 historychange 事件。
79
+ * 同时监听原生 popstate 事件并转发为 historychange 事件。
80
+ *
81
+ * @returns 清理函数,用于恢复原始方法和移除监听器
82
+ */
83
+ declare function initHistoryInterceptor(): () => void;
84
+ /** 检查拦截器是否已初始化 */
85
+ declare function isHistoryIntercepted(): boolean;
86
+ /**
87
+ * 事件监听函数
88
+ *
89
+ * @param callback 回调函数
90
+ * @returns 取消监听的函数
91
+ */
92
+ declare function onHistoryChange(callback: (detail: HistoryChangeEventDetail) => void): () => void;
38
93
 
39
94
  interface NavigatorType extends History {
40
95
  preload: (path: string, isReplace?: boolean, query?: ParsedQuery<string | number | boolean>) => Promise<void>;
@@ -50,4 +105,4 @@ declare function createNavigator(options: CreateNavigatorOptions): NavigatorType
50
105
  declare const getClientNavigator: () => NavigatorType;
51
106
  declare const routerReady: typeof loadableReady;
52
107
 
53
- export { type CreateNavigatorOptions, type GetRoutesConfig, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, routerDynamicRegx, routerIndexRegx, routerReady };
108
+ export { type CreateNavigatorOptions, type GetRoutesConfig, HISTORY_CHANGE_EVENT, type HistoryChangeEvent, type HistoryChangeEventDetail, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, initHistoryInterceptor, isHistoryIntercepted, onHistoryChange, routerDynamicRegx, routerIndexRegx, routerReady };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { History } from 'history';
2
1
  import { LoadableComponent, loadableReady } from '@loadable/component';
2
+ import { History } from 'history';
3
3
  import { ParsedQuery } from '@xfe-repo/web-utils/tools';
4
4
  import React, { ReactElement, PropsWithChildren, ComponentType } from 'react';
5
5
  import { RegisterComponentStatic } from '@xfe-repo/web-register';
@@ -22,6 +22,12 @@ declare const routerIndexRegx: RegExp;
22
22
  declare const routerDynamicRegx: RegExp;
23
23
  declare const getRoutes: (config: GetRoutesConfig) => RouteConfig[];
24
24
 
25
+ type LinkProps = Omit<LinkProps$1, 'to'> & {
26
+ to: string;
27
+ preload?: boolean;
28
+ };
29
+ declare const Link: React.MemoExoticComponent<(props: LinkProps) => react_jsx_runtime.JSX.Element>;
30
+
25
31
  type RouterProps = PropsWithChildren<{
26
32
  navigator: NavigatorType;
27
33
  routes: RouteConfig[];
@@ -30,11 +36,60 @@ type RouterProps = PropsWithChildren<{
30
36
  }>;
31
37
  declare const Router: React.MemoExoticComponent<(props: RouterProps) => react_jsx_runtime.JSX.Element>;
32
38
 
33
- type LinkProps = Omit<LinkProps$1, 'to'> & {
34
- to: string;
35
- preload?: boolean;
36
- };
37
- declare const Link: React.MemoExoticComponent<(props: LinkProps) => react_jsx_runtime.JSX.Element>;
39
+ /**
40
+ * History API 拦截器
41
+ *
42
+ * 劫持 history.pushState 和 history.replaceState 方法,
43
+ * 在调用原始方法后触发标准化的 historychange 事件。
44
+ *
45
+ * @example
46
+ * // 监听 URL 变化
47
+ * window.addEventListener('historychange', (event) => {
48
+ * console.log('URL changed:', event.detail.url)
49
+ * })
50
+ */
51
+ /** 自定义事件名称 */
52
+ declare const HISTORY_CHANGE_EVENT = "historychange";
53
+ /** History 变化事件详情 */
54
+ interface HistoryChangeEventDetail {
55
+ /** 变化类型 */
56
+ type: 'pushState' | 'replaceState' | 'popstate';
57
+ /** 完整 URL */
58
+ url: string;
59
+ /** 路径部分 */
60
+ pathname: string;
61
+ /** 查询参数部分 */
62
+ search: string;
63
+ /** hash 部分 */
64
+ hash: string;
65
+ /** history state */
66
+ state: any;
67
+ /** 时间戳 */
68
+ timestamp: number;
69
+ }
70
+ /** History 变化事件类型 */
71
+ interface HistoryChangeEvent extends CustomEvent<HistoryChangeEventDetail> {
72
+ type: typeof HISTORY_CHANGE_EVENT;
73
+ }
74
+ /**
75
+ * 初始化 history 拦截器
76
+ *
77
+ * 劫持 history.pushState 和 history.replaceState 方法,
78
+ * 在调用原始方法后触发 historychange 事件。
79
+ * 同时监听原生 popstate 事件并转发为 historychange 事件。
80
+ *
81
+ * @returns 清理函数,用于恢复原始方法和移除监听器
82
+ */
83
+ declare function initHistoryInterceptor(): () => void;
84
+ /** 检查拦截器是否已初始化 */
85
+ declare function isHistoryIntercepted(): boolean;
86
+ /**
87
+ * 事件监听函数
88
+ *
89
+ * @param callback 回调函数
90
+ * @returns 取消监听的函数
91
+ */
92
+ declare function onHistoryChange(callback: (detail: HistoryChangeEventDetail) => void): () => void;
38
93
 
39
94
  interface NavigatorType extends History {
40
95
  preload: (path: string, isReplace?: boolean, query?: ParsedQuery<string | number | boolean>) => Promise<void>;
@@ -50,4 +105,4 @@ declare function createNavigator(options: CreateNavigatorOptions): NavigatorType
50
105
  declare const getClientNavigator: () => NavigatorType;
51
106
  declare const routerReady: typeof loadableReady;
52
107
 
53
- export { type CreateNavigatorOptions, type GetRoutesConfig, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, routerDynamicRegx, routerIndexRegx, routerReady };
108
+ export { type CreateNavigatorOptions, type GetRoutesConfig, HISTORY_CHANGE_EVENT, type HistoryChangeEvent, type HistoryChangeEventDetail, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, initHistoryInterceptor, isHistoryIntercepted, onHistoryChange, routerDynamicRegx, routerIndexRegx, routerReady };
package/dist/index.js CHANGED
@@ -261,6 +261,9 @@ var __toCommonJS = function(mod) {
261
261
  // src/index.ts
262
262
  var src_exports = {};
263
263
  __export(src_exports, {
264
+ HISTORY_CHANGE_EVENT: function() {
265
+ return HISTORY_CHANGE_EVENT;
266
+ },
264
267
  Link: function() {
265
268
  return Link;
266
269
  },
@@ -276,6 +279,15 @@ __export(src_exports, {
276
279
  getRoutes: function() {
277
280
  return getRoutes;
278
281
  },
282
+ initHistoryInterceptor: function() {
283
+ return initHistoryInterceptor;
284
+ },
285
+ isHistoryIntercepted: function() {
286
+ return isHistoryIntercepted;
287
+ },
288
+ onHistoryChange: function() {
289
+ return onHistoryChange;
290
+ },
279
291
  routerDynamicRegx: function() {
280
292
  return routerDynamicRegx;
281
293
  },
@@ -287,86 +299,89 @@ __export(src_exports, {
287
299
  }
288
300
  });
289
301
  module.exports = __toCommonJS(src_exports);
290
- var import_history = require("history");
291
302
  var import_component2 = require("@loadable/component");
303
+ var import_history = require("history");
292
304
  var import_react_router_dom3 = require("react-router-dom");
293
305
  var import_tools = require("@xfe-repo/web-utils/tools");
294
- __reExport(src_exports, require("react-router-dom"), module.exports);
295
- // src/routes.ts
296
- var import_component = __toESM(require("@loadable/component"));
297
- var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
298
- var routerDynamicRegx = /\[([^.]+)]/;
299
- var getRoutes = function(config) {
300
- var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
301
- var routes = [];
302
- pagesIndexPath.forEach(function(pageIndexPath) {
303
- var _pageIndexPath_match;
304
- if (pageIndexPath.startsWith("./")) return;
305
- var pageComponent = (0, import_component.default)(function() {
306
- return getPageComponents(pageIndexPath);
307
- }, {
308
- fallback: fallback
309
- });
310
- var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
311
- if (routerPath === "home" || routerPath === "index") routerPath = "/";
312
- var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
313
- if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
314
- var config2 = {
315
- path: routerPath,
316
- Component: pageComponent
317
- };
318
- routes.push(config2);
306
+ // src/historyInterceptor.ts
307
+ var HISTORY_CHANGE_EVENT = "historychange";
308
+ var originalPushState = null;
309
+ var originalReplaceState = null;
310
+ var isIntercepted = false;
311
+ function dispatchHistoryChangeEvent(detail) {
312
+ var event = new CustomEvent(HISTORY_CHANGE_EVENT, {
313
+ detail: detail,
314
+ bubbles: false,
315
+ cancelable: false
319
316
  });
320
- return routes;
321
- };
322
- // src/Router.tsx
317
+ window.dispatchEvent(event);
318
+ }
319
+ function createEventDetail(type, state) {
320
+ return {
321
+ type: type,
322
+ url: window.location.href,
323
+ pathname: window.location.pathname,
324
+ search: window.location.search,
325
+ hash: window.location.hash,
326
+ state: state,
327
+ timestamp: Date.now()
328
+ };
329
+ }
330
+ function initHistoryInterceptor() {
331
+ if (isIntercepted) {
332
+ return function() {};
333
+ }
334
+ originalPushState = history.pushState;
335
+ originalReplaceState = history.replaceState;
336
+ history.pushState = function(state, unused, url) {
337
+ originalPushState.call(this, state, unused, url);
338
+ dispatchHistoryChangeEvent(createEventDetail("pushState", state));
339
+ };
340
+ history.replaceState = function(state, unused, url) {
341
+ originalReplaceState.call(this, state, unused, url);
342
+ dispatchHistoryChangeEvent(createEventDetail("replaceState", state));
343
+ };
344
+ var handlePopState = function() {
345
+ dispatchHistoryChangeEvent(createEventDetail("popstate", history.state));
346
+ };
347
+ window.addEventListener("popstate", handlePopState);
348
+ isIntercepted = true;
349
+ return function() {
350
+ if (originalPushState) {
351
+ history.pushState = originalPushState;
352
+ originalPushState = null;
353
+ }
354
+ if (originalReplaceState) {
355
+ history.replaceState = originalReplaceState;
356
+ originalReplaceState = null;
357
+ }
358
+ window.removeEventListener("popstate", handlePopState);
359
+ isIntercepted = false;
360
+ };
361
+ }
362
+ function isHistoryIntercepted() {
363
+ return isIntercepted;
364
+ }
365
+ function onHistoryChange(callback) {
366
+ var handler = function(event) {
367
+ var customEvent = event;
368
+ callback(customEvent.detail);
369
+ };
370
+ window.addEventListener(HISTORY_CHANGE_EVENT, handler);
371
+ return function() {
372
+ window.removeEventListener(HISTORY_CHANGE_EVENT, handler);
373
+ };
374
+ }
375
+ // src/index.ts
376
+ __reExport(src_exports, require("react-router-dom"), module.exports);
377
+ // src/Link.tsx
323
378
  var import_react = require("react");
324
379
  var import_react_router_dom = require("react-router-dom");
325
380
  var import_jsx_runtime = require("react/jsx-runtime");
326
- var Router = (0, import_react.memo)(function(props) {
327
- var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
328
- var _ref = _sliced_to_array((0, import_react.useState)({
329
- action: navigator.action,
330
- location: navigator.location
331
- }), 2), navigatorState = _ref[0], setNavigatorState = _ref[1];
332
- (0, import_react.useEffect)(function() {
333
- return navigator.listen(setNavigatorState);
334
- }, [
335
- navigator
336
- ]);
337
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Router, {
338
- navigator: navigator,
339
- navigationType: navigatorState.action,
340
- location: navigatorState.location,
341
- basename: basename,
342
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Routes, {
343
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_router_dom.Route, {
344
- path: "/",
345
- element: children,
346
- children: [
347
- routes.map(function(param) {
348
- var path = param.path, Component = param.Component;
349
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Route, {
350
- path: path,
351
- Component: Component
352
- }, path);
353
- }),
354
- NotFoundPageComponent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Route, {
355
- path: "*",
356
- Component: NotFoundPageComponent
357
- })
358
- ]
359
- })
360
- })
361
- });
362
- });
363
- // src/Link.tsx
364
- var import_react2 = require("react");
365
- var import_react_router_dom2 = require("react-router-dom");
366
- var import_jsx_runtime2 = require("react/jsx-runtime");
367
- var Link = (0, import_react2.memo)(function(props) {
368
- var to = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
369
- var _navigator2 = (0, import_react2.useMemo)(function() {
381
+ var Link = (0, import_react.memo)(function(props) {
382
+ var originTo = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
383
+ var to = (0, import_react_router_dom.useHref)(originTo);
384
+ var _navigator2 = (0, import_react.useMemo)(function() {
370
385
  return getClientNavigator();
371
386
  }, []);
372
387
  if (/http(s)?:\/{2}/.test(to)) {
@@ -379,7 +394,7 @@ var Link = (0, import_react2.memo)(function(props) {
379
394
  window.location.href = to;
380
395
  }
381
396
  };
382
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", {
397
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
383
398
  href: to,
384
399
  onClick: handleLink,
385
400
  className: className,
@@ -413,15 +428,83 @@ var Link = (0, import_react2.memo)(function(props) {
413
428
  return _ref.apply(this, arguments);
414
429
  };
415
430
  }();
416
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", {
431
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
417
432
  href: to,
418
433
  onClick: handleLink1,
419
434
  className: className,
420
435
  children: children
421
436
  });
422
437
  }
423
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Link, _object_spread({}, props));
438
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Link, _object_spread({}, props));
424
439
  });
440
+ // src/Router.tsx
441
+ var import_react2 = require("react");
442
+ var import_react_router_dom2 = require("react-router-dom");
443
+ var import_jsx_runtime2 = require("react/jsx-runtime");
444
+ var Router = (0, import_react2.memo)(function(props) {
445
+ var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
446
+ var _ref = _sliced_to_array((0, import_react2.useState)({
447
+ action: navigator.action,
448
+ location: navigator.location
449
+ }), 2), navigatorState = _ref[0], setNavigatorState = _ref[1];
450
+ (0, import_react2.useEffect)(function() {
451
+ return navigator.listen(setNavigatorState);
452
+ }, [
453
+ navigator
454
+ ]);
455
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Router, {
456
+ navigator: navigator,
457
+ navigationType: navigatorState.action,
458
+ location: navigatorState.location,
459
+ basename: basename,
460
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Routes, {
461
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_router_dom2.Route, {
462
+ path: "/",
463
+ element: children,
464
+ children: [
465
+ routes.map(function(param) {
466
+ var path = param.path, Component = param.Component;
467
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Route, {
468
+ path: path,
469
+ Component: Component
470
+ }, path);
471
+ }),
472
+ NotFoundPageComponent && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Route, {
473
+ path: "*",
474
+ Component: NotFoundPageComponent
475
+ })
476
+ ]
477
+ })
478
+ })
479
+ });
480
+ });
481
+ // src/routes.ts
482
+ var import_component = __toESM(require("@loadable/component"));
483
+ var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
484
+ var routerDynamicRegx = /\[([^.]+)]/;
485
+ var getRoutes = function(config) {
486
+ var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
487
+ var routes = [];
488
+ pagesIndexPath.forEach(function(pageIndexPath) {
489
+ var _pageIndexPath_match;
490
+ if (pageIndexPath.startsWith("./")) return;
491
+ var pageComponent = (0, import_component.default)(function() {
492
+ return getPageComponents(pageIndexPath);
493
+ }, {
494
+ fallback: fallback
495
+ });
496
+ var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
497
+ if (routerPath === "home" || routerPath === "index") routerPath = "/";
498
+ var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
499
+ if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
500
+ var config2 = {
501
+ path: routerPath,
502
+ Component: pageComponent
503
+ };
504
+ routes.push(config2);
505
+ });
506
+ return routes;
507
+ };
425
508
  // src/index.ts
426
509
  var _navigator;
427
510
  function createNavigator(options) {
@@ -508,13 +591,18 @@ var getClientNavigator = function() {
508
591
  return _navigator;
509
592
  };
510
593
  var routerReady = import_component2.loadableReady;
594
+ initHistoryInterceptor();
511
595
  // Annotate the CommonJS export names for ESM import in node:
512
596
  0 && (module.exports = _object_spread({
597
+ HISTORY_CHANGE_EVENT: HISTORY_CHANGE_EVENT,
513
598
  Link: Link,
514
599
  Router: Router,
515
600
  createNavigator: createNavigator,
516
601
  getClientNavigator: getClientNavigator,
517
602
  getRoutes: getRoutes,
603
+ initHistoryInterceptor: initHistoryInterceptor,
604
+ isHistoryIntercepted: isHistoryIntercepted,
605
+ onHistoryChange: onHistoryChange,
518
606
  routerDynamicRegx: routerDynamicRegx,
519
607
  routerIndexRegx: routerIndexRegx,
520
608
  routerReady: routerReady
package/dist/index.mjs CHANGED
@@ -197,85 +197,88 @@ function _ts_generator(thisArg, body) {
197
197
  };
198
198
  }
199
199
  }
200
- import { createHashHistory, createBrowserHistory, createMemoryHistory } from "history";
201
200
  import { loadableReady } from "@loadable/component";
201
+ import { createBrowserHistory, createHashHistory, createMemoryHistory } from "history";
202
202
  import { matchRoutes } from "react-router-dom";
203
203
  import { queryString } from "@xfe-repo/web-utils/tools";
204
- export * from "react-router-dom";
205
- // src/routes.ts
206
- import loadable from "@loadable/component";
207
- var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
208
- var routerDynamicRegx = /\[([^.]+)]/;
209
- var getRoutes = function(config) {
210
- var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
211
- var routes = [];
212
- pagesIndexPath.forEach(function(pageIndexPath) {
213
- var _pageIndexPath_match;
214
- if (pageIndexPath.startsWith("./")) return;
215
- var pageComponent = loadable(function() {
216
- return getPageComponents(pageIndexPath);
217
- }, {
218
- fallback: fallback
219
- });
220
- var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
221
- if (routerPath === "home" || routerPath === "index") routerPath = "/";
222
- var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
223
- if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
224
- var config2 = {
225
- path: routerPath,
226
- Component: pageComponent
227
- };
228
- routes.push(config2);
204
+ // src/historyInterceptor.ts
205
+ var HISTORY_CHANGE_EVENT = "historychange";
206
+ var originalPushState = null;
207
+ var originalReplaceState = null;
208
+ var isIntercepted = false;
209
+ function dispatchHistoryChangeEvent(detail) {
210
+ var event = new CustomEvent(HISTORY_CHANGE_EVENT, {
211
+ detail: detail,
212
+ bubbles: false,
213
+ cancelable: false
229
214
  });
230
- return routes;
231
- };
232
- // src/Router.tsx
233
- import { memo, useState, useEffect } from "react";
234
- import { Router as OriginalRouter, Routes, Route } from "react-router-dom";
235
- import { jsx, jsxs } from "react/jsx-runtime";
236
- var Router = memo(function(props) {
237
- var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
238
- var _useState = _sliced_to_array(useState({
239
- action: navigator.action,
240
- location: navigator.location
241
- }), 2), navigatorState = _useState[0], setNavigatorState = _useState[1];
242
- useEffect(function() {
243
- return navigator.listen(setNavigatorState);
244
- }, [
245
- navigator
246
- ]);
247
- return /* @__PURE__ */ jsx(OriginalRouter, {
248
- navigator: navigator,
249
- navigationType: navigatorState.action,
250
- location: navigatorState.location,
251
- basename: basename,
252
- children: /* @__PURE__ */ jsx(Routes, {
253
- children: /* @__PURE__ */ jsxs(Route, {
254
- path: "/",
255
- element: children,
256
- children: [
257
- routes.map(function(param) {
258
- var path = param.path, Component = param.Component;
259
- return /* @__PURE__ */ jsx(Route, {
260
- path: path,
261
- Component: Component
262
- }, path);
263
- }),
264
- NotFoundPageComponent && /* @__PURE__ */ jsx(Route, {
265
- path: "*",
266
- Component: NotFoundPageComponent
267
- })
268
- ]
269
- })
270
- })
271
- });
272
- });
215
+ window.dispatchEvent(event);
216
+ }
217
+ function createEventDetail(type, state) {
218
+ return {
219
+ type: type,
220
+ url: window.location.href,
221
+ pathname: window.location.pathname,
222
+ search: window.location.search,
223
+ hash: window.location.hash,
224
+ state: state,
225
+ timestamp: Date.now()
226
+ };
227
+ }
228
+ function initHistoryInterceptor() {
229
+ if (isIntercepted) {
230
+ return function() {};
231
+ }
232
+ originalPushState = history.pushState;
233
+ originalReplaceState = history.replaceState;
234
+ history.pushState = function(state, unused, url) {
235
+ originalPushState.call(this, state, unused, url);
236
+ dispatchHistoryChangeEvent(createEventDetail("pushState", state));
237
+ };
238
+ history.replaceState = function(state, unused, url) {
239
+ originalReplaceState.call(this, state, unused, url);
240
+ dispatchHistoryChangeEvent(createEventDetail("replaceState", state));
241
+ };
242
+ var handlePopState = function() {
243
+ dispatchHistoryChangeEvent(createEventDetail("popstate", history.state));
244
+ };
245
+ window.addEventListener("popstate", handlePopState);
246
+ isIntercepted = true;
247
+ return function() {
248
+ if (originalPushState) {
249
+ history.pushState = originalPushState;
250
+ originalPushState = null;
251
+ }
252
+ if (originalReplaceState) {
253
+ history.replaceState = originalReplaceState;
254
+ originalReplaceState = null;
255
+ }
256
+ window.removeEventListener("popstate", handlePopState);
257
+ isIntercepted = false;
258
+ };
259
+ }
260
+ function isHistoryIntercepted() {
261
+ return isIntercepted;
262
+ }
263
+ function onHistoryChange(callback) {
264
+ var handler = function(event) {
265
+ var customEvent = event;
266
+ callback(customEvent.detail);
267
+ };
268
+ window.addEventListener(HISTORY_CHANGE_EVENT, handler);
269
+ return function() {
270
+ window.removeEventListener(HISTORY_CHANGE_EVENT, handler);
271
+ };
272
+ }
273
+ // src/index.ts
274
+ export * from "react-router-dom";
273
275
  // src/Link.tsx
274
- import { memo as memo2, useMemo } from "react";
275
- import { Link as OriginalLink } from "react-router-dom";
276
- import { jsx as jsx2 } from "react/jsx-runtime";
277
- var Link = memo2(function(props) {
278
- var to = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
276
+ import { memo, useMemo } from "react";
277
+ import { Link as OriginalLink, useHref } from "react-router-dom";
278
+ import { jsx } from "react/jsx-runtime";
279
+ var Link = memo(function(props) {
280
+ var originTo = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
281
+ var to = useHref(originTo);
279
282
  var _navigator2 = useMemo(function() {
280
283
  return getClientNavigator();
281
284
  }, []);
@@ -289,7 +292,7 @@ var Link = memo2(function(props) {
289
292
  window.location.href = to;
290
293
  }
291
294
  };
292
- return /* @__PURE__ */ jsx2("a", {
295
+ return /* @__PURE__ */ jsx("a", {
293
296
  href: to,
294
297
  onClick: handleLink,
295
298
  className: className,
@@ -323,15 +326,83 @@ var Link = memo2(function(props) {
323
326
  return _ref.apply(this, arguments);
324
327
  };
325
328
  }();
326
- return /* @__PURE__ */ jsx2("a", {
329
+ return /* @__PURE__ */ jsx("a", {
327
330
  href: to,
328
331
  onClick: handleLink1,
329
332
  className: className,
330
333
  children: children
331
334
  });
332
335
  }
333
- return /* @__PURE__ */ jsx2(OriginalLink, _object_spread({}, props));
336
+ return /* @__PURE__ */ jsx(OriginalLink, _object_spread({}, props));
337
+ });
338
+ // src/Router.tsx
339
+ import { memo as memo2, useState, useEffect } from "react";
340
+ import { Router as OriginalRouter, Routes, Route } from "react-router-dom";
341
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
342
+ var Router = memo2(function(props) {
343
+ var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
344
+ var _useState = _sliced_to_array(useState({
345
+ action: navigator.action,
346
+ location: navigator.location
347
+ }), 2), navigatorState = _useState[0], setNavigatorState = _useState[1];
348
+ useEffect(function() {
349
+ return navigator.listen(setNavigatorState);
350
+ }, [
351
+ navigator
352
+ ]);
353
+ return /* @__PURE__ */ jsx2(OriginalRouter, {
354
+ navigator: navigator,
355
+ navigationType: navigatorState.action,
356
+ location: navigatorState.location,
357
+ basename: basename,
358
+ children: /* @__PURE__ */ jsx2(Routes, {
359
+ children: /* @__PURE__ */ jsxs(Route, {
360
+ path: "/",
361
+ element: children,
362
+ children: [
363
+ routes.map(function(param) {
364
+ var path = param.path, Component = param.Component;
365
+ return /* @__PURE__ */ jsx2(Route, {
366
+ path: path,
367
+ Component: Component
368
+ }, path);
369
+ }),
370
+ NotFoundPageComponent && /* @__PURE__ */ jsx2(Route, {
371
+ path: "*",
372
+ Component: NotFoundPageComponent
373
+ })
374
+ ]
375
+ })
376
+ })
377
+ });
334
378
  });
379
+ // src/routes.ts
380
+ import loadable from "@loadable/component";
381
+ var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
382
+ var routerDynamicRegx = /\[([^.]+)]/;
383
+ var getRoutes = function(config) {
384
+ var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
385
+ var routes = [];
386
+ pagesIndexPath.forEach(function(pageIndexPath) {
387
+ var _pageIndexPath_match;
388
+ if (pageIndexPath.startsWith("./")) return;
389
+ var pageComponent = loadable(function() {
390
+ return getPageComponents(pageIndexPath);
391
+ }, {
392
+ fallback: fallback
393
+ });
394
+ var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
395
+ if (routerPath === "home" || routerPath === "index") routerPath = "/";
396
+ var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
397
+ if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
398
+ var config2 = {
399
+ path: routerPath,
400
+ Component: pageComponent
401
+ };
402
+ routes.push(config2);
403
+ });
404
+ return routes;
405
+ };
335
406
  // src/index.ts
336
407
  var _navigator;
337
408
  function createNavigator(options) {
@@ -418,4 +489,5 @@ var getClientNavigator = function() {
418
489
  return _navigator;
419
490
  };
420
491
  var routerReady = loadableReady;
421
- export { Link, Router, createNavigator, getClientNavigator, getRoutes, routerDynamicRegx, routerIndexRegx, routerReady };
492
+ initHistoryInterceptor();
493
+ export { HISTORY_CHANGE_EVENT, Link, Router, createNavigator, getClientNavigator, getRoutes, initHistoryInterceptor, isHistoryIntercepted, onHistoryChange, routerDynamicRegx, routerIndexRegx, routerReady };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfe-repo/web-router",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "sideEffects": false,
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "@xfe-repo/typescript-config": "0.0.6"
34
34
  },
35
35
  "peerDependencies": {
36
- "@xfe-repo/web-utils": "1.3.7"
36
+ "@xfe-repo/web-utils": "1.3.11"
37
37
  },
38
38
  "publishConfig": {
39
39
  "registry": "https://registry.npmjs.org/"