@xfe-repo/web-router 1.2.5 → 1.2.6

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,88 @@ __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) {
381
+ var Link = (0, import_react.memo)(function(props) {
368
382
  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() {
383
+ var _navigator2 = (0, import_react.useMemo)(function() {
370
384
  return getClientNavigator();
371
385
  }, []);
372
386
  if (/http(s)?:\/{2}/.test(to)) {
@@ -379,7 +393,7 @@ var Link = (0, import_react2.memo)(function(props) {
379
393
  window.location.href = to;
380
394
  }
381
395
  };
382
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", {
396
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
383
397
  href: to,
384
398
  onClick: handleLink,
385
399
  className: className,
@@ -413,15 +427,83 @@ var Link = (0, import_react2.memo)(function(props) {
413
427
  return _ref.apply(this, arguments);
414
428
  };
415
429
  }();
416
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", {
430
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
417
431
  href: to,
418
432
  onClick: handleLink1,
419
433
  className: className,
420
434
  children: children
421
435
  });
422
436
  }
423
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Link, _object_spread({}, props));
437
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Link, _object_spread({}, props));
424
438
  });
439
+ // src/Router.tsx
440
+ var import_react2 = require("react");
441
+ var import_react_router_dom2 = require("react-router-dom");
442
+ var import_jsx_runtime2 = require("react/jsx-runtime");
443
+ var Router = (0, import_react2.memo)(function(props) {
444
+ var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
445
+ var _ref = _sliced_to_array((0, import_react2.useState)({
446
+ action: navigator.action,
447
+ location: navigator.location
448
+ }), 2), navigatorState = _ref[0], setNavigatorState = _ref[1];
449
+ (0, import_react2.useEffect)(function() {
450
+ return navigator.listen(setNavigatorState);
451
+ }, [
452
+ navigator
453
+ ]);
454
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Router, {
455
+ navigator: navigator,
456
+ navigationType: navigatorState.action,
457
+ location: navigatorState.location,
458
+ basename: basename,
459
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Routes, {
460
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_router_dom2.Route, {
461
+ path: "/",
462
+ element: children,
463
+ children: [
464
+ routes.map(function(param) {
465
+ var path = param.path, Component = param.Component;
466
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Route, {
467
+ path: path,
468
+ Component: Component
469
+ }, path);
470
+ }),
471
+ NotFoundPageComponent && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Route, {
472
+ path: "*",
473
+ Component: NotFoundPageComponent
474
+ })
475
+ ]
476
+ })
477
+ })
478
+ });
479
+ });
480
+ // src/routes.ts
481
+ var import_component = __toESM(require("@loadable/component"));
482
+ var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
483
+ var routerDynamicRegx = /\[([^.]+)]/;
484
+ var getRoutes = function(config) {
485
+ var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
486
+ var routes = [];
487
+ pagesIndexPath.forEach(function(pageIndexPath) {
488
+ var _pageIndexPath_match;
489
+ if (pageIndexPath.startsWith("./")) return;
490
+ var pageComponent = (0, import_component.default)(function() {
491
+ return getPageComponents(pageIndexPath);
492
+ }, {
493
+ fallback: fallback
494
+ });
495
+ var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
496
+ if (routerPath === "home" || routerPath === "index") routerPath = "/";
497
+ var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
498
+ if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
499
+ var config2 = {
500
+ path: routerPath,
501
+ Component: pageComponent
502
+ };
503
+ routes.push(config2);
504
+ });
505
+ return routes;
506
+ };
425
507
  // src/index.ts
426
508
  var _navigator;
