vitarx-router 3.0.0-alpha.1 → 3.0.0-beta.1

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.
@@ -1376,7 +1376,7 @@ export declare class RouterView extends Widget<RouteOptions> {
1376
1376
  * ```
1377
1377
  * @protected
1378
1378
  */
1379
- build(): Element_2;
1379
+ build(): Element_2 | null;
1380
1380
  /**
1381
1381
  * 视图渲染完成通知路由器
1382
1382
  *
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value);
4
- import { deepClone, reactive, markRaw, shallowReactive, readonly, createElement, isDeepEqual, isRecordObject, isObject, Widget, shallowRef, inject, provide, watch, toRaw, Observer, Fragment, Computed, isString } from "vitarx";
4
+ import { deepClone, reactive, markRaw, shallowReactive, readonly, createElement, isDeepEqual, isRecordObject, isObject, Widget, shallowRef, inject, provide, watch, toRaw, Observer, Computed, isString } from "vitarx";
5
5
  var NavigateStatus = /* @__PURE__ */ ((NavigateStatus2) => (NavigateStatus2[NavigateStatus2.success = 0] = "success", NavigateStatus2[NavigateStatus2.aborted = 1] = "aborted", NavigateStatus2[NavigateStatus2.cancelled = 2] = "cancelled", NavigateStatus2[NavigateStatus2.duplicated = 3] = "duplicated", NavigateStatus2[NavigateStatus2.not_matched = 4] = "not_matched", NavigateStatus2[NavigateStatus2.exception = 5] = "exception", NavigateStatus2))(NavigateStatus || {});
6
6
  function isVariablePath(path) {
7
7
  return /\{[^}]+}/.test(path);
@@ -1355,7 +1355,7 @@ class RouterView extends Widget {
1355
1355
  * @protected
1356
1356
  */
1357
1357
  build() {
1358
- return this.currentElement || createElement(Fragment);
1358
+ return this.currentElement || null;
1359
1359
  }
1360
1360
  /**
1361
1361
  * 视图渲染完成通知路由器
@@ -0,0 +1 @@
1
+ var __defProp=Object.defineProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value}):obj[key]=value;var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!="symbol"?key+"":key,value);var VitarxRouter=(function(exports,vitarx){"use strict";var NavigateStatus=(NavigateStatus2=>(NavigateStatus2[NavigateStatus2.success=0]="success",NavigateStatus2[NavigateStatus2.aborted=1]="aborted",NavigateStatus2[NavigateStatus2.cancelled=2]="cancelled",NavigateStatus2[NavigateStatus2.duplicated=3]="duplicated",NavigateStatus2[NavigateStatus2.not_matched=4]="not_matched",NavigateStatus2[NavigateStatus2.exception=5]="exception",NavigateStatus2))(NavigateStatus||{});function isVariablePath(path){return/\{[^}]+}/.test(path)}function optionalVariableCount(path){const pathWithoutSpaces=path.replace(/\s+/g,""),regex=/\{[\w-]+\?}/g,matches=pathWithoutSpaces.match(regex);return matches?matches.length:0}function isRouteGroup(route){return"children"in route&&route.children!==void 0&&route.children.length>0}function createDynamicPattern(path,pattern,strict,defaultPattern){let optional=0;const processVariable=(varName,isOptional)=>{const regex=pattern[varName];if(regex?regex instanceof RegExp||(console.warn(`[Vitarx.Router][WARN]:${path} 动态路径${varName}变量的自定义正则表达式必须是 RegExp 类型`),pattern[varName]=defaultPattern):pattern[varName]=defaultPattern,isOptional)return optional++,`(?:(${pattern[varName].source}))?`;if(optional)throw new Error(`[Vitarx.Router][ERROR]:动态路径 ${path} 中,可选变量 ${varName} 后不能存在任何必填变量`);return`(${pattern[varName].source})`},processedPath=path.replace(/{([^}?]+)\?}/g,(_,varName)=>processVariable(varName,!0)).replace(/{([^}]+)}/g,(_,varName)=>processVariable(varName,!1)).replace(/\//g,"\\/").replace(/\/?$/,"/?"),flags=strict?"":"i",segments=path.replace(/^\/|\/$/g,"").split("/").length;return{regex:new RegExp(`^${processedPath}$`,flags),length:segments,optional}}function formatPath(path){return path=`/${path}`.replace(/\s+/g,"").replace(/\/+/g,"/"),path.length?path==="/"||path==="/#/"?path:path.replace(/\/$/,""):"/"}function mergePathParams(path,params){if(!isVariablePath(path))return path;const oldPath=path;return path=path.replace(/{([^}]+)\?*}/g,(_match,paramName)=>{const isOptional=paramName.endsWith("?");if(isOptional&&(paramName=paramName.slice(0,-1)),params[paramName]===void 0){if(isOptional)return"";throw new TypeError(`[Vitarx.Router.mergePathParams] 访问路由${oldPath}时缺少参数:${paramName}`)}return String(params[paramName]).replace(/\s+/g,"_")}),formatPath(path)}function formatHash(hash,addHashPrefix){return typeof hash!="string"||!hash?"":(hash=hash.trim(),hash.startsWith("#")?hash:`#${hash}`)}function queryStringToObject(queryString){queryString=decodeURIComponent(queryString);const params=new URLSearchParams(queryString.startsWith("?")?queryString.substring(1):queryString),obj={};return params.forEach((value,key)=>obj[key]=value),obj}function objectToQueryString(obj){const queryString=new URLSearchParams(obj).toString();return queryString?`?${queryString}`:""}function urlToRouteTarget(url,mode,base){let path=decodeURIComponent(url.pathname),hash=decodeURIComponent(url.hash),query=queryStringToObject(url.search);if(path=formatPath(path.startsWith(base)?path.slice(base.length):path),mode==="hash"&&hash.includes("#/")){const hashPart=hash.slice(1),[fullPath,anchor]=hashPart.split("#");path=formatPath(fullPath||"/"),hash=anchor?`#${anchor}`:""}return{index:path,hash,query}}function splitPathAndSuffix(path){const suffix=getPathSuffix(path);return suffix&&(path=path.slice(0,-suffix.length)),{path,suffix:suffix.substring(1)}}function getPathSuffix(path){const lastDotIndex=path.lastIndexOf(".");return lastDotIndex!==-1&&lastDotIndex<path.length-1?`.${path.substring(lastDotIndex+1)}`:""}function isRouteLocationTypeObject(obj){if(typeof obj!="object"||obj===null)return!1;const keys=["index","fullPath","path","hash","params","query","matched","meta"];for(const key of keys)if(!Object.prototype.hasOwnProperty.call(obj,key))return!1;return!0}function validateSuffix(suffix,allowSuffix,inputPath,routePath){return inputPath==="/"||allowSuffix==="*"?!0:allowSuffix===!1?inputPath===routePath:Array.isArray(allowSuffix)?allowSuffix.includes(suffix):suffix===allowSuffix}function addPathSuffix(path,suffix){return suffix&&!path.endsWith("/")&&!path.includes(".")&&(path+=suffix.startsWith(".")?suffix:`.${suffix}`),path}function cloneRouteLocation(route){const{matched,...other}=route;return Object.assign(vitarx.deepClone(other),{matched:Array.from(matched)})}const validInjectProps=props=>["boolean","function"].includes(typeof props);function normalizeInjectProps(route){if(!route.widget)return;const injectProps={},inputValue=route.injectProps??!0,type=typeof inputValue;if(type==="object")for(const name in route.widget){const value=inputValue[name];if(value&&!validInjectProps(value))throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${route.path} 路由线路配置,injectProps.${name}值错误,仅支持boolean、function类型`);injectProps[name]=value??!0}else if(type==="function"||type==="boolean")for(const name in route.widget)injectProps[name]=inputValue;else throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${route.path} 路由线路配置,injectProps属性配置错误,仅支持boolean、{key:boolean|function}、function类型`);route.injectProps=injectProps}const validWidgetType=(widget,path)=>{const type=typeof widget;if(type!=="function"){if(type==="object"){if(!widget.default)throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${path} 路由配置,widget传入对象时则认为是命名视图,命名视图必须具有default视图`);for(const k in widget)validWidgetType(widget[k],path);return}throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${path} 路由配置,widget配置无效`)}};function normalizeRouteWidget(route){const isGroup=route.children.length;if(route.widget)validWidgetType(route.widget,route.path);else if(!isGroup)throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${route.path} 路由配置,widget和children不能同时为空。`);typeof route.widget=="function"&&(route.widget={default:route.widget})}function normalizeRoute(route,group,suffix){if(route.meta=route.meta||{},route.pattern=route.pattern||{},route.children=route.children||[],!Array.isArray(route.children))throw new TypeError(`[Vitarx.Router][TYPE_ERROR]:${route.path} 路由线路配置 children 类型错误,它必须是数组类型。`);if(!route.path.trim())throw new TypeError("[Vitarx.Router][TYPE_ERROR]:路由线路配置 path 不能为空");return route.path=formatPath(group?`${group.path}/${route.path}`:route.path),normalizeRouteWidget(route),normalizeInjectProps(route),route.suffix??(route.suffix=(group==null?void 0:group.suffix)??suffix),route.afterEnter??(route.afterEnter=group==null?void 0:group.afterEnter),route.beforeEnter??(route.beforeEnter=group==null?void 0:group.beforeEnter),route}class RouterRegistry{constructor(options){__publicField(this,"_options");__publicField(this,"_namedRoutes",new Map);__publicField(this,"_dynamicRoutes",new Map);__publicField(this,"_pathRoutes",new Map);__publicField(this,"_parentRoute",new WeakMap);const config={base:"/",strict:!1,mode:"path",scrollBehavior:"auto",anchorsScrollBehavior:"auto",suffix:"*",pattern:/[\w.]+/,defaultSuffix:"",...options};if(config.base=`/${config.base.replace(/^\/+|\/+$/g,"")}`,typeof config.suffix=="string"?config.suffix=config.suffix.replace(/\./g,""):Array.isArray(config.suffix)&&(config.suffix=config.suffix.map(item=>item.replace(/\./g,""))),config.defaultSuffix&&(config.defaultSuffix=config.defaultSuffix.replace(/\./g,"")),config.missing&&typeof config.missing!="function")throw new TypeError("[VitarxRouter][ERROR]:missing配置无效");this._options=config}get options(){return this._options}get mode(){return this._options.mode}get missing(){return this._options.missing}get pathRoutes(){return this._pathRoutes}get namedRoutes(){return this._namedRoutes}get dynamicRoutes(){return this._dynamicRoutes}get routes(){return this._options.routes}get basePath(){return this._options.base}get suffix(){return this._options.suffix}removeRoute(index){const deleteRoute=this.findRoute(index);if(deleteRoute)return this._pathRoutes.delete(deleteRoute.path),deleteRoute.name&&this._namedRoutes.delete(deleteRoute.name),this.removeDynamicRoute(deleteRoute.path),this.removedFromRoutes(deleteRoute),deleteRoute}addRoute(route,parent){if(parent){const parentRoute=this.findRoute(parent);if(!parentRoute)throw new Error(`[Vitarx.Router.addRoute][ERROR]:父路由${parent}不存在`);parentRoute.children.includes(parentRoute)||parentRoute.children.push(this.registerRoute(route,parentRoute))}else this.registerRoute(route),this._options.routes.push(route)}findRoute(target){const isRouterTarget=typeof target=="object",index=isRouterTarget?target.index:target;if(typeof index!="string")throw new TypeError(`[Vitarx.Router.getRoute][ERROR]:路由索引${target}类型错误,必须给定字符串类型`);if(index.startsWith("/")){const matched=this.matchRoute(index);return matched?(matched.params&&isRouterTarget&&(target.params=Object.assign(target.params||{},matched.params)),matched.route):void 0}return this.findNamedRoute(index)}findPathRoute(path){return this._options.strict||(path=path.toLowerCase()),this._pathRoutes.get(path)}findNamedRoute(name){return this._namedRoutes.get(name)}findParentRoute(route){return this._parentRoute.get(route)}matchRoute(path){let formattedPath=formatPath(path);this._options.strict||(formattedPath=formattedPath.toLowerCase());try{const{path:shortPath,suffix}=splitPathAndSuffix(formattedPath),staticRoute=this._pathRoutes.get(shortPath);if(staticRoute&&validateSuffix(suffix,staticRoute.suffix,formattedPath,staticRoute.path))return{route:staticRoute,params:void 0};const segmentCount=shortPath.split("/").filter(Boolean).length,candidates=this._dynamicRoutes.get(segmentCount);if(candidates){const normalizedPath=`${shortPath}/`,regexCache=new Map;for(const{regex,route}of candidates){const match=(regexCache.get(regex.source)||regex).exec(normalizedPath);if(!match)continue;const params={},keys=Object.keys(route.pattern);for(let i=0;i<keys.length;i++)params[keys[i]]=match[i+1];if(validateSuffix(suffix,route.suffix,formattedPath,formattedPath))return{route,params}}}if(!suffix&&!shortPath.endsWith("/index")){const indexRoute=this._pathRoutes.get(`${shortPath==="/"?"":shortPath}/index`);if(indexRoute&&validateSuffix(suffix,indexRoute.suffix,formattedPath,indexRoute.path))return{route:indexRoute,params:void 0}}else if(shortPath==="/index"){const indexRoute=this._pathRoutes.get("/");if(indexRoute&&validateSuffix(suffix,indexRoute.suffix,formattedPath,indexRoute.path))return{route:indexRoute,params:void 0}}}catch(error){console.error("Error in matchRoute:",error);return}}setupRoutes(routes){for(const route of routes)this.registerRoute(route)}removedFromRoutes(route){const parent=this.findParentRoute(route);if(parent!=null&&parent.children){const index2=parent.children.indexOf(route);index2!==-1&&parent.children.splice(index2,1)}const index=this._options.routes.indexOf(route);index!==-1&&this._options.routes.splice(index,1)}removeDynamicRoute(path){if(!isVariablePath(path))return;const length=path.split("/").filter(Boolean).length,removeRouteFromRecords=key=>{const records=this._dynamicRoutes.get(key);if(records){for(let i=0;i<records.length;i++)if(records[i].route.path===path){records.splice(i,1);break}}};removeRouteFromRecords(length);const count=optionalVariableCount(path);if(count>0)for(let i=1;i<=count;i++)removeRouteFromRecords(length-i)}registerRoute(route,group){const normalizedRoute=normalizeRoute(route,group,this.suffix);if(group&&this._parentRoute.set(normalizedRoute,group),isRouteGroup(normalizedRoute)){this.recordRoute(normalizedRoute);for(const child of normalizedRoute.children)this.registerRoute(child,normalizedRoute);normalizedRoute.redirect||(normalizedRoute.redirect=function(to){var _a;let first=normalizedRoute.children[0];for(;first;){if(first.redirect)return typeof first.redirect=="function"?first.redirect.call(this,to):first.redirect;if(first.widget)return{index:first.path};first=(_a=first.children)==null?void 0:_a[0]}console.error(`[Vitarx.Router][ERROR]:${normalizedRoute.path} 分组路由在没有配置重定向的情况下,它的第一个子路由必须具有widget或redirect,否则无法匹配视图`,normalizedRoute)})}else this.recordRoute(normalizedRoute);return normalizedRoute}strictPath(path){return this._options.strict?path:path.toLowerCase()}recordRoute(route){if(route.name){if(route.name.startsWith("/")&&(route.name=route.name.replace(/^\//,""),console.warn(`[Vitarx.Router][WARN]:命名路由(name)不要以/开头: ${route.name},因为内部需要使用/区分path、name`)),this._namedRoutes.has(route.name))throw new Error(`[Vitarx.Router][ERROR]:检测到重复的路由名称(name): ${route.name}`);this._namedRoutes.set(route.name,route)}const path=this.strictPath(route.path);if(this._pathRoutes.has(path))throw new Error(`[Vitarx.Router][ERROR]:检测到重复的路由路径(path): ${route.path}`);this._pathRoutes.set(path,route),isVariablePath(route.path)&&this.recordDynamicRoute(route)}recordDynamicRoute(route){const{regex,length,optional}=createDynamicPattern(route.path,route.pattern,this.options.strict,this.options.pattern),addToLengthMap=len=>{this._dynamicRoutes.has(len)||this._dynamicRoutes.set(len,[]),this._dynamicRoutes.get(len).push({regex,route})};if(addToLengthMap(length),optional>0)for(let i=1;i<=optional;i++)addToLengthMap(length-i)}}const __stringValueKeys=["path","hash","index","fullPath"];function patchUpdate(location,newLocation){diffUpdateArrays(location.matched,newLocation.matched),diffUpdateObjects(location.params,newLocation.params),diffUpdateObjects(location.query,newLocation.query),diffUpdateObjects(location.meta,newLocation.meta);for(const key of __stringValueKeys)location[key]!==newLocation[key]&&(location[key]=newLocation[key])}function diffUpdateArrays(a,b){for(let i=0;i<b.length;i++)a[i]!==b[i]&&(a[i]=b[i]);a.length>b.length&&(a.length=b.length)}function diffUpdateObjects(a,b){const aKeys=new Set(Object.keys(a)),bKeys=Object.keys(b);for(const key of bKeys)a[key]=b[key],aKeys.delete(key);for(const key of aKeys)delete a[key]}function diffUpdateProps(oldProps,newProps){const removeKeys=new Set(Object.keys(oldProps)),bKeys=Object.keys(newProps),changes=[];for(const key of bKeys)key!=="key"&&(oldProps[key]!==newProps[key]&&(oldProps[key]=newProps[key],changes.push(key)),removeKeys.delete(key));changes.push(...removeKeys);for(const key of removeKeys)delete oldProps[key];return changes}const _RouterCore=class _RouterCore extends RouterRegistry{constructor(options){if(_RouterCore._instance)throw new Error("[Vitarx.Router.constructor]:路由器实例已存在,不能创建多个实例");super(options);__publicField(this,"_currentTaskId",null);__publicField(this,"_taskCounter",0);__publicField(this,"_pendingReplace",null);__publicField(this,"_pendingPush",null);__publicField(this,"_scrollBehaviorHandler");__publicField(this,"_currentRouteLocation");__publicField(this,"_readonlyRouteLocation");__publicField(this,"_isBrowser",typeof window<"u"&&typeof window.document<"u");__publicField(this,"_scrollBehavior","auto");this._currentRouteLocation=vitarx.reactive({index:this._options.base,path:this._options.base,hash:"",fullPath:"",params:{},query:{},matched:vitarx.shallowReactive([]),meta:vitarx.markRaw({}),suffix:""}),this._readonlyRouteLocation=vitarx.readonly(this._currentRouteLocation)}static get instance(){if(!_RouterCore._instance)throw new Error("[Vitarx.Router.instance]:路由器实例未初始化");return _RouterCore._instance}get initialized(){return _RouterCore._instance!==void 0}get isBrowser(){return this._isBrowser}get scrollBehavior(){return this._scrollBehavior}get options(){return this._options}get mode(){return this._options.mode}get currentRouteLocation(){return this._readonlyRouteLocation}get isPendingNavigation(){return!!(this._pendingReplace||this._pendingPush)}get pendingReplaceData(){return this._pendingReplace}get pendingPushData(){return this._pendingPush}static routeViewElement(route,name,index){return route?this.instance.createRouteViewElement(route,name):index===0&&name==="default"&&this.instance.missing&&!this.instance.isPendingNavigation?vitarx.createElement(this.instance.missing):void 0}back(){return this.go(-1)}forward(){return this.go(1)}replace(target){return typeof target=="string"?this.navigate({index:target,isReplace:!0}):(target.isReplace=!0,this.navigate(target))}push(target){return typeof target=="string"?this.navigate({index:target,isReplace:!1}):(target.isReplace=!1,this.navigate(target))}initialize(){return _RouterCore._instance?this:(this.setupRoutes(this._options.routes),typeof this.options.scrollBehavior=="function"?this._scrollBehaviorHandler=this.options.scrollBehavior:this._scrollBehavior=this.options.scrollBehavior,this.initializeRouter(),_RouterCore._instance=this,this)}scrollTo(scrollTarget){if(!(!this.isBrowser||!scrollTarget||typeof scrollTarget!="object"))try{if("el"in scrollTarget){const{el,...rest}=scrollTarget,element=typeof el=="string"?document.querySelector(el):el;element&&element instanceof Element&&(element.scrollIntoView?element.scrollIntoView({behavior:this.scrollBehavior,...rest}):window.scrollTo({behavior:this.scrollBehavior,top:element.getBoundingClientRect().top+window.scrollY,left:element.getBoundingClientRect().left+window.scrollX}));return}window.scrollTo({behavior:this.scrollBehavior,...scrollTarget})}catch(e){console.error("[Vitarx.Router.scrollTo][WARN]:滚动到指定位置时发生错误,请检查滚动目标参数是否正确",e)}}createRouteLocation(target){if(isRouteLocationTypeObject(target))return target;const route=this.findRoute(target),{index,query={},params={},hash=""}=target,path=route?mergePathParams(route.path,params):formatPath(index),matched=[];if(route){let parent=this.findParentRoute(route);for(;parent;)parent.widget&&matched.unshift(parent),parent=this.findParentRoute(parent);matched.push(route)}const meta=route!=null&&route.meta?vitarx.deepClone(route.meta):{},hashStr=formatHash(hash),suffix=getPathSuffix(index),fullPath=this.makeFullPath(path,query,hashStr,suffix);return{index,path,hash:hashStr,fullPath,params,query,matched,meta,suffix}}navigate(target){const taskId=++this._taskCounter;this._currentTaskId=taskId;const isCurrentTask=()=>this._currentTaskId===taskId,from=cloneRouteLocation(this.currentRouteLocation),performNavigation=async(_target,isRedirect)=>{const createNavigateResult=(overrides={})=>({from,to,status:NavigateStatus.success,message:"导航成功",redirectFrom:isRedirect?target:void 0,...overrides}),to=this.createRouteLocation(_target);if(to.fullPath===this.currentRouteLocation.fullPath&&vitarx.isDeepEqual(to.params,this.currentRouteLocation.params))return createNavigateResult({status:NavigateStatus.duplicated,message:"导航到相同的路由,被系统阻止!"});if(to.matched.at(-1)===this._currentRouteLocation.matched.at(-1)&&to.path===this._currentRouteLocation.path&&vitarx.isDeepEqual(to.query,this._currentRouteLocation.query)&&to.hash!==this._currentRouteLocation.hash)return this.updateHash(to.hash),createNavigateResult({status:NavigateStatus.success,message:"仅hash变化,导航成功!"});const matched=to.matched.at(-1);if(matched!=null&&matched.redirect){let redirectTarget;if(typeof matched.redirect=="object"&&matched.redirect.index)redirectTarget=matched.redirect;else if(typeof matched.redirect=="string")redirectTarget={index:matched.redirect};else if(typeof matched.redirect=="function"){const redirectHandleResult=matched.redirect.call(this,to);vitarx.isObject(redirectHandleResult)&&(redirectTarget=redirectHandleResult)}if(redirectTarget!=null&&redirectTarget.index)return performNavigation(redirectTarget,!0)}try{const result=await this.onBeforeEach(to,from);return result===!1?createNavigateResult({status:NavigateStatus.aborted,message:`导航到${to.index}目标时被前置守卫钩子阻止!`}):isCurrentTask()?typeof result=="object"&&result.index!==_target.index?(result.isReplace??(result.isReplace=!1),performNavigation(result,!0)):typeof result=="string"&&result!==_target.index?performNavigation({index:result,isReplace:!1},!0):!to.matched.length&&!this.missing?createNavigateResult({status:NavigateStatus.not_matched,message:`未匹配到任何路由规则,被系统阻止!请检测目标索引(${to.index})是否已注册路由。`}):("isReplace"in _target&&_target.isReplace?(this._pendingReplace=to,this.replaceHistory(to)):(this._pendingPush=to,this.pushHistory(to)),createNavigateResult(!to.matched.length&&this.missing?{status:NavigateStatus.not_matched,message:`${to.fullPath}未匹配到任何路由规则,被系统允许访问,因为系统定义了missing视图。`}:void 0)):createNavigateResult({status:NavigateStatus.cancelled,message:"已被新的导航请求替代,取消此次导航!"})}catch(error){return console.error("[Vitarx.Router.navigate][ERROR]:导航时捕获到了异常",error),createNavigateResult({status:NavigateStatus.exception,message:"导航时捕获到了异常",error})}};return performNavigation(target,!1)}updateQuery(query){vitarx.isDeepEqual(this._currentRouteLocation.query,query)||(this._currentRouteLocation.query=query,this._currentRouteLocation.fullPath=this.makeFullPath(this._currentRouteLocation.path,query,this._currentRouteLocation.hash,this._currentRouteLocation.suffix))}updateHash(hash){if(typeof hash!="string")throw new TypeError(`[Vitarx.Router.updateHash][WARN]:hash值只能是字符串类型,给定${hash}`);const newHash=formatHash(hash);newHash!==this._currentRouteLocation.hash&&(this._currentRouteLocation.hash=newHash,this._currentRouteLocation.fullPath=this.makeFullPath(this._currentRouteLocation.path,this._currentRouteLocation.query,newHash,this._currentRouteLocation.suffix))}createViewProps(route,name){var _a;const injectProps=(_a=route.injectProps)==null?void 0:_a[name];let props;return injectProps===!0?props=JSON.parse(JSON.stringify(this._currentRouteLocation.params)):injectProps===!1?props={}:typeof injectProps=="function"?props=injectProps(this.currentRouteLocation):vitarx.isRecordObject(injectProps)?props=injectProps:props={},props}createRouteViewElement(route,name){var _a;const widget=(_a=route.widget)==null?void 0:_a[name];if(!widget)return;const props=this.createViewProps(route,name);return props.key=route.path,vitarx.createElement(widget,props)}_completeViewRender(){}completeNavigation(savedPosition){const newData=this.pendingReplaceData||this.pendingPushData;if(!newData)throw new Error("[Vitarx.Router.completeNavigation][ERROR]:没有处于等待状态的导航请求。");const from=cloneRouteLocation(this.currentRouteLocation);this._completeViewRender=()=>{this.onScrollBehavior(this.currentRouteLocation,from,savedPosition).then(),this.onAfterEach(this.currentRouteLocation,from)},this.updateRouteLocation(newData),this._pendingReplace=null,this._pendingPush=null}makeFullPath(path,query,hash,suffix){return hash&&!hash.startsWith("#")&&(hash=`#${hash}`),typeof query=="object"&&(query=objectToQueryString(query)),path=addPathSuffix(path,suffix||this._options.defaultSuffix),this.mode==="hash"?formatPath(`${this.basePath}/${query}#${path}${hash}`):formatPath(`${this.basePath}${path}${query}${hash}`)}onBeforeEach(to,from){var _a;const matched=to.matched.at(-1);return matched&&"beforeEnter"in matched&&typeof matched.beforeEnter=="function"?matched.beforeEnter.call(this,to,from):(_a=this._options.beforeEach)==null?void 0:_a.call(this,to,from)}onAfterEach(to,from){var _a;const matched=to.matched.at(-1);if(matched)return"afterEnter"in matched&&typeof matched.afterEnter=="function"?matched.afterEnter.call(this,to,from):(_a=this._options.afterEach)==null?void 0:_a.call(this,to,from)}updateRouteLocation(newLocation){patchUpdate(this._currentRouteLocation,newLocation)}async onScrollBehavior(to,from,savedPosition){try{if(this._scrollBehaviorHandler){const scrollTarget=await this._scrollBehaviorHandler(to,from,savedPosition);scrollTarget&&this.scrollTo(scrollTarget)}else!savedPosition&&!to.hash?this.scrollTo({left:0,top:0}):this.scrollTo(savedPosition??{el:to.hash})}catch(e){console.error("[Vitarx.Router.onScrollBehavior]['ERROR']:处理滚动行为时捕获到了异常",e)}}removeRoute(index){const removed=super.removeRoute(index);if(removed){const index2=this._currentRouteLocation.matched.indexOf(removed);index2!==-1&&this._currentRouteLocation.matched.splice(index2,1)}return removed}install(app){app.provide("router",this)}};__publicField(_RouterCore,"_instance");let RouterCore=_RouterCore;class RouterHistory extends RouterCore{constructor(options){["path","hash"].includes(options.mode)||(options.mode="hash"),super(options),options.mode==="hash"&&this.ensureHash()}updateHash(hash){if(super.updateHash(hash),this.saveCurrentScrollPosition(),this.webHistory.pushState(this.createState(this.currentRouteLocation),"",this.currentRouteLocation.fullPath),!hash.trim())window.scrollTo(0,0);else{const anchorId=hash.startsWith("#")?hash.slice(1):hash;try{const element=window.document.getElementById(anchorId);element&&element.scrollIntoView({behavior:this.options.anchorsScrollBehavior})}catch(e){console.error(`滚动到目标锚点${hash}失败`,e)}}}updateQuery(query){super.updateQuery(query),this.webHistory.pushState(this.createState(this.currentRouteLocation),"",this.currentRouteLocation.fullPath)}get currentRouteTarget(){return urlToRouteTarget(window.location,this.mode,this.basePath)}get webHistory(){return window.history}go(delta){this.webHistory.go(delta)}initializeRouter(){window.addEventListener("popstate",this.onPopState.bind(this)),this.replace(this.currentRouteTarget).then(res=>{res.status!==NavigateStatus.success&&console.warn(`[VitarxRouter.initializeRouter]:路由初始化匹配失败,${res.message}`)})}pushHistory(data){this.saveCurrentScrollPosition(),this.webHistory.pushState(this.createState(data),"",data.fullPath),this.completeNavigation()}replaceHistory(data){var _a;const scrollPosition=(_a=this.webHistory.state)==null?void 0:_a.scrollPosition;this.webHistory.replaceState(this.createState(data),"",data.fullPath),this.completeNavigation(scrollPosition)}saveCurrentScrollPosition(){const scrollPosition={left:window.scrollX,top:window.scrollY,behavior:this.scrollBehavior};this.webHistory.replaceState({...this.webHistory.state,scrollPosition},"",window.location.href)}createState(data,hash,query){const{matched,...state}=data;return typeof hash=="string"&&(state.hash=hash),typeof query=="object"&&(state.query=query),JSON.parse(JSON.stringify(state))}onPopState(event){var _a;let newTarget;(_a=event.state)!=null&&_a.index?newTarget={index:event.state.index,hash:event.state.hash,query:event.state.query}:newTarget=this.currentRouteTarget,this.replace(newTarget).then(res=>{if(!res.redirectFrom&&this.mode==="hash"&&res.status!==NavigateStatus.success)if(res.status===NavigateStatus.not_matched){if(res.to.index.startsWith("/")){const anchorId=res.to.index.slice(1),element=window.document.getElementById(anchorId);element&&element.scrollIntoView({behavior:this.scrollBehavior}),this.updateHash(`#${anchorId}`)}}else res.status===NavigateStatus.duplicated&&this.webHistory.replaceState(this.createState(this.currentRouteLocation),"",this.currentRouteLocation.fullPath)})}ensureHash(){const{pathname,search,hash}=window.location;if(!hash){const path=`${this.basePath}${search}#${pathname}`;window.location.replace(path)}}}class RouterMemory extends RouterCore{constructor(options){super(options);__publicField(this,"_history",[]);__publicField(this,"_pendingGo",null);__publicField(this,"_currentIndex",0);options.mode="memory"}get currentIndex(){return this._currentIndex}go(delta){if(!delta)return;const currentIndex=this.currentIndex,targetIndex=Math.max(0,Math.min(this._history.length-1,currentIndex+delta));if(targetIndex===currentIndex)return;const target=this._history[targetIndex];this._pendingGo=targetIndex,this.navigate(target).then(res=>{res.status!==NavigateStatus.success&&(this._pendingGo=null)})}initializeRouter(){this._history.push(this.currentRouteLocation)}pushHistory(data){this._updateHistory(data,!1)}replaceHistory(data){this._updateHistory(data,!0)}_updateHistory(data,isReplace){let newIndex;if(this._pendingGo!==null)this._history[this._pendingGo]=data,newIndex=this._pendingGo;else if(isReplace)this._history[this.currentIndex]=data,newIndex=this.currentIndex;else{const nextIndex=this.currentIndex+1;nextIndex<this._history.length?(this._history[nextIndex]=data,this._history.length=nextIndex+1,newIndex=nextIndex):(this._history.push(data),newIndex=this._history.length-1)}this._currentIndex=newIndex,this.completeNavigation(),this._pendingGo=null}}function defineRoutes(...routes){return routes}function defineRoute(route){return route}function createRouter(options){let router;return typeof window>"u"&&options.mode!=="memory"?(console.warn("当前环境非浏览器端,强制使用内存模式路由"),options.mode="memory",new RouterMemory(options).initialize()):(options.mode==="memory"?router=new RouterMemory(options):router=new RouterHistory(options),router.initialize())}function useRouter(){return RouterCore.instance}function useRoute(){return RouterCore.instance.currentRouteLocation}const INDEX_SYMBOL=Symbol("RouterViewCounter");class RouterView extends vitarx.Widget{constructor(props){super(props);__publicField(this,"_$index");__publicField(this,"_$currentRoute");__publicField(this,"_$currentElement",vitarx.shallowRef());const parentIndex=vitarx.inject(INDEX_SYMBOL,-1);this._$index=parentIndex+1,vitarx.provide(INDEX_SYMBOL,this._$index),this._$currentRoute=this.matchedRoute,this._$currentElement.value=RouterCore.routeViewElement(this._$currentRoute,this.name,this._$index);const router=useRouter();let paramStr=JSON.stringify(this.location.params);vitarx.watch(this.location.matched,(_c,o)=>{const newRoute=o[this.index];newRoute!==this._$currentRoute&&(this._$currentRoute=newRoute,this._$currentElement.value=RouterCore.routeViewElement(newRoute,this.name,this._$index))}),vitarx.watch(this.location.params,()=>{if(!this._$currentRoute)return;const newParams=JSON.stringify(this.location.params);if(newParams!==paramStr){paramStr=newParams;const newProps=router.createViewProps(this._$currentRoute,this.name),oldProps=vitarx.toRaw(this._$currentElement.value.props),changes=diffUpdateProps(oldProps,newProps);changes.length>0&&vitarx.Observer.notify(this._$currentElement.value.props,changes)}})}get index(){return this._$index}get isLastView(){return this.index===this.location.matched.length-1&&this.name==="default"}get name(){return this.props.name||"default"}get matchedRoute(){return this.location.matched[this.index]}get currentElement(){return this._$currentElement.value}get currentWidget(){var _a;return(_a=this._$currentElement.value)==null?void 0:_a.type}get location(){return RouterCore.instance.currentRouteLocation}onMounted(){this.completeViewRender()}onUpdated(){this.completeViewRender()}build(){return this.currentElement||null}completeViewRender(){this.isLastView&&RouterCore.instance._completeViewRender()}}class RouterLink extends vitarx.Widget{constructor(props){super(props);__publicField(this,"target");__publicField(this,"location");__publicField(this,"active");__publicField(this,"htmlProps");this.target=new vitarx.Computed(()=>{if(!this.props.to)return;const to=vitarx.isString(props.to)?{index:decodeURIComponent(props.to)}:props.to;if(RouterLink.isHttpOrHttpsUrl(to.index)||to.index.startsWith("#"))return to.index;if(to.index.includes("#")){const[index,hash]=to.index.split("#",2);to.index=index,to.hash=`#${hash}`}return to}),this.location=new vitarx.Computed(()=>{if(!this.target.value||typeof this.target.value=="string")return;const location=RouterCore.instance.createRouteLocation(this.target.value);return location.matched.length||console.warn(`[Vitarx.RouterLink][WARN]:索引:${this.target.value.index},未匹配到任何有效的路由线路,请检查to属性是否配置正确!`),location}),props.active!==void 0&&props.active!=="none"&&(this.active=new vitarx.Computed(()=>!this.location.value||typeof this.target.value=="string"||!this.target.value?!1:this.target.value.index.startsWith("/")?props.active==="obscure"?this.location.value.path==="/"?RouterCore.instance.currentRouteLocation.path==="/":RouterCore.instance.currentRouteLocation.fullPath.startsWith(this.location.value.path):this.location.value.path===RouterCore.instance.currentRouteLocation.path:!!RouterCore.instance.currentRouteLocation.matched.find(route=>route.name===this.target.value.index))),this.htmlProps=new vitarx.Computed(()=>{var _a;const props2={href:this.href,onClick:e=>this.navigate(e),children:this.children??((_a=this.location.value)==null?void 0:_a.index),draggable:this.props.draggable??!1,"v-bind":[this.props,["to","children","href","disabled","active","callback","onClick","onclick","aria-current"]]};return this.isActive&&(props2["aria-current"]="page"),this.isDisabled&&(props2.disabled=!0),props2})}static isHttpOrHttpsUrl(url){return/^(https?):\/\/[^\s\/$.?#].\S*$/i.test(url)}get isActive(){var _a;return((_a=this.active)==null?void 0:_a.value)&&!this.isDisabled}get isDisabled(){return this.props.disabled??!1}get href(){var _a;return typeof this.target.value=="string"?this.target.value:((_a=this.location.value)==null?void 0:_a.fullPath)||"javascript:void(0)"}navigate(e){typeof this.target.value!="string"&&(e.preventDefault(),this.location.value&&!this.isDisabled&&RouterCore.instance.navigate(this.location.value).then(res=>{var _a;res.status!==NavigateStatus.success&&console.warn(`[Vitarx.RouterLink][WARN]:导航到索引:${(_a=this.target.value)==null?void 0:_a.index}失败,${res.message}`),this.props.callback&&this.props.callback(res)}))}build(){return vitarx.createElement("a",this.htmlProps.value)}}return exports.HistoryRouter=RouterHistory,exports.MemoryRouter=RouterMemory,exports.NavigateStatus=NavigateStatus,exports.Router=RouterCore,exports.RouterLink=RouterLink,exports.RouterView=RouterView,exports.createRouter=createRouter,exports.defineRoute=defineRoute,exports.defineRoutes=defineRoutes,exports.useRoute=useRoute,exports.useRouter=useRouter,Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),exports})({},Vitarx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitarx-router",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-beta.1",
4
4
  "description": "Vitarx前端框架的配套路由器",
5
5
  "author": "ZhuChongLin <8210856@qq.com>",
6
6
  "license": "MIT",
@@ -12,28 +12,21 @@
12
12
  "keywords": [
13
13
  "vitarx",
14
14
  "router",
15
- "vitarx-router",
16
- "vitarx-router-lib"
15
+ "vitarx-router"
17
16
  ],
18
17
  "type": "module",
19
- "main": "./dist/vitarx-router.umd.js",
20
18
  "module": "./dist/vitarx-router.es.js",
21
19
  "types": "./dist/vitarx-router.d.ts",
22
- "unpkg": "./dist/vitarx-router.umd.js",
23
- "jsdelivr": "./dist/vitarx-router.umd.js",
20
+ "unpkg": "./dist/vitarx-router.iife.js",
21
+ "jsdelivr": "./dist/vitarx-router.iife.js",
24
22
  "exports": {
25
23
  ".": {
26
- "require": {
27
- "types": "./dist/vitarx-router.d.ts",
28
- "node": "./dist/vitarx-router.umd.js"
29
- },
30
24
  "import": {
31
25
  "types": "./dist/vitarx-router.d.ts",
32
- "node": "./index.mjs",
33
26
  "default": "./dist/vitarx-router.es.js"
34
27
  }
35
28
  },
36
- "./scripts/make-type": {
29
+ "./make": {
37
30
  "types": "./dist/scripts/type-make.d.ts",
38
31
  "default": "./dist/scripts/type-make.js"
39
32
  }
@@ -45,10 +38,10 @@
45
38
  "push": "npm publish --access=public"
46
39
  },
47
40
  "peerDependencies": {
48
- "vitarx": "^3.0.0-alpha.5"
41
+ "vitarx": "^3.0.0-beta.1"
49
42
  },
50
43
  "devDependencies": {
51
- "@types/node": "^22.17.2",
44
+ "@types/node": "^22.18.0",
52
45
  "@vitarx/vite-bundler": "3.0.0-alpha.1",
53
46
  "prettier": "^3.6.2",
54
47
  "typescript": "^5.9.2",
@@ -58,7 +51,6 @@
58
51
  "files": [
59
52
  "dist",
60
53
  "LICENSE",
61
- "README.md",
62
- "index.mjs"
54
+ "README.md"
63
55
  ]
64
56
  }
@@ -1 +0,0 @@
1
- (function(global,factory){typeof exports=="object"&&typeof module<"u"?factory(exports,require("vitarx")):typeof define=="function"&&define.amd?define(["exports","vitarx"],factory):(global=typeof globalThis<"u"?globalThis:global||self,factory(global.VitarxRouter={},global.Vitarx))})(this,(function(exports2,vitarx){"use strict";var __defProp=Object.defineProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:!0,configurable:!0,writable:!0,value}):obj[key]=value;var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!="symbol"?key+"":key,value);var NavigateStatus=(NavigateStatus2=>(NavigateStatus2[NavigateStatus2.success=0]="success",NavigateStatus2[NavigateStatus2.aborted=1]="aborted",NavigateStatus2[NavigateStatus2.cancelled=2]="cancelled",NavigateStatus2[NavigateStatus2.duplicated=3]="duplicated",NavigateStatus2[NavigateStatus2.not_matched=4]="not_matched",NavigateStatus2[NavigateStatus2.exception=5]="exception",NavigateStatus2))(NavigateStatus||{});function isVariablePath(path){return/\{[^}]+}/.test(path)}function optionalVariableCount(path){const pathWithoutSpaces=path.replace(/\s+/g,""),regex=/\{[\w-]+\?}/g,matches=pathWithoutSpaces.match(regex);return matches?matches.length:0}function isRouteGroup(route){return"children"in route&&route.children!==void 0&&route.children.length>0}function createDynamicPattern(path,pattern,strict,defaultPattern){let optional=0;const processVariable=(varName,isOptional)=>{const regex=pattern[varName];if(regex?regex instanceof RegExp||(console.warn(`[Vitarx.Router][WARN]:${path} 动态路径${varName}变量的自定义正则表达式必须是 RegExp 类型`),pattern[varName]=defaultPattern):pattern[varName]=defaultPattern,isOptional)return optional++,`(?:(${pattern[varName].source}))?`;if(optional)throw new Error(`[Vitarx.Router][ERROR]:动态路径 ${path} 中,可选变量 ${varName} 后不能存在任何必填变量`);return`(${pattern[varName].source})`},processedPath=path.replace(/{([^}?]+)\?}/g,(_,varName)=>processVariable(varName,!0)).replace(/{([^}]+)}/g,(_,varName)=>processVariable(varName,!1)).replace(/\//g,"\\/").replace(/\/?$/,"/?"),flags=strict?"":"i",segments=path.replace(/^\/|\/$/g,"").split("/").length;return{regex:new RegExp(`^${processedPath}$`,flags),length:segments,optional}}function formatPath(path){return path=`/${path}`.replace(/\s+/g,"").replace(/\/+/g,"/"),path.length?path==="/"||path==="/#/"?path:path.replace(/\/$/,""):"/"}function mergePathParams(path,params){if(!isVariablePath(path))return path;const oldPath=path;return path=path.replace(/{([^}]+)\?*}/g,(_match,paramName)=>{const isOptional=paramName.endsWith("?");if(isOptional&&(paramName=paramName.slice(0,-1)),params[paramName]===void 0){if(isOptional)return"";throw new TypeError(`[Vitarx.Router.mergePathParams] 访问路由${oldPath}时缺少参数:${paramName}`)}return String(params[paramName]).replace(/\s+/g,"_")}),formatPath(path)}function formatHash(hash,addHashPrefix){return typeof hash!="string"||!hash?"":(hash=hash.trim(),hash.startsWith("#")?hash:`#${hash}`)}function queryStringToObject(queryString){queryString=decodeURIComponent(queryString);const params=new URLSearchParams(queryString.startsWith("?")?queryString.substring(1):queryString),obj={};return params.forEach((value,key)=>obj[key]=value),obj}function objectToQueryString(obj){const queryString=new URLSearchParams(obj).toString();return queryString?`?${queryString}`:""}function urlToRouteTarget(url,mode,base){let path=decodeURIComponent(url.pathname),hash=decodeURIComponent(url.hash),query=queryStringToObject(url.search);if(path=formatPath(path.startsWith(base)?path.slice(base.length):path),mode==="hash"&&hash.includes("#/")){const hashPart=hash.slice(1),[fullPath,anchor]=hashPart.split("#");path=formatPath(fullPath||"/"),hash=anchor?`#${anchor}`:""}return{index:path,hash,query}}function splitPathAndSuffix(path){const suffix=getPathSuffix(path);return suffix&&(path=path.slice(0,-suffix.length)),{path,suffix:suffix.substring(1)}}function getPathSuffix(path){const lastDotIndex=path.lastIndexOf(".");return lastDotIndex!==-1&&lastDotIndex<path.length-1?`.${path.substring(lastDotIndex+1)}`:""}function isRouteLocationTypeObject(obj){if(typeof obj!="object"||obj===null)return!1;const keys=["index","fullPath","path","hash","params","query","matched","meta"];for(const key of keys)if(!Object.prototype.hasOwnProperty.call(obj,key))return!1;return!0}function validateSuffix(suffix,allowSuffix,inputPath,routePath){return inputPath==="/"||allowSuffix==="*"?!0:allowSuffix===!1?inputPath===routePath:Array.isArray(allowSuffix)?allowSuffix.includes(suffix):suffix===allowSuffix}function addPathSuffix(path,suffix){return suffix&&!path.endsWith("/")&&!path.includes(".")&&(path+=suffix.startsWith(".")?suffix:`.${suffix}`),path}function cloneRouteLocation(route){const{matched,...other}=route;return Object.assign(vitarx.deepClone(other),{matched:Array.from(matched)})}const validInjectProps=props=>["boolean","function"].includes(typeof props);function normalizeInjectProps(route){if(!route.widget)return;const injectProps={},inputValue=route.injectProps??!0,type=typeof inputValue;if(type==="object")for(const name in route.widget){const value=inputValue[name];if(value&&!validInjectProps(value))throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${route.path} 路由线路配置,injectProps.${name}值错误,仅支持boolean、function类型`);injectProps[name]=value??!0}else if(type==="function"||type==="boolean")for(const name in route.widget)injectProps[name]=inputValue;else throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${route.path} 路由线路配置,injectProps属性配置错误,仅支持boolean、{key:boolean|function}、function类型`);route.injectProps=injectProps}const validWidgetType=(widget,path)=>{const type=typeof widget;if(type!=="function"){if(type==="object"){if(!widget.default)throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${path} 路由配置,widget传入对象时则认为是命名视图,命名视图必须具有default视图`);for(const k in widget)validWidgetType(widget[k],path);return}throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${path} 路由配置,widget配置无效`)}};function normalizeRouteWidget(route){const isGroup=route.children.length;if(route.widget)validWidgetType(route.widget,route.path);else if(!isGroup)throw new TypeError(`[Vitarx.Router][ERROR]:请检查 ${route.path} 路由配置,widget和children不能同时为空。`);typeof route.widget=="function"&&(route.widget={default:route.widget})}function normalizeRoute(route,group,suffix){if(route.meta=route.meta||{},route.pattern=route.pattern||{},route.children=route.children||[],!Array.isArray(route.children))throw new TypeError(`[Vitarx.Router][TYPE_ERROR]:${route.path} 路由线路配置 children 类型错误,它必须是数组类型。`);if(!route.path.trim())throw new TypeError("[Vitarx.Router][TYPE_ERROR]:路由线路配置 path 不能为空");return route.path=formatPath(group?`${group.path}/${route.path}`:route.path),normalizeRouteWidget(route),normalizeInjectProps(route),route.suffix??(route.suffix=(group==null?void 0:group.suffix)??suffix),route.afterEnter??(route.afterEnter=group==null?void 0:group.afterEnter),route.beforeEnter??(route.beforeEnter=group==null?void 0:group.beforeEnter),route}class RouterRegistry{constructor(options){__publicField(this,"_options");__publicField(this,"_namedRoutes",new Map);__publicField(this,"_dynamicRoutes",new Map);__publicField(this,"_pathRoutes",new Map);__publicField(this,"_parentRoute",new WeakMap);const config={base:"/",strict:!1,mode:"path",scrollBehavior:"auto",anchorsScrollBehavior:"auto",suffix:"*",pattern:/[\w.]+/,defaultSuffix:"",...options};if(config.base=`/${config.base.replace(/^\/+|\/+$/g,"")}`,typeof config.suffix=="string"?config.suffix=config.suffix.replace(/\./g,""):Array.isArray(config.suffix)&&(config.suffix=config.suffix.map(item=>item.replace(/\./g,""))),config.defaultSuffix&&(config.defaultSuffix=config.defaultSuffix.replace(/\./g,"")),config.missing&&typeof config.missing!="function")throw new TypeError("[VitarxRouter][ERROR]:missing配置无效");this._options=config}get options(){return this._options}get mode(){return this._options.mode}get missing(){return this._options.missing}get pathRoutes(){return this._pathRoutes}get namedRoutes(){return this._namedRoutes}get dynamicRoutes(){return this._dynamicRoutes}get routes(){return this._options.routes}get basePath(){return this._options.base}get suffix(){return this._options.suffix}removeRoute(index){const deleteRoute=this.findRoute(index);if(deleteRoute)return this._pathRoutes.delete(deleteRoute.path),deleteRoute.name&&this._namedRoutes.delete(deleteRoute.name),this.removeDynamicRoute(deleteRoute.path),this.removedFromRoutes(deleteRoute),deleteRoute}addRoute(route,parent){if(parent){const parentRoute=this.findRoute(parent);if(!parentRoute)throw new Error(`[Vitarx.Router.addRoute][ERROR]:父路由${parent}不存在`);parentRoute.children.includes(parentRoute)||parentRoute.children.push(this.registerRoute(route,parentRoute))}else this.registerRoute(route),this._options.routes.push(route)}findRoute(target){const isRouterTarget=typeof target=="object",index=isRouterTarget?target.index:target;if(typeof index!="string")throw new TypeError(`[Vitarx.Router.getRoute][ERROR]:路由索引${target}类型错误,必须给定字符串类型`);if(index.startsWith("/")){const matched=this.matchRoute(index);return matched?(matched.params&&isRouterTarget&&(target.params=Object.assign(target.params||{},matched.params)),matched.route):void 0}return this.findNamedRoute(index)}findPathRoute(path){return this._options.strict||(path=path.toLowerCase()),this._pathRoutes.get(path)}findNamedRoute(name){return this._namedRoutes.get(name)}findParentRoute(route){return this._parentRoute.get(route)}matchRoute(path){let formattedPath=formatPath(path);this._options.strict||(formattedPath=formattedPath.toLowerCase());try{const{path:shortPath,suffix}=splitPathAndSuffix(formattedPath),staticRoute=this._pathRoutes.get(shortPath);if(staticRoute&&validateSuffix(suffix,staticRoute.suffix,formattedPath,staticRoute.path))return{route:staticRoute,params:void 0};const segmentCount=shortPath.split("/").filter(Boolean).length,candidates=this._dynamicRoutes.get(segmentCount);if(candidates){const normalizedPath=`${shortPath}/`,regexCache=new Map;for(const{regex,route}of candidates){const match=(regexCache.get(regex.source)||regex).exec(normalizedPath);if(!match)continue;const params={},keys=Object.keys(route.pattern);for(let i=0;i<keys.length;i++)params[keys[i]]=match[i+1];if(validateSuffix(suffix,route.suffix,formattedPath,formattedPath))return{route,params}}}if(!suffix&&!shortPath.endsWith("/index")){const indexRoute=this._pathRoutes.get(`${shortPath==="/"?"":shortPath}/index`);if(indexRoute&&validateSuffix(suffix,indexRoute.suffix,formattedPath,indexRoute.path))return{route:indexRoute,params:void 0}}else if(shortPath==="/index"){const indexRoute=this._pathRoutes.get("/");if(indexRoute&&validateSuffix(suffix,indexRoute.suffix,formattedPath,indexRoute.path))return{route:indexRoute,params:void 0}}}catch(error){console.error("Error in matchRoute:",error);return}}setupRoutes(routes){for(const route of routes)this.registerRoute(route)}removedFromRoutes(route){const parent=this.findParentRoute(route);if(parent!=null&&parent.children){const index2=parent.children.indexOf(route);index2!==-1&&parent.children.splice(index2,1)}const index=this._options.routes.indexOf(route);index!==-1&&this._options.routes.splice(index,1)}removeDynamicRoute(path){if(!isVariablePath(path))return;const length=path.split("/").filter(Boolean).length,removeRouteFromRecords=key=>{const records=this._dynamicRoutes.get(key);if(records){for(let i=0;i<records.length;i++)if(records[i].route.path===path){records.splice(i,1);break}}};removeRouteFromRecords(length);const count=optionalVariableCount(path);if(count>0)for(let i=1;i<=count;i++)removeRouteFromRecords(length-i)}registerRoute(route,group){const normalizedRoute=normalizeRoute(route,group,this.suffix);if(group&&this._parentRoute.set(normalizedRoute,group),isRouteGroup(normalizedRoute)){this.recordRoute(normalizedRoute);for(const child of normalizedRoute.children)this.registerRoute(child,normalizedRoute);normalizedRoute.redirect||(normalizedRoute.redirect=function(to){var _a;let first=normalizedRoute.children[0];for(;first;){if(first.redirect)return typeof first.redirect=="function"?first.redirect.call(this,to):first.redirect;if(first.widget)return{index:first.path};first=(_a=first.children)==null?void 0:_a[0]}console.error(`[Vitarx.Router][ERROR]:${normalizedRoute.path} 分组路由在没有配置重定向的情况下,它的第一个子路由必须具有widget或redirect,否则无法匹配视图`,normalizedRoute)})}else this.recordRoute(normalizedRoute);return normalizedRoute}strictPath(path){return this._options.strict?path:path.toLowerCase()}recordRoute(route){if(route.name){if(route.name.startsWith("/")&&(route.name=route.name.replace(/^\//,""),console.warn(`[Vitarx.Router][WARN]:命名路由(name)不要以/开头: ${route.name},因为内部需要使用/区分path、name`)),this._namedRoutes.has(route.name))throw new Error(`[Vitarx.Router][ERROR]:检测到重复的路由名称(name): ${route.name}`);this._namedRoutes.set(route.name,route)}const path=this.strictPath(route.path);if(this._pathRoutes.has(path))throw new Error(`[Vitarx.Router][ERROR]:检测到重复的路由路径(path): ${route.path}`);this._pathRoutes.set(path,route),isVariablePath(route.path)&&this.recordDynamicRoute(route)}recordDynamicRoute(route){const{regex,length,optional}=createDynamicPattern(route.path,route.pattern,this.options.strict,this.options.pattern),addToLengthMap=len=>{this._dynamicRoutes.has(len)||this._dynamicRoutes.set(len,[]),this._dynamicRoutes.get(len).push({regex,route})};if(addToLengthMap(length),optional>0)for(let i=1;i<=optional;i++)addToLengthMap(length-i)}}const __stringValueKeys=["path","hash","index","fullPath"];function patchUpdate(location,newLocation){diffUpdateArrays(location.matched,newLocation.matched),diffUpdateObjects(location.params,newLocation.params),diffUpdateObjects(location.query,newLocation.query),diffUpdateObjects(location.meta,newLocation.meta);for(const key of __stringValueKeys)location[key]!==newLocation[key]&&(location[key]=newLocation[key])}function diffUpdateArrays(a,b){for(let i=0;i<b.length;i++)a[i]!==b[i]&&(a[i]=b[i]);a.length>b.length&&(a.length=b.length)}function diffUpdateObjects(a,b){const aKeys=new Set(Object.keys(a)),bKeys=Object.keys(b);for(const key of bKeys)a[key]=b[key],aKeys.delete(key);for(const key of aKeys)delete a[key]}function diffUpdateProps(oldProps,newProps){const removeKeys=new Set(Object.keys(oldProps)),bKeys=Object.keys(newProps),changes=[];for(const key of bKeys)key!=="key"&&(oldProps[key]!==newProps[key]&&(oldProps[key]=newProps[key],changes.push(key)),removeKeys.delete(key));changes.push(...removeKeys);for(const key of removeKeys)delete oldProps[key];return changes}const _RouterCore=class _RouterCore extends RouterRegistry{constructor(options){if(_RouterCore._instance)throw new Error("[Vitarx.Router.constructor]:路由器实例已存在,不能创建多个实例");super(options);__publicField(this,"_currentTaskId",null);__publicField(this,"_taskCounter",0);__publicField(this,"_pendingReplace",null);__publicField(this,"_pendingPush",null);__publicField(this,"_scrollBehaviorHandler");__publicField(this,"_currentRouteLocation");__publicField(this,"_readonlyRouteLocation");__publicField(this,"_isBrowser",typeof window<"u"&&typeof window.document<"u");__publicField(this,"_scrollBehavior","auto");this._currentRouteLocation=vitarx.reactive({index:this._options.base,path:this._options.base,hash:"",fullPath:"",params:{},query:{},matched:vitarx.shallowReactive([]),meta:vitarx.markRaw({}),suffix:""}),this._readonlyRouteLocation=vitarx.readonly(this._currentRouteLocation)}static get instance(){if(!_RouterCore._instance)throw new Error("[Vitarx.Router.instance]:路由器实例未初始化");return _RouterCore._instance}get initialized(){return _RouterCore._instance!==void 0}get isBrowser(){return this._isBrowser}get scrollBehavior(){return this._scrollBehavior}get options(){return this._options}get mode(){return this._options.mode}get currentRouteLocation(){return this._readonlyRouteLocation}get isPendingNavigation(){return!!(this._pendingReplace||this._pendingPush)}get pendingReplaceData(){return this._pendingReplace}get pendingPushData(){return this._pendingPush}static routeViewElement(route,name,index){return route?this.instance.createRouteViewElement(route,name):index===0&&name==="default"&&this.instance.missing&&!this.instance.isPendingNavigation?vitarx.createElement(this.instance.missing):void 0}back(){return this.go(-1)}forward(){return this.go(1)}replace(target){return typeof target=="string"?this.navigate({index:target,isReplace:!0}):(target.isReplace=!0,this.navigate(target))}push(target){return typeof target=="string"?this.navigate({index:target,isReplace:!1}):(target.isReplace=!1,this.navigate(target))}initialize(){return _RouterCore._instance?this:(this.setupRoutes(this._options.routes),typeof this.options.scrollBehavior=="function"?this._scrollBehaviorHandler=this.options.scrollBehavior:this._scrollBehavior=this.options.scrollBehavior,this.initializeRouter(),_RouterCore._instance=this,this)}scrollTo(scrollTarget){if(!(!this.isBrowser||!scrollTarget||typeof scrollTarget!="object"))try{if("el"in scrollTarget){const{el,...rest}=scrollTarget,element=typeof el=="string"?document.querySelector(el):el;element&&element instanceof Element&&(element.scrollIntoView?element.scrollIntoView({behavior:this.scrollBehavior,...rest}):window.scrollTo({behavior:this.scrollBehavior,top:element.getBoundingClientRect().top+window.scrollY,left:element.getBoundingClientRect().left+window.scrollX}));return}window.scrollTo({behavior:this.scrollBehavior,...scrollTarget})}catch(e){console.error("[Vitarx.Router.scrollTo][WARN]:滚动到指定位置时发生错误,请检查滚动目标参数是否正确",e)}}createRouteLocation(target){if(isRouteLocationTypeObject(target))return target;const route=this.findRoute(target),{index,query={},params={},hash=""}=target,path=route?mergePathParams(route.path,params):formatPath(index),matched=[];if(route){let parent=this.findParentRoute(route);for(;parent;)parent.widget&&matched.unshift(parent),parent=this.findParentRoute(parent);matched.push(route)}const meta=route!=null&&route.meta?vitarx.deepClone(route.meta):{},hashStr=formatHash(hash),suffix=getPathSuffix(index),fullPath=this.makeFullPath(path,query,hashStr,suffix);return{index,path,hash:hashStr,fullPath,params,query,matched,meta,suffix}}navigate(target){const taskId=++this._taskCounter;this._currentTaskId=taskId;const isCurrentTask=()=>this._currentTaskId===taskId,from=cloneRouteLocation(this.currentRouteLocation),performNavigation=async(_target,isRedirect)=>{const createNavigateResult=(overrides={})=>({from,to,status:NavigateStatus.success,message:"导航成功",redirectFrom:isRedirect?target:void 0,...overrides}),to=this.createRouteLocation(_target);if(to.fullPath===this.currentRouteLocation.fullPath&&vitarx.isDeepEqual(to.params,this.currentRouteLocation.params))return createNavigateResult({status:NavigateStatus.duplicated,message:"导航到相同的路由,被系统阻止!"});if(to.matched.at(-1)===this._currentRouteLocation.matched.at(-1)&&to.path===this._currentRouteLocation.path&&vitarx.isDeepEqual(to.query,this._currentRouteLocation.query)&&to.hash!==this._currentRouteLocation.hash)return this.updateHash(to.hash),createNavigateResult({status:NavigateStatus.success,message:"仅hash变化,导航成功!"});const matched=to.matched.at(-1);if(matched!=null&&matched.redirect){let redirectTarget;if(typeof matched.redirect=="object"&&matched.redirect.index)redirectTarget=matched.redirect;else if(typeof matched.redirect=="string")redirectTarget={index:matched.redirect};else if(typeof matched.redirect=="function"){const redirectHandleResult=matched.redirect.call(this,to);vitarx.isObject(redirectHandleResult)&&(redirectTarget=redirectHandleResult)}if(redirectTarget!=null&&redirectTarget.index)return performNavigation(redirectTarget,!0)}try{const result=await this.onBeforeEach(to,from);return result===!1?createNavigateResult({status:NavigateStatus.aborted,message:`导航到${to.index}目标时被前置守卫钩子阻止!`}):isCurrentTask()?typeof result=="object"&&result.index!==_target.index?(result.isReplace??(result.isReplace=!1),performNavigation(result,!0)):typeof result=="string"&&result!==_target.index?performNavigation({index:result,isReplace:!1},!0):!to.matched.length&&!this.missing?createNavigateResult({status:NavigateStatus.not_matched,message:`未匹配到任何路由规则,被系统阻止!请检测目标索引(${to.index})是否已注册路由。`}):("isReplace"in _target&&_target.isReplace?(this._pendingReplace=to,this.replaceHistory(to)):(this._pendingPush=to,this.pushHistory(to)),createNavigateResult(!to.matched.length&&this.missing?{status:NavigateStatus.not_matched,message:`${to.fullPath}未匹配到任何路由规则,被系统允许访问,因为系统定义了missing视图。`}:void 0)):createNavigateResult({status:NavigateStatus.cancelled,message:"已被新的导航请求替代,取消此次导航!"})}catch(error){return console.error("[Vitarx.Router.navigate][ERROR]:导航时捕获到了异常",error),createNavigateResult({status:NavigateStatus.exception,message:"导航时捕获到了异常",error})}};return performNavigation(target,!1)}updateQuery(query){vitarx.isDeepEqual(this._currentRouteLocation.query,query)||(this._currentRouteLocation.query=query,this._currentRouteLocation.fullPath=this.makeFullPath(this._currentRouteLocation.path,query,this._currentRouteLocation.hash,this._currentRouteLocation.suffix))}updateHash(hash){if(typeof hash!="string")throw new TypeError(`[Vitarx.Router.updateHash][WARN]:hash值只能是字符串类型,给定${hash}`);const newHash=formatHash(hash);newHash!==this._currentRouteLocation.hash&&(this._currentRouteLocation.hash=newHash,this._currentRouteLocation.fullPath=this.makeFullPath(this._currentRouteLocation.path,this._currentRouteLocation.query,newHash,this._currentRouteLocation.suffix))}createViewProps(route,name){var _a;const injectProps=(_a=route.injectProps)==null?void 0:_a[name];let props;return injectProps===!0?props=JSON.parse(JSON.stringify(this._currentRouteLocation.params)):injectProps===!1?props={}:typeof injectProps=="function"?props=injectProps(this.currentRouteLocation):vitarx.isRecordObject(injectProps)?props=injectProps:props={},props}createRouteViewElement(route,name){var _a;const widget=(_a=route.widget)==null?void 0:_a[name];if(!widget)return;const props=this.createViewProps(route,name);return props.key=route.path,vitarx.createElement(widget,props)}_completeViewRender(){}completeNavigation(savedPosition){const newData=this.pendingReplaceData||this.pendingPushData;if(!newData)throw new Error("[Vitarx.Router.completeNavigation][ERROR]:没有处于等待状态的导航请求。");const from=cloneRouteLocation(this.currentRouteLocation);this._completeViewRender=()=>{this.onScrollBehavior(this.currentRouteLocation,from,savedPosition).then(),this.onAfterEach(this.currentRouteLocation,from)},this.updateRouteLocation(newData),this._pendingReplace=null,this._pendingPush=null}makeFullPath(path,query,hash,suffix){return hash&&!hash.startsWith("#")&&(hash=`#${hash}`),typeof query=="object"&&(query=objectToQueryString(query)),path=addPathSuffix(path,suffix||this._options.defaultSuffix),this.mode==="hash"?formatPath(`${this.basePath}/${query}#${path}${hash}`):formatPath(`${this.basePath}${path}${query}${hash}`)}onBeforeEach(to,from){var _a;const matched=to.matched.at(-1);return matched&&"beforeEnter"in matched&&typeof matched.beforeEnter=="function"?matched.beforeEnter.call(this,to,from):(_a=this._options.beforeEach)==null?void 0:_a.call(this,to,from)}onAfterEach(to,from){var _a;const matched=to.matched.at(-1);if(matched)return"afterEnter"in matched&&typeof matched.afterEnter=="function"?matched.afterEnter.call(this,to,from):(_a=this._options.afterEach)==null?void 0:_a.call(this,to,from)}updateRouteLocation(newLocation){patchUpdate(this._currentRouteLocation,newLocation)}async onScrollBehavior(to,from,savedPosition){try{if(this._scrollBehaviorHandler){const scrollTarget=await this._scrollBehaviorHandler(to,from,savedPosition);scrollTarget&&this.scrollTo(scrollTarget)}else!savedPosition&&!to.hash?this.scrollTo({left:0,top:0}):this.scrollTo(savedPosition??{el:to.hash})}catch(e){console.error("[Vitarx.Router.onScrollBehavior]['ERROR']:处理滚动行为时捕获到了异常",e)}}removeRoute(index){const removed=super.removeRoute(index);if(removed){const index2=this._currentRouteLocation.matched.indexOf(removed);index2!==-1&&this._currentRouteLocation.matched.splice(index2,1)}return removed}install(app){app.provide("router",this)}};__publicField(_RouterCore,"_instance");let RouterCore=_RouterCore;class RouterHistory extends RouterCore{constructor(options){["path","hash"].includes(options.mode)||(options.mode="hash"),super(options),options.mode==="hash"&&this.ensureHash()}updateHash(hash){if(super.updateHash(hash),this.saveCurrentScrollPosition(),this.webHistory.pushState(this.createState(this.currentRouteLocation),"",this.currentRouteLocation.fullPath),!hash.trim())window.scrollTo(0,0);else{const anchorId=hash.startsWith("#")?hash.slice(1):hash;try{const element=window.document.getElementById(anchorId);element&&element.scrollIntoView({behavior:this.options.anchorsScrollBehavior})}catch(e){console.error(`滚动到目标锚点${hash}失败`,e)}}}updateQuery(query){super.updateQuery(query),this.webHistory.pushState(this.createState(this.currentRouteLocation),"",this.currentRouteLocation.fullPath)}get currentRouteTarget(){return urlToRouteTarget(window.location,this.mode,this.basePath)}get webHistory(){return window.history}go(delta){this.webHistory.go(delta)}initializeRouter(){window.addEventListener("popstate",this.onPopState.bind(this)),this.replace(this.currentRouteTarget).then(res=>{res.status!==NavigateStatus.success&&console.warn(`[VitarxRouter.initializeRouter]:路由初始化匹配失败,${res.message}`)})}pushHistory(data){this.saveCurrentScrollPosition(),this.webHistory.pushState(this.createState(data),"",data.fullPath),this.completeNavigation()}replaceHistory(data){var _a;const scrollPosition=(_a=this.webHistory.state)==null?void 0:_a.scrollPosition;this.webHistory.replaceState(this.createState(data),"",data.fullPath),this.completeNavigation(scrollPosition)}saveCurrentScrollPosition(){const scrollPosition={left:window.scrollX,top:window.scrollY,behavior:this.scrollBehavior};this.webHistory.replaceState({...this.webHistory.state,scrollPosition},"",window.location.href)}createState(data,hash,query){const{matched,...state}=data;return typeof hash=="string"&&(state.hash=hash),typeof query=="object"&&(state.query=query),JSON.parse(JSON.stringify(state))}onPopState(event){var _a;let newTarget;(_a=event.state)!=null&&_a.index?newTarget={index:event.state.index,hash:event.state.hash,query:event.state.query}:newTarget=this.currentRouteTarget,this.replace(newTarget).then(res=>{if(!res.redirectFrom&&this.mode==="hash"&&res.status!==NavigateStatus.success)if(res.status===NavigateStatus.not_matched){if(res.to.index.startsWith("/")){const anchorId=res.to.index.slice(1),element=window.document.getElementById(anchorId);element&&element.scrollIntoView({behavior:this.scrollBehavior}),this.updateHash(`#${anchorId}`)}}else res.status===NavigateStatus.duplicated&&this.webHistory.replaceState(this.createState(this.currentRouteLocation),"",this.currentRouteLocation.fullPath)})}ensureHash(){const{pathname,search,hash}=window.location;if(!hash){const path=`${this.basePath}${search}#${pathname}`;window.location.replace(path)}}}class RouterMemory extends RouterCore{constructor(options){super(options);__publicField(this,"_history",[]);__publicField(this,"_pendingGo",null);__publicField(this,"_currentIndex",0);options.mode="memory"}get currentIndex(){return this._currentIndex}go(delta){if(!delta)return;const currentIndex=this.currentIndex,targetIndex=Math.max(0,Math.min(this._history.length-1,currentIndex+delta));if(targetIndex===currentIndex)return;const target=this._history[targetIndex];this._pendingGo=targetIndex,this.navigate(target).then(res=>{res.status!==NavigateStatus.success&&(this._pendingGo=null)})}initializeRouter(){this._history.push(this.currentRouteLocation)}pushHistory(data){this._updateHistory(data,!1)}replaceHistory(data){this._updateHistory(data,!0)}_updateHistory(data,isReplace){let newIndex;if(this._pendingGo!==null)this._history[this._pendingGo]=data,newIndex=this._pendingGo;else if(isReplace)this._history[this.currentIndex]=data,newIndex=this.currentIndex;else{const nextIndex=this.currentIndex+1;nextIndex<this._history.length?(this._history[nextIndex]=data,this._history.length=nextIndex+1,newIndex=nextIndex):(this._history.push(data),newIndex=this._history.length-1)}this._currentIndex=newIndex,this.completeNavigation(),this._pendingGo=null}}function defineRoutes(...routes){return routes}function defineRoute(route){return route}function createRouter(options){let router;return typeof window>"u"&&options.mode!=="memory"?(console.warn("当前环境非浏览器端,强制使用内存模式路由"),options.mode="memory",new RouterMemory(options).initialize()):(options.mode==="memory"?router=new RouterMemory(options):router=new RouterHistory(options),router.initialize())}function useRouter(){return RouterCore.instance}function useRoute(){return RouterCore.instance.currentRouteLocation}const INDEX_SYMBOL=Symbol("RouterViewCounter");class RouterView extends vitarx.Widget{constructor(props){super(props);__publicField(this,"_$index");__publicField(this,"_$currentRoute");__publicField(this,"_$currentElement",vitarx.shallowRef());const parentIndex=vitarx.inject(INDEX_SYMBOL,-1);this._$index=parentIndex+1,vitarx.provide(INDEX_SYMBOL,this._$index),this._$currentRoute=this.matchedRoute,this._$currentElement.value=RouterCore.routeViewElement(this._$currentRoute,this.name,this._$index);const router=useRouter();let paramStr=JSON.stringify(this.location.params);vitarx.watch(this.location.matched,(_c,o)=>{const newRoute=o[this.index];newRoute!==this._$currentRoute&&(this._$currentRoute=newRoute,this._$currentElement.value=RouterCore.routeViewElement(newRoute,this.name,this._$index))}),vitarx.watch(this.location.params,()=>{if(!this._$currentRoute)return;const newParams=JSON.stringify(this.location.params);if(newParams!==paramStr){paramStr=newParams;const newProps=router.createViewProps(this._$currentRoute,this.name),oldProps=vitarx.toRaw(this._$currentElement.value.props),changes=diffUpdateProps(oldProps,newProps);changes.length>0&&vitarx.Observer.notify(this._$currentElement.value.props,changes)}})}get index(){return this._$index}get isLastView(){return this.index===this.location.matched.length-1&&this.name==="default"}get name(){return this.props.name||"default"}get matchedRoute(){return this.location.matched[this.index]}get currentElement(){return this._$currentElement.value}get currentWidget(){var _a;return(_a=this._$currentElement.value)==null?void 0:_a.type}get location(){return RouterCore.instance.currentRouteLocation}onMounted(){this.completeViewRender()}onUpdated(){this.completeViewRender()}build(){return this.currentElement||vitarx.createElement(vitarx.Fragment)}completeViewRender(){this.isLastView&&RouterCore.instance._completeViewRender()}}class RouterLink extends vitarx.Widget{constructor(props){super(props);__publicField(this,"target");__publicField(this,"location");__publicField(this,"active");__publicField(this,"htmlProps");this.target=new vitarx.Computed(()=>{if(!this.props.to)return;const to=vitarx.isString(props.to)?{index:decodeURIComponent(props.to)}:props.to;if(RouterLink.isHttpOrHttpsUrl(to.index)||to.index.startsWith("#"))return to.index;if(to.index.includes("#")){const[index,hash]=to.index.split("#",2);to.index=index,to.hash=`#${hash}`}return to}),this.location=new vitarx.Computed(()=>{if(!this.target.value||typeof this.target.value=="string")return;const location=RouterCore.instance.createRouteLocation(this.target.value);return location.matched.length||console.warn(`[Vitarx.RouterLink][WARN]:索引:${this.target.value.index},未匹配到任何有效的路由线路,请检查to属性是否配置正确!`),location}),props.active!==void 0&&props.active!=="none"&&(this.active=new vitarx.Computed(()=>!this.location.value||typeof this.target.value=="string"||!this.target.value?!1:this.target.value.index.startsWith("/")?props.active==="obscure"?this.location.value.path==="/"?RouterCore.instance.currentRouteLocation.path==="/":RouterCore.instance.currentRouteLocation.fullPath.startsWith(this.location.value.path):this.location.value.path===RouterCore.instance.currentRouteLocation.path:!!RouterCore.instance.currentRouteLocation.matched.find(route=>route.name===this.target.value.index))),this.htmlProps=new vitarx.Computed(()=>{var _a;const props2={href:this.href,onClick:e=>this.navigate(e),children:this.children??((_a=this.location.value)==null?void 0:_a.index),draggable:this.props.draggable??!1,"v-bind":[this.props,["to","children","href","disabled","active","callback","onClick","onclick","aria-current"]]};return this.isActive&&(props2["aria-current"]="page"),this.isDisabled&&(props2.disabled=!0),props2})}static isHttpOrHttpsUrl(url){return/^(https?):\/\/[^\s\/$.?#].\S*$/i.test(url)}get isActive(){var _a;return((_a=this.active)==null?void 0:_a.value)&&!this.isDisabled}get isDisabled(){return this.props.disabled??!1}get href(){var _a;return typeof this.target.value=="string"?this.target.value:((_a=this.location.value)==null?void 0:_a.fullPath)||"javascript:void(0)"}navigate(e){typeof this.target.value!="string"&&(e.preventDefault(),this.location.value&&!this.isDisabled&&RouterCore.instance.navigate(this.location.value).then(res=>{var _a;res.status!==NavigateStatus.success&&console.warn(`[Vitarx.RouterLink][WARN]:导航到索引:${(_a=this.target.value)==null?void 0:_a.index}失败,${res.message}`),this.props.callback&&this.props.callback(res)}))}build(){return vitarx.createElement("a",this.htmlProps.value)}}exports2.HistoryRouter=RouterHistory,exports2.MemoryRouter=RouterMemory,exports2.NavigateStatus=NavigateStatus,exports2.Router=RouterCore,exports2.RouterLink=RouterLink,exports2.RouterView=RouterView,exports2.createRouter=createRouter,exports2.defineRoute=defineRoute,exports2.defineRoutes=defineRoutes,exports2.useRoute=useRoute,exports2.useRouter=useRouter,Object.defineProperty(exports2,Symbol.toStringTag,{value:"Module"})}));
package/index.mjs DELETED
@@ -1 +0,0 @@
1
- export * from './dist/vitarx-router.es.js'