427
509
  function createNavigator(options) {
@@ -508,13 +590,18 @@ var getClientNavigator = function() {
508
590
  return _navigator;
509
591
  };
510
592
  var routerReady = import_component2.loadableReady;
593
+ initHistoryInterceptor();
511
594
  // Annotate the CommonJS export names for ESM import in node:
512
595
  0 && (module.exports = _object_spread({
596
+ HISTORY_CHANGE_EVENT: HISTORY_CHANGE_EVENT,
513
597
  Link: Link,
514
598
  Router: Router,
515
599
  createNavigator: createNavigator,
516
600
  getClientNavigator: getClientNavigator,
517
601
  getRoutes: getRoutes,
602
+ initHistoryInterceptor: initHistoryInterceptor,
603
+ isHistoryIntercepted: isHistoryIntercepted,
604
+ onHistoryChange: onHistoryChange,
518
605
  routerDynamicRegx: routerDynamicRegx,
519
606
  routerIndexRegx: routerIndexRegx,
520
607
  routerReady: routerReady
package/dist/index.mjs CHANGED
@@ -197,84 +197,86 @@ 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";
276
+ import { memo, useMemo } from "react";
275
277
  import { Link as OriginalLink } from "react-router-dom";
276
- import { jsx as jsx2 } from "react/jsx-runtime";
277
- var Link = memo2(function(props) {
278
+ import { jsx } from "react/jsx-runtime";
279
+ var Link = memo(function(props) {
278
280
  var to = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
279
281
  var _navigator2 = useMemo(function() {
280
282
  return getClientNavigator();
@@ -289,7 +291,7 @@ var Link = memo2(function(props) {
289
291
  window.location.href = to;
290
292
  }
291
293
  };
292
- return /* @__PURE__ */ jsx2("a", {
294
+ return /* @__PURE__ */ jsx("a", {
293
295
  href: to,
294
296
  onClick: handleLink,
295
297
  className: className,
@@ -323,15 +325,83 @@ var Link = memo2(function(props) {
323
325
  return _ref.apply(this, arguments);
324
326
  };
325
327
  }();
326
- return /* @__PURE__ */ jsx2("a", {
328
+ return /* @__PURE__ */ jsx("a", {
327
329
  href: to,
328
330
  onClick: handleLink1,
329
331
  className: className,
330
332
  children: children
331
333
  });
332
334
  }
333
- return /* @__PURE__ */ jsx2(OriginalLink, _object_spread({}, props));
335
+ return /* @__PURE__ */ jsx(OriginalLink, _object_spread({}, props));
336
+ });
337
+ // src/Router.tsx
338
+ import { memo as memo2, useState, useEffect } from "react";
339
+ import { Router as OriginalRouter, Routes, Route } from "react-router-dom";
340
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
341
+ var Router = memo2(function(props) {
342
+ var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
343
+ var _useState = _sliced_to_array(useState({
344
+ action: navigator.action,
345
+ location: navigator.location
346
+ }), 2), navigatorState = _useState[0], setNavigatorState = _useState[1];
347
+ useEffect(function() {
348
+ return navigator.listen(setNavigatorState);
349
+ }, [
350
+ navigator
351
+ ]);
352
+ return /* @__PURE__ */ jsx2(OriginalRouter, {
353
+ navigator: navigator,
354
+ navigationType: navigatorState.action,
355
+ location: navigatorState.location,
356
+ basename: basename,
357
+ children: /* @__PURE__ */ jsx2(Routes, {
358
+ children: /* @__PURE__ */ jsxs(Route, {
359
+ path: "/",
360
+ element: children,
361
+ children: [
362
+ routes.map(function(param) {
363
+ var path = param.path, Component = param.Component;
364
+ return /* @__PURE__ */ jsx2(Route, {
365
+ path: path,
366
+ Component: Component
367
+ }, path);
368
+ }),
369
+ NotFoundPageComponent && /* @__PURE__ */ jsx2(Route, {
370
+ path: "*",
371
+ Component: NotFoundPageComponent
372
+ })
373
+ ]
374
+ })
375
+ })
376
+ });
334
377
  });
378
+ // src/routes.ts
379
+ import loadable from "@loadable/component";
380
+ var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
381
+ var routerDynamicRegx = /\[([^.]+)]/;
382
+ var getRoutes = function(config) {
383
+ var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
384
+ var routes = [];
385
+ pagesIndexPath.forEach(function(pageIndexPath) {
386
+ var _pageIndexPath_match;
387
+ if (pageIndexPath.startsWith("./")) return;
388
+ var pageComponent = loadable(function() {
389
+ return getPageComponents(pageIndexPath);
390
+ }, {
391
+ fallback: fallback
392
+ });
393
+ var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
394
+ if (routerPath === "home" || routerPath === "index") routerPath = "/";
395
+ var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
396
+ if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
397
+ var config2 = {
398
+ path: routerPath,
399
+ Component: pageComponent
400
+ };
401
+ routes.push(config2);
402
+ });
403
+ return routes;
404
+ };
335
405
  // src/index.ts
336
406
  var _navigator;
337
407
  function createNavigator(options) {
@@ -418,4 +488,5 @@ var getClientNavigator = function() {
418
488
  return _navigator;
419
489
  };
420
490
  var routerReady = loadableReady;
421
- export { Link, Router, createNavigator, getClientNavigator, getRoutes, routerDynamicRegx, routerIndexRegx, routerReady };
491
+ initHistoryInterceptor();
492
+ 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.6",
4
4
  "sideEffects": false,
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,12 +28,12 @@
28
28
  "@types/loadable__component": "^5.13.9",
29
29
  "@types/node": "^20.16.5",
30
30
  "@types/react": "^18",
31
+ "@xfe-repo/typescript-config": "0.0.6",
31
32
  "@xfe-repo/eslint-config": "0.0.5",
32
- "@xfe-repo/web-register": "1.3.5",
33
- "@xfe-repo/typescript-config": "0.0.6"
33
+ "@xfe-repo/web-register": "1.3.5"
34
34
  },
35
35
  "peerDependencies": {
36
- "@xfe-repo/web-utils": "1.3.7"
36
+ "@xfe-repo/web-utils": "1.3.8"
37
37
  },
38
38
  "publishConfig": {
39
39
  "registry": "https://registry.npmjs.org/"