@vobs/router 1.3.7 → 1.4.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.
- package/dist/index.cjs +37 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +38 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/index.test.ts +126 -0
- package/src/index.ts +44 -1
package/dist/index.cjs
CHANGED
|
@@ -580,9 +580,12 @@ function RouterView(props = {}) {
|
|
|
580
580
|
onRetry: /* @__PURE__ */ __name(() => routeRetry(), "onRetry"),
|
|
581
581
|
fallback: /* @__PURE__ */ __name((error, retry) => {
|
|
582
582
|
router.devtools.reportError("render", error, router.currentRoute.value.fullPath);
|
|
583
|
-
return props.error
|
|
583
|
+
if (props.error !== void 0) return props.error(error, () => {
|
|
584
584
|
void retry();
|
|
585
|
-
})
|
|
585
|
+
});
|
|
586
|
+
return createRouteErrorFallback(error, () => {
|
|
587
|
+
void retry();
|
|
588
|
+
});
|
|
586
589
|
}, "fallback"),
|
|
587
590
|
children: /* @__PURE__ */ __name(() => {
|
|
588
591
|
const route = router.currentRoute.value;
|
|
@@ -621,6 +624,38 @@ function useRouter() {
|
|
|
621
624
|
return router;
|
|
622
625
|
}
|
|
623
626
|
__name(useRouter, "useRouter");
|
|
627
|
+
function createRouteErrorFallback(error, retry) {
|
|
628
|
+
const box = (0, import_vobs.createElement)("div");
|
|
629
|
+
box.setAttribute("class", "vobs-route-error");
|
|
630
|
+
box.style.padding = "48px 24px";
|
|
631
|
+
box.style.display = "flex";
|
|
632
|
+
box.style.flexDirection = "column";
|
|
633
|
+
box.style.alignItems = "center";
|
|
634
|
+
box.style.gap = "12px";
|
|
635
|
+
box.style.fontFamily = "system-ui, -apple-system, sans-serif";
|
|
636
|
+
box.style.color = "#5a5f6a";
|
|
637
|
+
const title = (0, import_vobs.createElement)("div");
|
|
638
|
+
title.textContent = "\u9875\u9762\u6E32\u67D3\u51FA\u9519";
|
|
639
|
+
title.style.fontSize = "16px";
|
|
640
|
+
title.style.fontWeight = "600";
|
|
641
|
+
title.style.color = "#1c1c1e";
|
|
642
|
+
const message = (0, import_vobs.createElement)("code");
|
|
643
|
+
message.textContent = error.message;
|
|
644
|
+
message.style.fontSize = "12px";
|
|
645
|
+
message.style.maxWidth = "520px";
|
|
646
|
+
message.style.wordBreak = "break-word";
|
|
647
|
+
message.style.opacity = "0.75";
|
|
648
|
+
const button = (0, import_vobs.createElement)("button");
|
|
649
|
+
button.setAttribute("type", "button");
|
|
650
|
+
button.textContent = "\u91CD\u8BD5";
|
|
651
|
+
button.style.padding = "6px 20px";
|
|
652
|
+
button.style.fontSize = "13px";
|
|
653
|
+
button.style.cursor = "pointer";
|
|
654
|
+
button.addEventListener("click", retry);
|
|
655
|
+
box.append(title, message, button);
|
|
656
|
+
return box;
|
|
657
|
+
}
|
|
658
|
+
__name(createRouteErrorFallback, "createRouteErrorFallback");
|
|
624
659
|
function useRoute() {
|
|
625
660
|
return useRouter().currentRoute;
|
|
626
661
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/debug.ts"],"sourcesContent":["import { state, type Signal } from '@vobs/reactivity'\nimport {\n createComponent,\n createFragment,\n createInjectionKey,\n inject,\n insertBoundary,\n type InjectionKey,\n type VobsNode,\n type VobsPlugin\n} from '@vobs/vobs'\nimport {\n createRouterDebugId,\n emitRouterDebug\n} from './debug'\nimport {\n getRuntimeDebugContext,\n runWithRuntimeDebugContext,\n type RuntimeDebugContext\n} from '@vobs/runtime'\n\nexport { createRouterDebugId, emitRouterDebug, subscribeRouterDebug } from './debug'\nexport type { RouterDebugEvent, RouterDebugEventType } from './debug'\n\nexport type RouteParams = Readonly<Record<string, string>>\nexport type RouteQueryValue = string | readonly string[]\nexport type RouteQuery = Readonly<Record<string, RouteQueryValue>>\nexport type RouteMeta = Readonly<Record<string, unknown>>\n\nexport interface RouteLocation {\n readonly path: string\n readonly fullPath: string\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly hash: string\n readonly name: string | undefined\n readonly meta: RouteMeta\n readonly record: RouteRecord | null\n readonly matched: readonly RouteRecord[]\n readonly state?: unknown\n}\n\nexport interface RouteComponentProps {\n readonly route: RouteLocation\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly children?: VobsNode\n}\n\nexport type RouteComponent = (props: RouteComponentProps) => VobsNode\nexport type RouteComponentModule = RouteComponent | { default: RouteComponent }\nexport type RouteComponentLoader = () => PromiseLike<RouteComponentModule>\n\nexport interface LazyRouteComponent {\n readonly kind: 'vobs-lazy-route'\n readonly load: RouteComponentLoader\n}\n\nexport type RouteComponentDefinition = RouteComponent | LazyRouteComponent\n\nexport interface RouteLoaderContext {\n readonly route: RouteLocation\n readonly navigationId?: number\n readonly dataRequestId?: number\n}\n\nexport type RouteLoader = (context: RouteLoaderContext) => unknown | PromiseLike<unknown>\n\nexport interface RouteRecord {\n readonly path?: string\n readonly component?: RouteComponentDefinition\n readonly source?: string\n readonly name?: string\n readonly meta?: Record<string, unknown>\n readonly loader?: RouteLoader\n readonly action?: RouteLoader\n readonly children?: readonly RouteRecord[]\n}\n\nexport type RouteQueryInput = Record<string, unknown> | URLSearchParams\n\nexport interface RouteLocationRaw {\n readonly path?: string\n readonly name?: string\n readonly params?: Record<string, unknown>\n readonly query?: RouteQueryInput\n readonly hash?: string\n readonly state?: unknown\n}\n\nexport type RouteTarget = string | RouteLocationRaw\n\nexport type NavigationGuardResult = void | boolean | RouteTarget\nexport type NavigationGuard = (\n to: RouteLocation,\n from: RouteLocation\n) => NavigationGuardResult | PromiseLike<NavigationGuardResult>\n\nexport class NavigationCancelledError extends Error {\n readonly code = 'NAVIGATION_CANCELLED'\n\n constructor() {\n super('Vobs Router: 导航已被更新的导航取消')\n this.name = 'NavigationCancelledError'\n }\n}\n\nexport class NavigationRedirectError extends Error {\n readonly code = 'NAVIGATION_REDIRECT_LIMIT'\n\n constructor() {\n super('Vobs Router: 导航重定向超过最大次数')\n this.name = 'NavigationRedirectError'\n }\n}\n\nexport interface RouterHistory {\n readonly location: string\n /** 当前 history 条目携带的导航 state(push/replace 时写入,popstate/初始启动时回读)。 */\n readonly state?: unknown\n push(path: string, state?: unknown): void\n replace(path: string, state?: unknown): void\n back(): void\n listen(listener: (path: string, state: unknown) => void): () => void\n}\n\nexport interface RouterOptions {\n readonly routes: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport interface RouterViewState {\n readonly status: 'ready' | 'loading' | 'error' | 'not-found'\n readonly component?: RouteComponent\n readonly layouts?: readonly RouteComponent[]\n readonly error?: Error\n readonly retry: () => void\n}\n\nexport interface RouteDebugNode {\n readonly id: string\n readonly path: string\n readonly name?: string\n readonly component: string\n readonly lazy: boolean\n readonly loader: boolean\n readonly action: boolean\n readonly status: 'ready' | 'loading' | 'error'\n readonly meta: RouteMeta\n readonly source?: string\n readonly children: readonly RouteDebugNode[]\n}\n\nexport interface RouteErrorTrace {\n readonly id: number\n readonly phase: 'navigation' | 'render' | 'lazy' | 'loader' | 'action' | 'fetcher'\n readonly route: string\n readonly message: string\n readonly stack?: string\n readonly timestamp: number\n readonly requestId?: number\n readonly navigationId?: number\n}\n\nexport interface NavigationTrace {\n readonly id: number\n readonly from: string\n readonly to: string\n readonly status: 'success' | 'redirected' | 'cancelled' | 'error'\n readonly source: 'push' | 'replace' | 'history'\n readonly startedAt: number\n readonly endedAt: number\n readonly duration: number\n readonly redirect?: string\n readonly error?: string\n}\n\nexport interface NavigationState {\n readonly status: 'idle' | 'loading' | 'error'\n readonly from: string\n readonly to: string\n readonly traceId?: number\n readonly error?: string\n}\n\nexport interface RouterPerformanceMetrics {\n readonly navigationCount: number\n readonly averageNavigationDuration: number\n readonly slowNavigationCount: number\n}\n\nexport type RouterDataRequestKind = 'loader' | 'action' | 'fetcher'\n\nexport interface RouterDataRequestTrace {\n readonly id: number\n readonly kind: RouterDataRequestKind\n readonly key: string\n readonly route?: string\n readonly status: 'loading' | 'success' | 'error' | 'cancelled'\n readonly startedAt: number\n readonly endedAt?: number\n readonly duration?: number\n readonly result?: unknown\n readonly error?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport interface RouterDataRequestOptions {\n readonly route?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport type RouterDevToolsEvent = 'navigation:start' | 'navigation:end' | 'route:update' | 'data-request' | 'error'\n\nexport interface RouterDevToolsAPI {\n getRouteTree(): readonly RouteDebugNode[]\n getCurrentRoute(): RouteLocation\n getNavigationState(): NavigationState\n getNavigationHistory(): readonly NavigationTrace[]\n getPerformanceMetrics(): RouterPerformanceMetrics\n getDataRequests(): readonly RouterDataRequestTrace[]\n getErrors(): readonly RouteErrorTrace[]\n trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: () => T | PromiseLike<T>,\n options?: RouterDataRequestOptions | string\n ): Promise<T>\n runAction<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n runFetcher<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n reportError(phase: RouteErrorTrace['phase'], error: unknown, route?: string, context?: { readonly requestId?: number; readonly navigationId?: number }): void\n revalidate(route?: string): Promise<void>\n subscribe(event: RouterDevToolsEvent, callback: (payload: unknown) => void): () => void\n}\n\nexport interface Router {\n readonly currentRoute: Signal<RouteLocation>\n readonly history: RouterHistory\n resolve(to: RouteTarget): RouteLocation\n push(to: RouteTarget): Promise<RouteLocation | false>\n replace(to: RouteTarget): Promise<RouteLocation | false>\n back(): void\n beforeEach(guard: NavigationGuard): () => void\n getViewState(route: RouteLocation): RouterViewState\n readonly devtools: RouterDevToolsAPI\n destroy(): void\n}\n\nexport interface RouterViewProps {\n readonly router?: Router\n /** 加载占位:JSX 属性经编译器编译为惰性 getter,手写对象字面量可传节点或工厂。 */\n readonly loading?: VobsNode | (() => VobsNode | null | undefined)\n readonly notFound?: (route: RouteLocation) => VobsNode | null | undefined\n readonly error?: (error: Error, retry: () => void) => VobsNode | null | undefined\n}\n\nexport interface RouterPluginOptions {\n readonly router?: Router\n readonly routes?: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport const ROUTER_KEY: InjectionKey<Router> = createInjectionKey<Router>('vobs.router')\n\nexport function lazy(loader: RouteComponentLoader): LazyRouteComponent {\n return {\n kind: 'vobs-lazy-route',\n load: loader\n }\n}\n\nexport function createMemoryHistory(initial = '/'): RouterHistory {\n let entries = [{ path: normalizeHistoryPath(initial), state: undefined as unknown }]\n let index = 0\n const listeners = new Set<(path: string, state: unknown) => void>()\n\n return {\n get location(): string {\n return entries[index]!.path\n },\n\n get state(): unknown {\n return entries[index]!.state\n },\n\n push(path: string, state?: unknown): void {\n const next = normalizeHistoryPath(path)\n entries = entries.slice(0, index + 1)\n entries.push({ path: next, state })\n index++\n },\n\n replace(path: string, state?: unknown): void {\n entries[index] = { path: normalizeHistoryPath(path), state }\n },\n\n back(): void {\n if (index === 0) return\n index--\n notifyListeners(listeners, entries[index]!.path, entries[index]!.state)\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n }\n}\n\nexport function createBrowserHistory(base = ''): RouterHistory {\n if (typeof window === 'undefined') {\n throw new Error('Vobs Router: createBrowserHistory 需要浏览器环境')\n }\n\n const normalizedBase = normalizeBase(base)\n const listeners = new Set<(path: string, state: unknown) => void>()\n const onPopState = (event: PopStateEvent): void => {\n notifyListeners(listeners, readBrowserLocation(normalizedBase), event.state)\n }\n\n return {\n get location(): string {\n return readBrowserLocation(normalizedBase)\n },\n\n get state(): unknown {\n return window.history.state\n },\n\n push(path: string, state?: unknown): void {\n window.history.pushState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n replace(path: string, state?: unknown): void {\n window.history.replaceState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n back(): void {\n window.history.back()\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n if (listeners.size === 0) window.addEventListener('popstate', onPopState)\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n if (listeners.size === 0) window.removeEventListener('popstate', onPopState)\n }\n }\n }\n}\n\nexport function createRouter(options: RouterOptions): Router {\n const matchers = normalizeRoutes(options.routes)\n const history = options.history ?? defaultHistory()\n const routerDebugId = createRouterDebugId()\n matchers.sort(compareMatchers)\n const currentRoute = state<RouteLocation>(resolvePath(history.location))\n const lazyStates = new Map<RouteRecord, LazyState>()\n const guards: NavigationGuard[] = []\n const navigationHistory: NavigationTrace[] = []\n const dataRequests: RouterDataRequestTrace[] = []\n const errors: RouteErrorTrace[] = []\n const dataLoaders = new Map<string, { kind: RouterDataRequestKind; route: string; task: () => unknown | PromiseLike<unknown> }>()\n const dataRequestContexts = new Map<number, RuntimeDebugContext>()\n const routerListeners = new Map<RouterDevToolsEvent, Set<(payload: unknown) => void>>()\n let navigationState: NavigationState = { status: 'idle', from: currentRoute.value.fullPath, to: currentRoute.value.fullPath }\n let navigationCount = 0\n let totalNavigationDuration = 0\n let slowNavigationCount = 0\n let nextDataRequestId = 1\n let nextErrorId = 1\n let navigationId = 0\n let destroyed = false\n const viewRevision = state(0)\n\n function resolve(to: RouteTarget): RouteLocation {\n ensureActive()\n const target = typeof to === 'string' ? parseTargetString(to) : normalizeTarget(to, matchers)\n return resolvePath(buildTargetPath(target.path, target.query, target.hash), target.state)\n }\n\n function resolvePath(rawPath: string, state?: unknown): RouteLocation {\n const parsed = parseTargetString(rawPath)\n const matched = matchers.find(matcher => matcher.regex.exec(parsed.path))\n const params = matched ? extractParams(matched, parsed.path) : {}\n const record = matched?.record ?? null\n const query = parsed.query\n const hash = parsed.hash\n return {\n path: parsed.path,\n fullPath: buildTargetPath(parsed.path, query, hash),\n params,\n query,\n hash,\n name: record?.name,\n meta: matched?.meta ?? {},\n record,\n matched: matched?.chain ?? EMPTY_MATCHED,\n state\n }\n }\n\n async function navigate(\n to: RouteTarget,\n replaceHistory: boolean,\n fromHistory: boolean,\n historyState?: unknown\n ): Promise<RouteLocation | false> {\n ensureActive()\n const id = ++navigationId\n const from = currentRoute.value\n let target = resolve(to)\n // popstate 回读的 state 保存在 history 条目上,不在目标描述里,这里回填。\n if (fromHistory && historyState !== undefined) target = { ...target, state: historyState }\n const source: NavigationTrace['source'] = fromHistory ? 'history' : replaceHistory ? 'replace' : 'push'\n const startedAt = now()\n const initialTarget = target.fullPath\n let terminalRecorded = false\n navigationState = { status: 'loading', from: from.fullPath, to: target.fullPath, traceId: id }\n emitRouter('navigation:start', navigationState)\n if (target.fullPath === from.fullPath && !fromHistory) {\n navigationState = { status: 'idle', from: from.fullPath, to: target.fullPath }\n return from\n }\n\n try {\n for (let redirectCount = 0; ; redirectCount++) {\n ensureNavigationIsCurrent(id)\n let redirect: RouteTarget | undefined\n for (const guard of [...guards]) {\n let result: NavigationGuardResult\n try {\n result = await guard(target, from)\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) throw reason\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw reason\n }\n ensureNavigationIsCurrent(id)\n if (result === false) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n return false\n }\n if (typeof result === 'string' || isRouteLocationRaw(result)) {\n redirect = result\n break\n }\n }\n\n for (const record of target.matched) {\n if (!record.loader) continue\n // 上一 loader 期间被新导航抢占时立即取消,跳过剩余 loader。\n ensureNavigationIsCurrent(id)\n await trackDataRequest(\n 'loader',\n `${target.fullPath}#${record.path ?? record.name ?? 'route'}`,\n context => record.loader!({ route: target, navigationId: id, dataRequestId: context.dataRequestId }),\n { route: target.fullPath, navigationId: id, trigger: 'navigation' }\n )\n }\n\n // loader 完成后、提交前必须重新校验:飞行期间被抢占的导航不允许覆盖 currentRoute 与 history。\n ensureNavigationIsCurrent(id)\n\n if (redirect !== undefined) {\n if (redirectCount >= 10) {\n const error = new NavigationRedirectError()\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw error\n }\n const redirected = resolve(redirect)\n if (redirected.fullPath === target.fullPath) return false\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'redirected', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: redirected.fullPath })\n target = redirected\n continue\n }\n\n if (target.fullPath === from.fullPath) return from\n if (!fromHistory) {\n if (replaceHistory) history.replace(target.fullPath, target.state)\n else history.push(target.fullPath, target.state)\n }\n currentRoute.value = target\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'success', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: target.fullPath !== initialTarget ? target.fullPath : undefined })\n terminalRecorded = true\n return target\n }\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n } else if (!terminalRecorded) {\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n }\n throw reason\n }\n }\n\n function now(): number {\n return typeof performance === 'undefined' ? Date.now() : performance.now()\n }\n\n function emitRouter(event: RouterDevToolsEvent, payload: unknown): void {\n for (const callback of routerListeners.get(event) ?? []) {\n try { callback(payload) } catch { /* diagnostics must not affect navigation */ }\n }\n emitRouterDebug(routerDebugId, event, payload, getRuntimeDebugContext() ?? undefined)\n }\n\n function recordNavigation(trace: NavigationTrace): void {\n navigationHistory.push(Object.freeze(trace))\n if (navigationHistory.length > 100) navigationHistory.shift()\n navigationCount++\n totalNavigationDuration += trace.duration\n if (trace.duration >= 16) slowNavigationCount++\n if (trace.id === navigationId) {\n navigationState = trace.status === 'error'\n ? { status: 'error', from: trace.from, to: trace.to, traceId: trace.id, error: trace.error }\n : { status: 'idle', from: trace.from, to: trace.to, traceId: trace.id }\n }\n emitRouter('navigation:end', trace)\n emitRouter('route:update', currentRoute.value)\n }\n\n async function trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: ((context: { readonly dataRequestId: number }) => T | PromiseLike<T>) | (() => T | PromiseLike<T>),\n optionsOrRoute: RouterDataRequestOptions | string = {}\n ): Promise<T> {\n ensureActive()\n const options = typeof optionsOrRoute === 'string' ? { route: optionsOrRoute } : optionsOrRoute\n const id = nextDataRequestId++\n const startedAt = now()\n const context = getRuntimeDebugContext()\n const route = options.route ?? currentRoute.value.fullPath\n const requestContext: RuntimeDebugContext = {\n ...context,\n environment: options.environment ?? context?.environment,\n route,\n navigationId: options.navigationId ?? context?.navigationId,\n dataRequestId: id,\n source: kind\n }\n const loading: RouterDataRequestTrace = {\n id,\n kind,\n key,\n route,\n status: 'loading',\n startedAt,\n navigationId: requestContext.navigationId,\n trigger: options.trigger,\n environment: requestContext.environment\n }\n dataRequests.push(loading)\n if (dataRequests.length > 100) dataRequests.shift()\n dataRequestContexts.set(id, requestContext)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', loading)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'start', trace: loading }, requestContext)\n dataLoaders.set(key, { kind, route, task: task as () => unknown | PromiseLike<unknown> })\n try {\n const result = await runWithRuntimeDebugContext(requestContext, () => (task as (context: { readonly dataRequestId: number }) => T | PromiseLike<T>)({ dataRequestId: id }))\n const endedAt = now()\n replaceDataRequest(id, { ...loading, status: 'success', endedAt, duration: endedAt - startedAt, result })\n return result\n } catch (reason) {\n const endedAt = now()\n const error = toError(reason)\n const status = isAbortError(reason) ? 'cancelled' : 'error'\n if (status === 'error') reportError(kind, error, route, { requestId: id, navigationId: requestContext.navigationId })\n replaceDataRequest(id, { ...loading, status, endedAt, duration: endedAt - startedAt, error: status === 'error' ? error.message : undefined })\n throw reason\n }\n }\n\n function replaceDataRequest(id: number, trace: RouterDataRequestTrace): void {\n const index = dataRequests.findIndex(item => item.id === id)\n if (index >= 0) dataRequests[index] = Object.freeze(trace)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', trace)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'end', trace }, dataRequestContexts.get(id))\n dataRequestContexts.delete(id)\n }\n\n function reportError(\n phase: RouteErrorTrace['phase'],\n reason: unknown,\n route = currentRoute.value.fullPath,\n context: { readonly requestId?: number; readonly navigationId?: number } = {}\n ): void {\n const error = toError(reason)\n errors.push(Object.freeze({\n id: nextErrorId++,\n phase,\n route,\n message: error.message,\n stack: error.stack,\n timestamp: now(),\n requestId: context.requestId,\n navigationId: context.navigationId\n }))\n if (errors.length > 100) errors.shift()\n emitRouter('error', errors[errors.length - 1]!)\n emitRouter('route:update', currentRoute.value)\n }\n\n function routeTree(): readonly RouteDebugNode[] {\n const statuses = new Map<string, LazyState['status']>()\n for (const matcher of matchers) {\n for (const record of matcher.chain) {\n if (record.component && isLazyRouteComponent(record.component)) {\n const debugId = routeDebugIds.get(record)\n if (debugId) statuses.set(debugId, lazyStates.get(record)?.status ?? 'loading')\n }\n }\n }\n return buildRouteDebugTree(options.routes, statuses)\n }\n\n function handleHistoryNavigation(path: string, state: unknown): void {\n void navigate(path, false, true, state).then(result => {\n if (destroyed) return\n if (result === false) {\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n } else if (result.fullPath !== normalizeHistoryPath(path)) {\n history.replace(result.fullPath, result.state)\n }\n }).catch(error => {\n if (!(error instanceof NavigationCancelledError) && !destroyed) {\n const current = currentRoute.value.fullPath\n const failed = toError(error)\n reportError('navigation', failed, normalizeHistoryPath(path))\n navigationState = { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message }\n emitRouter('navigation:end', { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message })\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n }\n })\n }\n\n const stopHistory = history.listen(handleHistoryNavigation)\n\n const router: Router = {\n currentRoute,\n history,\n\n resolve,\n\n push(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, false, false)\n },\n\n replace(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, true, false)\n },\n\n back(): void {\n ensureActive()\n history.back()\n },\n\n beforeEach(guard: NavigationGuard): () => void {\n ensureActive()\n guards.push(guard)\n return () => {\n const index = guards.indexOf(guard)\n if (index >= 0) guards.splice(index, 1)\n }\n },\n\n getViewState(route: RouteLocation): RouterViewState {\n viewRevision.value\n const records = route.matched.length > 0 ? route.matched : route.record ? [route.record] : []\n const entries = records\n .map(record => ({ record, definition: record.component }))\n .filter((entry): entry is { record: RouteRecord; definition: RouteComponentDefinition } =>\n isRouteComponentDefinition(entry.definition))\n if (!route.record || entries.length === 0) return { status: 'not-found', retry: () => undefined }\n\n const loaded: RouteComponent[] = []\n const lazyRecords: RouteRecord[] = []\n for (const entry of entries) {\n const { record, definition } = entry\n if (!isLazyRouteComponent(definition)) {\n loaded.push(definition)\n continue\n }\n lazyRecords.push(record)\n const lazyState = ensureLazyState(record, definition)\n if (lazyState.status === 'loading') return { status: 'loading', retry: () => retryLazyRoutes(lazyRecords) }\n if (lazyState.status === 'error') {\n return { status: 'error', error: lazyState.error, retry: () => retryLazyRoutes(lazyRecords) }\n }\n if (lazyState.component) loaded.push(lazyState.component)\n }\n\n const component = loaded[loaded.length - 1]\n if (!component) return { status: 'not-found', retry: () => undefined }\n return {\n status: 'ready',\n component,\n layouts: loaded.slice(0, -1),\n retry: () => retryLazyRoutes(lazyRecords)\n }\n },\n\n devtools: {\n getRouteTree: routeTree,\n getCurrentRoute: () => currentRoute.value,\n getNavigationState: () => navigationState,\n getNavigationHistory: () => [...navigationHistory],\n getPerformanceMetrics: () => ({\n navigationCount,\n averageNavigationDuration: navigationCount === 0 ? 0 : totalNavigationDuration / navigationCount,\n slowNavigationCount\n }),\n getDataRequests: () => [...dataRequests],\n getErrors: () => [...errors],\n trackDataRequest,\n runAction: (key, task) => trackDataRequest('action', key, task, { trigger: 'manual' }),\n runFetcher: (key, task) => trackDataRequest('fetcher', key, task, { trigger: 'manual' }),\n reportError,\n revalidate: async (route) => {\n await Promise.all([...dataLoaders.entries()]\n .filter(([, loader]) => loader.kind === 'loader' && (route === undefined || loader.route === route))\n .map(([key, loader]) => trackDataRequest(loader.kind, key, loader.task, { route: loader.route, trigger: 'revalidate' })))\n },\n subscribe(event, callback) {\n let listeners = routerListeners.get(event)\n if (!listeners) { listeners = new Set(); routerListeners.set(event, listeners) }\n listeners.add(callback)\n return () => listeners?.delete(callback)\n }\n },\n\n destroy(): void {\n if (destroyed) return\n destroyed = true\n navigationId++\n stopHistory()\n guards.length = 0\n routerListeners.clear()\n lazyStates.clear()\n errors.length = 0\n dataRequestContexts.clear()\n currentRoute.dispose()\n viewRevision.dispose()\n }\n }\n\n function ensureLazyState(record: RouteRecord, definition: LazyRouteComponent): LazyState {\n let lazyState = lazyStates.get(record)\n if (!lazyState) {\n lazyState = { status: 'loading' }\n lazyStates.set(record, lazyState)\n void loadRouteComponent(definition).then(component => {\n if (destroyed) return\n lazyState!.status = 'ready'\n lazyState!.component = component\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n }).catch(reason => {\n if (destroyed) return\n lazyState!.status = 'error'\n lazyState!.error = toError(reason)\n reportError('lazy', reason, currentRoute.value.fullPath)\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n })\n }\n return lazyState\n }\n\n function retryLazyRoutes(records: readonly RouteRecord[]): void {\n for (const record of records) lazyStates.delete(record)\n viewRevision.value++\n }\n\n function ensureActive(): void {\n if (destroyed) throw new Error('Vobs Router: 已销毁的 Router 不能继续使用')\n }\n\n function ensureNavigationIsCurrent(id: number): void {\n if (id !== navigationId) throw new NavigationCancelledError()\n }\n\n return router\n}\n\nexport function RouterView(props: RouterViewProps = {}): VobsNode {\n const router = props.router ?? inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: RouterView 找不到 Router,请安装 routerPlugin')\n\n return createFragment((parent, anchor) => {\n let routeRetry: () => void = () => undefined\n insertBoundary(parent, anchor, {\n resetKey: () => router.currentRoute.value.fullPath,\n onRetry: () => routeRetry(),\n fallback: (error, retry) => {\n router.devtools.reportError('render', error, router.currentRoute.value.fullPath)\n return props.error?.(error, () => { void retry() }) ?? null\n },\n children: () => {\n const route = router.currentRoute.value\n const view = router.getViewState(route)\n routeRetry = view.retry\n if (view.status === 'loading') {\n return (typeof props.loading === 'function' ? props.loading() : props.loading) ?? null\n }\n if (view.status === 'not-found') return props.notFound?.(route) ?? null\n if (view.status === 'error') {\n throw view.error ?? new Error('路由组件加载失败')\n }\n if (!view.component) return null\n let node = createComponent(view.component, {\n route,\n params: route.params,\n query: route.query\n })\n for (let index = (view.layouts?.length ?? 0) - 1; index >= 0; index--) {\n node = createComponent(view.layouts![index]!, {\n route,\n params: route.params,\n query: route.query,\n children: node\n })\n }\n return node\n }})\n })\n}\n\nexport function useRouter(): Router {\n const router = inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: useRouter 找不到 Router,请安装 routerPlugin')\n return router\n}\n\nexport function useRoute(): Signal<RouteLocation> {\n return useRouter().currentRoute\n}\n\nexport function routerPlugin(options: RouterPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/router',\n version: '0.1.0',\n install(context) {\n const ownedRouter = options.router ? undefined : createRouter({\n routes: options.routes ?? [],\n history: options.history\n })\n const router = options.router ?? ownedRouter!\n context.provide(ROUTER_KEY, router)\n return () => ownedRouter?.destroy()\n }\n }\n}\n\ninterface RouteMatcher {\n readonly record: RouteRecord\n readonly debugId: string\n readonly chain: readonly RouteRecord[]\n readonly meta: RouteMeta\n readonly regex: RegExp\n readonly keys: readonly string[]\n readonly score: number\n readonly order: number\n}\n\ninterface LazyState {\n status: 'loading' | 'ready' | 'error'\n component?: RouteComponent\n error?: Error\n}\n\ninterface ParsedTarget {\n readonly path: string\n readonly query: RouteQuery\n readonly hash: string\n readonly state?: unknown\n}\n\nfunction defaultHistory(): RouterHistory {\n return typeof window === 'undefined' ? createMemoryHistory('/') : createBrowserHistory()\n}\n\nconst EMPTY_MATCHED: readonly RouteRecord[] = Object.freeze([])\nconst routeDebugIds = new WeakMap<RouteRecord, string>()\n\nfunction buildRouteDebugTree(routes: readonly RouteRecord[], lazyStatuses: ReadonlyMap<string, LazyState['status']> = new Map()): readonly RouteDebugNode[] {\n const visit = (records: readonly RouteRecord[], parentPath: string, parentId: string): RouteDebugNode[] => records.map((record, index) => {\n const path = record.path === undefined ? parentPath || '/' : resolveChildPath(parentPath, record.path)\n const id = `${parentId}.${index}`\n const definition = record.component\n const lazyDefinition = definition !== undefined && isLazyRouteComponent(definition)\n const componentName = definition === undefined\n ? 'Route'\n : lazyDefinition\n ? 'lazy(...)'\n : typeof definition === 'function'\n ? definition.name || 'Anonymous'\n : 'Route'\n return {\n id,\n path,\n name: record.name,\n component: componentName,\n source: record.source,\n lazy: lazyDefinition,\n loader: record.loader !== undefined,\n action: record.action !== undefined,\n status: lazyDefinition ? (lazyStatuses.get(id) ?? 'loading') : 'ready',\n meta: Object.freeze({ ...(record.meta ?? {}) }),\n children: visit(record.children ?? [], path, id)\n }\n })\n return Object.freeze(visit(routes, '', 'route'))\n}\n\nfunction normalizeRoutes(routes: readonly RouteRecord[]): RouteMatcher[] {\n const matchers: RouteMatcher[] = []\n let order = 0\n\n function visit(records: readonly RouteRecord[], parentPath: string, parentChain: readonly RouteRecord[], parentMeta: RouteMeta, parentId = 'route'): void {\n records.forEach((record, index) => {\n const debugId = `${parentId}.${index}`\n const children = record.children ?? []\n const path = record.path === undefined\n ? parentPath\n : resolveChildPath(parentPath, record.path)\n const normalized: RouteRecord = {\n ...record,\n path: record.path === undefined\n ? (children.length > 0 ? undefined : (path || '/'))\n : path,\n meta: record.meta ? { ...record.meta } : {}\n }\n routeDebugIds.set(normalized, debugId)\n const chain = [...parentChain, normalized]\n const meta = Object.freeze({ ...parentMeta, ...(normalized.meta ?? {}) })\n if (children.length > 0) {\n visit(children, path, chain, meta, debugId)\n } else if (normalized.component) {\n matchers.push(createMatcher(normalized, chain, meta, order++, debugId))\n } else if (normalized.path === undefined) {\n throw new Error(`Vobs Router: 第 ${index + 1} 个路由缺少 path 或 children`)\n }\n })\n }\n\n visit(routes, '', [], {})\n return matchers\n}\n\nfunction resolveChildPath(parentPath: string, childPath: string): string {\n const normalizedChild = normalizePath(childPath)\n if (!parentPath || normalizedChild === '/') return normalizedChild === '/' ? (parentPath || '/') : normalizedChild\n if (childPath.startsWith('/')) return normalizedChild\n return normalizePath(`${parentPath}/${childPath}`)\n}\n\nfunction createMatcher(record: RouteRecord, chain: readonly RouteRecord[], meta: RouteMeta, order: number, debugId: string): RouteMatcher {\n const path = record.path ?? '/'\n const segments = path === '/' ? [] : path.slice(1).split('/')\n const keys: string[] = []\n let score = 0\n const pattern = segments.map(segment => {\n if (segment === '*') {\n keys.push('pathMatch')\n return '(.*)'\n }\n if (segment.startsWith(':')) {\n const key = segment.slice(1)\n if (!key) throw new Error(`Vobs Router: 路由 ${path} 的参数名不能为空`)\n if (keys.includes(key)) throw new Error(`Vobs Router: 路由 ${path} 存在重复参数 ${key}`)\n keys.push(key)\n score += 1\n return '([^/]+)'\n }\n score += 3\n return escapeRegExp(segment)\n }).join('/')\n\n return {\n record,\n debugId,\n chain: Object.freeze([...chain]),\n meta,\n regex: new RegExp(segments.length === 0 ? '^/?$' : `^/${pattern}/?$`),\n keys,\n score,\n order\n }\n}\n\nfunction compareMatchers(left: RouteMatcher, right: RouteMatcher): number {\n return right.score - left.score || left.order - right.order\n}\n\nfunction extractParams(matcher: RouteMatcher, path: string): RouteParams {\n const match = matcher.regex.exec(path)\n if (!match) return {}\n const params: Record<string, string> = {}\n matcher.keys.forEach((key, index) => {\n params[key] = decodeRoutePart(match[index + 1] ?? '')\n })\n return Object.freeze(params)\n}\n\nfunction parseTargetString(raw: string): ParsedTarget {\n const hashIndex = raw.indexOf('#')\n const hash = hashIndex >= 0 ? normalizeHash(raw.slice(hashIndex + 1)) : ''\n const withoutHash = hashIndex >= 0 ? raw.slice(0, hashIndex) : raw\n const queryIndex = withoutHash.indexOf('?')\n const path = normalizePath(queryIndex >= 0 ? withoutHash.slice(0, queryIndex) : withoutHash)\n const query = queryIndex >= 0 ? parseQuery(withoutHash.slice(queryIndex + 1)) : {}\n return { path, query, hash }\n}\n\nfunction normalizeTarget(target: RouteLocationRaw, matchers: readonly RouteMatcher[]): ParsedTarget {\n let path = target.path\n if (!path && target.name) {\n const matcher = matchers.find(candidate => candidate.record.name === target.name)\n if (!matcher) throw new Error(`Vobs Router: 找不到名为 ${target.name} 的路由`)\n path = fillRouteParams(matcher.record.path ?? '/', target.params ?? {})\n }\n if (!path) throw new Error('Vobs Router: 导航目标必须提供 path 或 name')\n\n const parsed = parseTargetString(path)\n const filledPath = fillRouteParams(parsed.path, target.params ?? {})\n const query = target.query === undefined ? parsed.query : normalizeQuery(target.query)\n const hash = target.hash === undefined ? parsed.hash : normalizeHash(target.hash)\n return { path: filledPath, query, hash, state: target.state }\n}\n\nfunction fillRouteParams(path: string, params: Record<string, unknown>): string {\n return path.replace(/:([A-Za-z0-9_]+)|\\*/g, (token, key: string | undefined) => {\n const value = key ? params[key] : params.pathMatch\n if (value === undefined || value === null) return token\n return encodeURIComponent(String(value))\n })\n}\n\nfunction buildTargetPath(path: string, query: RouteQuery, hash: string): string {\n const params = new URLSearchParams()\n for (const key of Object.keys(query).sort()) {\n const value = query[key]\n if (typeof value === 'string') {\n params.set(key, value)\n } else {\n for (const item of value) params.append(key, item)\n }\n }\n const serialized = params.toString()\n return `${path}${serialized ? `?${serialized}` : ''}${hash}`\n}\n\nfunction parseQuery(raw: string): RouteQuery {\n const params = new URLSearchParams(raw)\n const result: Record<string, RouteQueryValue> = {}\n params.forEach((value, key) => {\n const previous = result[key]\n if (previous === undefined) result[key] = value\n else if (typeof previous === 'string') result[key] = [previous, value]\n else result[key] = [...previous, value]\n })\n for (const key of Object.keys(result)) {\n if (Array.isArray(result[key])) result[key] = Object.freeze(result[key] as string[])\n }\n return Object.freeze(result)\n}\n\nfunction normalizeQuery(input: RouteQueryInput): RouteQuery {\n if (input instanceof URLSearchParams) return parseQuery(input.toString())\n const result: Record<string, RouteQueryValue> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) result[key] = Object.freeze(value.map(item => String(item)))\n else result[key] = String(value)\n }\n return Object.freeze(result)\n}\n\nfunction normalizePath(path: string): string {\n if (!path) return '/'\n const withoutQuery = path.split(/[?#]/, 1)[0] || '/'\n const withLeadingSlash = withoutQuery.startsWith('/') ? withoutQuery : `/${withoutQuery}`\n if (withLeadingSlash === '/*' || withLeadingSlash === '/') return withLeadingSlash\n return withLeadingSlash.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/'\n}\n\nfunction normalizeHistoryPath(path: string): string {\n const parsed = parseTargetString(path)\n return buildTargetPath(parsed.path, parsed.query, parsed.hash)\n}\n\nfunction normalizeHash(hash: string): string {\n if (!hash) return ''\n return hash.startsWith('#') ? hash : `#${hash}`\n}\n\nfunction normalizeBase(base: string): string {\n if (!base || base === '/') return ''\n return `/${base.replace(/^\\/+|\\/+$/g, '')}`\n}\n\nfunction readBrowserLocation(base: string): string {\n const pathname = window.location.pathname\n const path = base && (pathname === base || pathname.startsWith(`${base}/`))\n ? pathname.slice(base.length) || '/'\n : pathname\n return normalizeHistoryPath(`${path}${window.location.search}${window.location.hash}`)\n}\n\nfunction withBase(path: string, base: string): string {\n return `${base}${path === '/' ? '/' : path}` || '/'\n}\n\nfunction notifyListeners(listeners: Set<(path: string, state: unknown) => void>, path: string, state: unknown): void {\n for (const listener of [...listeners]) listener(path, state)\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction decodeRoutePart(value: string): string {\n try {\n return decodeURIComponent(value)\n } catch {\n return value\n }\n}\n\nfunction isLazyRouteComponent(value: RouteComponentDefinition): value is LazyRouteComponent {\n return typeof value === 'object' && value !== null && value.kind === 'vobs-lazy-route'\n}\n\nfunction isRouteComponentDefinition(value: unknown): value is RouteComponentDefinition {\n return typeof value === 'function' || isLazyRouteComponent(value as RouteComponentDefinition)\n}\n\nasync function loadRouteComponent(loader: LazyRouteComponent): Promise<RouteComponent> {\n const module = await loader.load()\n const component = typeof module === 'function' ? module : module.default\n if (typeof component !== 'function') throw new Error('Vobs Router: 懒加载模块没有默认组件导出')\n return component\n}\n\nfunction isRouteLocationRaw(value: unknown): value is RouteLocationRaw {\n return Boolean(value) && typeof value === 'object'\n}\n\nfunction toError(reason: unknown): Error {\n return reason instanceof Error ? reason : new Error(String(reason))\n}\n\nfunction isAbortError(reason: unknown): boolean {\n return Boolean(reason) && typeof reason === 'object'\n && ((reason as { readonly name?: unknown }).name === 'AbortError'\n || (reason as { readonly code?: unknown }).code === 'ERR_CANCELED')\n}\n","import type { RuntimeDebugContext } from '@vobs/runtime'\n\nexport type RouterDebugEventType =\n | 'navigation:start'\n | 'navigation:end'\n | 'route:update'\n | 'data-request'\n | 'error'\n\nexport interface RouterDebugEvent {\n readonly routerId: string\n readonly type: RouterDebugEventType\n readonly payload: unknown\n readonly context?: RuntimeDebugContext\n}\n\ntype RouterDebugListener = (event: RouterDebugEvent) => void\n\nconst listeners = new Set<RouterDebugListener>()\nlet nextRouterId = 1\n\nexport function createRouterDebugId(): string {\n return `router-${nextRouterId++}`\n}\n\nexport function subscribeRouterDebug(listener: RouterDebugListener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nexport function emitRouterDebug(\n routerId: string,\n type: RouterDebugEventType,\n payload: unknown,\n context?: RuntimeDebugContext\n): void {\n const event: RouterDebugEvent = { routerId, type, payload, context }\n for (const listener of [...listeners]) {\n try { listener(event) } catch { /* diagnostics must not affect navigation */ }\n }\n}\n"],"mappings":"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","names":["import_runtime","listeners","state","options","module"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/debug.ts"],"sourcesContent":["import { state, type Signal } from '@vobs/reactivity'\nimport {\n createComponent,\n createElement,\n createFragment,\n createInjectionKey,\n inject,\n insertBoundary,\n type InjectionKey,\n type VobsNode,\n type VobsPlugin\n} from '@vobs/vobs'\nimport {\n createRouterDebugId,\n emitRouterDebug\n} from './debug'\nimport {\n getRuntimeDebugContext,\n runWithRuntimeDebugContext,\n type RuntimeDebugContext\n} from '@vobs/runtime'\n\nexport { createRouterDebugId, emitRouterDebug, subscribeRouterDebug } from './debug'\nexport type { RouterDebugEvent, RouterDebugEventType } from './debug'\n\nexport type RouteParams = Readonly<Record<string, string>>\nexport type RouteQueryValue = string | readonly string[]\nexport type RouteQuery = Readonly<Record<string, RouteQueryValue>>\nexport type RouteMeta = Readonly<Record<string, unknown>>\n\nexport interface RouteLocation {\n readonly path: string\n readonly fullPath: string\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly hash: string\n readonly name: string | undefined\n readonly meta: RouteMeta\n readonly record: RouteRecord | null\n readonly matched: readonly RouteRecord[]\n readonly state?: unknown\n}\n\nexport interface RouteComponentProps {\n readonly route: RouteLocation\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly children?: VobsNode\n}\n\nexport type RouteComponent = (props: RouteComponentProps) => VobsNode\nexport type RouteComponentModule = RouteComponent | { default: RouteComponent }\nexport type RouteComponentLoader = () => PromiseLike<RouteComponentModule>\n\nexport interface LazyRouteComponent {\n readonly kind: 'vobs-lazy-route'\n readonly load: RouteComponentLoader\n}\n\nexport type RouteComponentDefinition = RouteComponent | LazyRouteComponent\n\nexport interface RouteLoaderContext {\n readonly route: RouteLocation\n readonly navigationId?: number\n readonly dataRequestId?: number\n}\n\nexport type RouteLoader = (context: RouteLoaderContext) => unknown | PromiseLike<unknown>\n\nexport interface RouteRecord {\n readonly path?: string\n readonly component?: RouteComponentDefinition\n readonly source?: string\n readonly name?: string\n readonly meta?: Record<string, unknown>\n readonly loader?: RouteLoader\n readonly action?: RouteLoader\n readonly children?: readonly RouteRecord[]\n}\n\nexport type RouteQueryInput = Record<string, unknown> | URLSearchParams\n\nexport interface RouteLocationRaw {\n readonly path?: string\n readonly name?: string\n readonly params?: Record<string, unknown>\n readonly query?: RouteQueryInput\n readonly hash?: string\n readonly state?: unknown\n}\n\nexport type RouteTarget = string | RouteLocationRaw\n\nexport type NavigationGuardResult = void | boolean | RouteTarget\nexport type NavigationGuard = (\n to: RouteLocation,\n from: RouteLocation\n) => NavigationGuardResult | PromiseLike<NavigationGuardResult>\n\nexport class NavigationCancelledError extends Error {\n readonly code = 'NAVIGATION_CANCELLED'\n\n constructor() {\n super('Vobs Router: 导航已被更新的导航取消')\n this.name = 'NavigationCancelledError'\n }\n}\n\nexport class NavigationRedirectError extends Error {\n readonly code = 'NAVIGATION_REDIRECT_LIMIT'\n\n constructor() {\n super('Vobs Router: 导航重定向超过最大次数')\n this.name = 'NavigationRedirectError'\n }\n}\n\nexport interface RouterHistory {\n readonly location: string\n /** 当前 history 条目携带的导航 state(push/replace 时写入,popstate/初始启动时回读)。 */\n readonly state?: unknown\n push(path: string, state?: unknown): void\n replace(path: string, state?: unknown): void\n back(): void\n listen(listener: (path: string, state: unknown) => void): () => void\n}\n\nexport interface RouterOptions {\n readonly routes: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport interface RouterViewState {\n readonly status: 'ready' | 'loading' | 'error' | 'not-found'\n readonly component?: RouteComponent\n readonly layouts?: readonly RouteComponent[]\n readonly error?: Error\n readonly retry: () => void\n}\n\nexport interface RouteDebugNode {\n readonly id: string\n readonly path: string\n readonly name?: string\n readonly component: string\n readonly lazy: boolean\n readonly loader: boolean\n readonly action: boolean\n readonly status: 'ready' | 'loading' | 'error'\n readonly meta: RouteMeta\n readonly source?: string\n readonly children: readonly RouteDebugNode[]\n}\n\nexport interface RouteErrorTrace {\n readonly id: number\n readonly phase: 'navigation' | 'render' | 'lazy' | 'loader' | 'action' | 'fetcher'\n readonly route: string\n readonly message: string\n readonly stack?: string\n readonly timestamp: number\n readonly requestId?: number\n readonly navigationId?: number\n}\n\nexport interface NavigationTrace {\n readonly id: number\n readonly from: string\n readonly to: string\n readonly status: 'success' | 'redirected' | 'cancelled' | 'error'\n readonly source: 'push' | 'replace' | 'history'\n readonly startedAt: number\n readonly endedAt: number\n readonly duration: number\n readonly redirect?: string\n readonly error?: string\n}\n\nexport interface NavigationState {\n readonly status: 'idle' | 'loading' | 'error'\n readonly from: string\n readonly to: string\n readonly traceId?: number\n readonly error?: string\n}\n\nexport interface RouterPerformanceMetrics {\n readonly navigationCount: number\n readonly averageNavigationDuration: number\n readonly slowNavigationCount: number\n}\n\nexport type RouterDataRequestKind = 'loader' | 'action' | 'fetcher'\n\nexport interface RouterDataRequestTrace {\n readonly id: number\n readonly kind: RouterDataRequestKind\n readonly key: string\n readonly route?: string\n readonly status: 'loading' | 'success' | 'error' | 'cancelled'\n readonly startedAt: number\n readonly endedAt?: number\n readonly duration?: number\n readonly result?: unknown\n readonly error?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport interface RouterDataRequestOptions {\n readonly route?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport type RouterDevToolsEvent = 'navigation:start' | 'navigation:end' | 'route:update' | 'data-request' | 'error'\n\nexport interface RouterDevToolsAPI {\n getRouteTree(): readonly RouteDebugNode[]\n getCurrentRoute(): RouteLocation\n getNavigationState(): NavigationState\n getNavigationHistory(): readonly NavigationTrace[]\n getPerformanceMetrics(): RouterPerformanceMetrics\n getDataRequests(): readonly RouterDataRequestTrace[]\n getErrors(): readonly RouteErrorTrace[]\n trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: () => T | PromiseLike<T>,\n options?: RouterDataRequestOptions | string\n ): Promise<T>\n runAction<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n runFetcher<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n reportError(phase: RouteErrorTrace['phase'], error: unknown, route?: string, context?: { readonly requestId?: number; readonly navigationId?: number }): void\n revalidate(route?: string): Promise<void>\n subscribe(event: RouterDevToolsEvent, callback: (payload: unknown) => void): () => void\n}\n\nexport interface Router {\n readonly currentRoute: Signal<RouteLocation>\n readonly history: RouterHistory\n resolve(to: RouteTarget): RouteLocation\n push(to: RouteTarget): Promise<RouteLocation | false>\n replace(to: RouteTarget): Promise<RouteLocation | false>\n back(): void\n beforeEach(guard: NavigationGuard): () => void\n getViewState(route: RouteLocation): RouterViewState\n readonly devtools: RouterDevToolsAPI\n destroy(): void\n}\n\nexport interface RouterViewProps {\n readonly router?: Router\n /** 加载占位:JSX 属性经编译器编译为惰性 getter,手写对象字面量可传节点或工厂。 */\n readonly loading?: VobsNode | (() => VobsNode | null | undefined)\n readonly notFound?: (route: RouteLocation) => VobsNode | null | undefined\n readonly error?: (error: Error, retry: () => void) => VobsNode | null | undefined\n}\n\nexport interface RouterPluginOptions {\n readonly router?: Router\n readonly routes?: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport const ROUTER_KEY: InjectionKey<Router> = createInjectionKey<Router>('vobs.router')\n\nexport function lazy(loader: RouteComponentLoader): LazyRouteComponent {\n return {\n kind: 'vobs-lazy-route',\n load: loader\n }\n}\n\nexport function createMemoryHistory(initial = '/'): RouterHistory {\n let entries = [{ path: normalizeHistoryPath(initial), state: undefined as unknown }]\n let index = 0\n const listeners = new Set<(path: string, state: unknown) => void>()\n\n return {\n get location(): string {\n return entries[index]!.path\n },\n\n get state(): unknown {\n return entries[index]!.state\n },\n\n push(path: string, state?: unknown): void {\n const next = normalizeHistoryPath(path)\n entries = entries.slice(0, index + 1)\n entries.push({ path: next, state })\n index++\n },\n\n replace(path: string, state?: unknown): void {\n entries[index] = { path: normalizeHistoryPath(path), state }\n },\n\n back(): void {\n if (index === 0) return\n index--\n notifyListeners(listeners, entries[index]!.path, entries[index]!.state)\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n }\n}\n\nexport function createBrowserHistory(base = ''): RouterHistory {\n if (typeof window === 'undefined') {\n throw new Error('Vobs Router: createBrowserHistory 需要浏览器环境')\n }\n\n const normalizedBase = normalizeBase(base)\n const listeners = new Set<(path: string, state: unknown) => void>()\n const onPopState = (event: PopStateEvent): void => {\n notifyListeners(listeners, readBrowserLocation(normalizedBase), event.state)\n }\n\n return {\n get location(): string {\n return readBrowserLocation(normalizedBase)\n },\n\n get state(): unknown {\n return window.history.state\n },\n\n push(path: string, state?: unknown): void {\n window.history.pushState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n replace(path: string, state?: unknown): void {\n window.history.replaceState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n back(): void {\n window.history.back()\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n if (listeners.size === 0) window.addEventListener('popstate', onPopState)\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n if (listeners.size === 0) window.removeEventListener('popstate', onPopState)\n }\n }\n }\n}\n\nexport function createRouter(options: RouterOptions): Router {\n const matchers = normalizeRoutes(options.routes)\n const history = options.history ?? defaultHistory()\n const routerDebugId = createRouterDebugId()\n matchers.sort(compareMatchers)\n const currentRoute = state<RouteLocation>(resolvePath(history.location))\n const lazyStates = new Map<RouteRecord, LazyState>()\n const guards: NavigationGuard[] = []\n const navigationHistory: NavigationTrace[] = []\n const dataRequests: RouterDataRequestTrace[] = []\n const errors: RouteErrorTrace[] = []\n const dataLoaders = new Map<string, { kind: RouterDataRequestKind; route: string; task: () => unknown | PromiseLike<unknown> }>()\n const dataRequestContexts = new Map<number, RuntimeDebugContext>()\n const routerListeners = new Map<RouterDevToolsEvent, Set<(payload: unknown) => void>>()\n let navigationState: NavigationState = { status: 'idle', from: currentRoute.value.fullPath, to: currentRoute.value.fullPath }\n let navigationCount = 0\n let totalNavigationDuration = 0\n let slowNavigationCount = 0\n let nextDataRequestId = 1\n let nextErrorId = 1\n let navigationId = 0\n let destroyed = false\n const viewRevision = state(0)\n\n function resolve(to: RouteTarget): RouteLocation {\n ensureActive()\n const target = typeof to === 'string' ? parseTargetString(to) : normalizeTarget(to, matchers)\n return resolvePath(buildTargetPath(target.path, target.query, target.hash), target.state)\n }\n\n function resolvePath(rawPath: string, state?: unknown): RouteLocation {\n const parsed = parseTargetString(rawPath)\n const matched = matchers.find(matcher => matcher.regex.exec(parsed.path))\n const params = matched ? extractParams(matched, parsed.path) : {}\n const record = matched?.record ?? null\n const query = parsed.query\n const hash = parsed.hash\n return {\n path: parsed.path,\n fullPath: buildTargetPath(parsed.path, query, hash),\n params,\n query,\n hash,\n name: record?.name,\n meta: matched?.meta ?? {},\n record,\n matched: matched?.chain ?? EMPTY_MATCHED,\n state\n }\n }\n\n async function navigate(\n to: RouteTarget,\n replaceHistory: boolean,\n fromHistory: boolean,\n historyState?: unknown\n ): Promise<RouteLocation | false> {\n ensureActive()\n const id = ++navigationId\n const from = currentRoute.value\n let target = resolve(to)\n // popstate 回读的 state 保存在 history 条目上,不在目标描述里,这里回填。\n if (fromHistory && historyState !== undefined) target = { ...target, state: historyState }\n const source: NavigationTrace['source'] = fromHistory ? 'history' : replaceHistory ? 'replace' : 'push'\n const startedAt = now()\n const initialTarget = target.fullPath\n let terminalRecorded = false\n navigationState = { status: 'loading', from: from.fullPath, to: target.fullPath, traceId: id }\n emitRouter('navigation:start', navigationState)\n if (target.fullPath === from.fullPath && !fromHistory) {\n navigationState = { status: 'idle', from: from.fullPath, to: target.fullPath }\n return from\n }\n\n try {\n for (let redirectCount = 0; ; redirectCount++) {\n ensureNavigationIsCurrent(id)\n let redirect: RouteTarget | undefined\n for (const guard of [...guards]) {\n let result: NavigationGuardResult\n try {\n result = await guard(target, from)\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) throw reason\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw reason\n }\n ensureNavigationIsCurrent(id)\n if (result === false) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n return false\n }\n if (typeof result === 'string' || isRouteLocationRaw(result)) {\n redirect = result\n break\n }\n }\n\n for (const record of target.matched) {\n if (!record.loader) continue\n // 上一 loader 期间被新导航抢占时立即取消,跳过剩余 loader。\n ensureNavigationIsCurrent(id)\n await trackDataRequest(\n 'loader',\n `${target.fullPath}#${record.path ?? record.name ?? 'route'}`,\n context => record.loader!({ route: target, navigationId: id, dataRequestId: context.dataRequestId }),\n { route: target.fullPath, navigationId: id, trigger: 'navigation' }\n )\n }\n\n // loader 完成后、提交前必须重新校验:飞行期间被抢占的导航不允许覆盖 currentRoute 与 history。\n ensureNavigationIsCurrent(id)\n\n if (redirect !== undefined) {\n if (redirectCount >= 10) {\n const error = new NavigationRedirectError()\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw error\n }\n const redirected = resolve(redirect)\n if (redirected.fullPath === target.fullPath) return false\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'redirected', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: redirected.fullPath })\n target = redirected\n continue\n }\n\n if (target.fullPath === from.fullPath) return from\n if (!fromHistory) {\n if (replaceHistory) history.replace(target.fullPath, target.state)\n else history.push(target.fullPath, target.state)\n }\n currentRoute.value = target\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'success', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: target.fullPath !== initialTarget ? target.fullPath : undefined })\n terminalRecorded = true\n return target\n }\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n } else if (!terminalRecorded) {\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n }\n throw reason\n }\n }\n\n function now(): number {\n return typeof performance === 'undefined' ? Date.now() : performance.now()\n }\n\n function emitRouter(event: RouterDevToolsEvent, payload: unknown): void {\n for (const callback of routerListeners.get(event) ?? []) {\n try { callback(payload) } catch { /* diagnostics must not affect navigation */ }\n }\n emitRouterDebug(routerDebugId, event, payload, getRuntimeDebugContext() ?? undefined)\n }\n\n function recordNavigation(trace: NavigationTrace): void {\n navigationHistory.push(Object.freeze(trace))\n if (navigationHistory.length > 100) navigationHistory.shift()\n navigationCount++\n totalNavigationDuration += trace.duration\n if (trace.duration >= 16) slowNavigationCount++\n if (trace.id === navigationId) {\n navigationState = trace.status === 'error'\n ? { status: 'error', from: trace.from, to: trace.to, traceId: trace.id, error: trace.error }\n : { status: 'idle', from: trace.from, to: trace.to, traceId: trace.id }\n }\n emitRouter('navigation:end', trace)\n emitRouter('route:update', currentRoute.value)\n }\n\n async function trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: ((context: { readonly dataRequestId: number }) => T | PromiseLike<T>) | (() => T | PromiseLike<T>),\n optionsOrRoute: RouterDataRequestOptions | string = {}\n ): Promise<T> {\n ensureActive()\n const options = typeof optionsOrRoute === 'string' ? { route: optionsOrRoute } : optionsOrRoute\n const id = nextDataRequestId++\n const startedAt = now()\n const context = getRuntimeDebugContext()\n const route = options.route ?? currentRoute.value.fullPath\n const requestContext: RuntimeDebugContext = {\n ...context,\n environment: options.environment ?? context?.environment,\n route,\n navigationId: options.navigationId ?? context?.navigationId,\n dataRequestId: id,\n source: kind\n }\n const loading: RouterDataRequestTrace = {\n id,\n kind,\n key,\n route,\n status: 'loading',\n startedAt,\n navigationId: requestContext.navigationId,\n trigger: options.trigger,\n environment: requestContext.environment\n }\n dataRequests.push(loading)\n if (dataRequests.length > 100) dataRequests.shift()\n dataRequestContexts.set(id, requestContext)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', loading)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'start', trace: loading }, requestContext)\n dataLoaders.set(key, { kind, route, task: task as () => unknown | PromiseLike<unknown> })\n try {\n const result = await runWithRuntimeDebugContext(requestContext, () => (task as (context: { readonly dataRequestId: number }) => T | PromiseLike<T>)({ dataRequestId: id }))\n const endedAt = now()\n replaceDataRequest(id, { ...loading, status: 'success', endedAt, duration: endedAt - startedAt, result })\n return result\n } catch (reason) {\n const endedAt = now()\n const error = toError(reason)\n const status = isAbortError(reason) ? 'cancelled' : 'error'\n if (status === 'error') reportError(kind, error, route, { requestId: id, navigationId: requestContext.navigationId })\n replaceDataRequest(id, { ...loading, status, endedAt, duration: endedAt - startedAt, error: status === 'error' ? error.message : undefined })\n throw reason\n }\n }\n\n function replaceDataRequest(id: number, trace: RouterDataRequestTrace): void {\n const index = dataRequests.findIndex(item => item.id === id)\n if (index >= 0) dataRequests[index] = Object.freeze(trace)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', trace)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'end', trace }, dataRequestContexts.get(id))\n dataRequestContexts.delete(id)\n }\n\n function reportError(\n phase: RouteErrorTrace['phase'],\n reason: unknown,\n route = currentRoute.value.fullPath,\n context: { readonly requestId?: number; readonly navigationId?: number } = {}\n ): void {\n const error = toError(reason)\n errors.push(Object.freeze({\n id: nextErrorId++,\n phase,\n route,\n message: error.message,\n stack: error.stack,\n timestamp: now(),\n requestId: context.requestId,\n navigationId: context.navigationId\n }))\n if (errors.length > 100) errors.shift()\n emitRouter('error', errors[errors.length - 1]!)\n emitRouter('route:update', currentRoute.value)\n }\n\n function routeTree(): readonly RouteDebugNode[] {\n const statuses = new Map<string, LazyState['status']>()\n for (const matcher of matchers) {\n for (const record of matcher.chain) {\n if (record.component && isLazyRouteComponent(record.component)) {\n const debugId = routeDebugIds.get(record)\n if (debugId) statuses.set(debugId, lazyStates.get(record)?.status ?? 'loading')\n }\n }\n }\n return buildRouteDebugTree(options.routes, statuses)\n }\n\n function handleHistoryNavigation(path: string, state: unknown): void {\n void navigate(path, false, true, state).then(result => {\n if (destroyed) return\n if (result === false) {\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n } else if (result.fullPath !== normalizeHistoryPath(path)) {\n history.replace(result.fullPath, result.state)\n }\n }).catch(error => {\n if (!(error instanceof NavigationCancelledError) && !destroyed) {\n const current = currentRoute.value.fullPath\n const failed = toError(error)\n reportError('navigation', failed, normalizeHistoryPath(path))\n navigationState = { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message }\n emitRouter('navigation:end', { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message })\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n }\n })\n }\n\n const stopHistory = history.listen(handleHistoryNavigation)\n\n const router: Router = {\n currentRoute,\n history,\n\n resolve,\n\n push(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, false, false)\n },\n\n replace(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, true, false)\n },\n\n back(): void {\n ensureActive()\n history.back()\n },\n\n beforeEach(guard: NavigationGuard): () => void {\n ensureActive()\n guards.push(guard)\n return () => {\n const index = guards.indexOf(guard)\n if (index >= 0) guards.splice(index, 1)\n }\n },\n\n getViewState(route: RouteLocation): RouterViewState {\n viewRevision.value\n const records = route.matched.length > 0 ? route.matched : route.record ? [route.record] : []\n const entries = records\n .map(record => ({ record, definition: record.component }))\n .filter((entry): entry is { record: RouteRecord; definition: RouteComponentDefinition } =>\n isRouteComponentDefinition(entry.definition))\n if (!route.record || entries.length === 0) return { status: 'not-found', retry: () => undefined }\n\n const loaded: RouteComponent[] = []\n const lazyRecords: RouteRecord[] = []\n for (const entry of entries) {\n const { record, definition } = entry\n if (!isLazyRouteComponent(definition)) {\n loaded.push(definition)\n continue\n }\n lazyRecords.push(record)\n const lazyState = ensureLazyState(record, definition)\n if (lazyState.status === 'loading') return { status: 'loading', retry: () => retryLazyRoutes(lazyRecords) }\n if (lazyState.status === 'error') {\n return { status: 'error', error: lazyState.error, retry: () => retryLazyRoutes(lazyRecords) }\n }\n if (lazyState.component) loaded.push(lazyState.component)\n }\n\n const component = loaded[loaded.length - 1]\n if (!component) return { status: 'not-found', retry: () => undefined }\n return {\n status: 'ready',\n component,\n layouts: loaded.slice(0, -1),\n retry: () => retryLazyRoutes(lazyRecords)\n }\n },\n\n devtools: {\n getRouteTree: routeTree,\n getCurrentRoute: () => currentRoute.value,\n getNavigationState: () => navigationState,\n getNavigationHistory: () => [...navigationHistory],\n getPerformanceMetrics: () => ({\n navigationCount,\n averageNavigationDuration: navigationCount === 0 ? 0 : totalNavigationDuration / navigationCount,\n slowNavigationCount\n }),\n getDataRequests: () => [...dataRequests],\n getErrors: () => [...errors],\n trackDataRequest,\n runAction: (key, task) => trackDataRequest('action', key, task, { trigger: 'manual' }),\n runFetcher: (key, task) => trackDataRequest('fetcher', key, task, { trigger: 'manual' }),\n reportError,\n revalidate: async (route) => {\n await Promise.all([...dataLoaders.entries()]\n .filter(([, loader]) => loader.kind === 'loader' && (route === undefined || loader.route === route))\n .map(([key, loader]) => trackDataRequest(loader.kind, key, loader.task, { route: loader.route, trigger: 'revalidate' })))\n },\n subscribe(event, callback) {\n let listeners = routerListeners.get(event)\n if (!listeners) { listeners = new Set(); routerListeners.set(event, listeners) }\n listeners.add(callback)\n return () => listeners?.delete(callback)\n }\n },\n\n destroy(): void {\n if (destroyed) return\n destroyed = true\n navigationId++\n stopHistory()\n guards.length = 0\n routerListeners.clear()\n lazyStates.clear()\n errors.length = 0\n dataRequestContexts.clear()\n currentRoute.dispose()\n viewRevision.dispose()\n }\n }\n\n function ensureLazyState(record: RouteRecord, definition: LazyRouteComponent): LazyState {\n let lazyState = lazyStates.get(record)\n if (!lazyState) {\n lazyState = { status: 'loading' }\n lazyStates.set(record, lazyState)\n void loadRouteComponent(definition).then(component => {\n if (destroyed) return\n lazyState!.status = 'ready'\n lazyState!.component = component\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n }).catch(reason => {\n if (destroyed) return\n lazyState!.status = 'error'\n lazyState!.error = toError(reason)\n reportError('lazy', reason, currentRoute.value.fullPath)\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n })\n }\n return lazyState\n }\n\n function retryLazyRoutes(records: readonly RouteRecord[]): void {\n for (const record of records) lazyStates.delete(record)\n viewRevision.value++\n }\n\n function ensureActive(): void {\n if (destroyed) throw new Error('Vobs Router: 已销毁的 Router 不能继续使用')\n }\n\n function ensureNavigationIsCurrent(id: number): void {\n if (id !== navigationId) throw new NavigationCancelledError()\n }\n\n return router\n}\n\nexport function RouterView(props: RouterViewProps = {}): VobsNode {\n const router = props.router ?? inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: RouterView 找不到 Router,请安装 routerPlugin')\n\n return createFragment((parent, anchor) => {\n let routeRetry: () => void = () => undefined\n insertBoundary(parent, anchor, {\n resetKey: () => router.currentRoute.value.fullPath,\n onRetry: () => routeRetry(),\n fallback: (error, retry) => {\n router.devtools.reportError('render', error, router.currentRoute.value.fullPath)\n // 提供了 error 兜底时完全尊重其返回值(含显式 null);\n // 未提供时渲染内置错误界面(含重试),不再静默渲染空白页——\n // 子 effect 抛错(如弹窗条件 children 内层裸读可空信号)会把整页换成空白\n if (props.error !== undefined) return props.error(error, () => { void retry() })\n return createRouteErrorFallback(error, () => { void retry() })\n },\n children: () => {\n const route = router.currentRoute.value\n const view = router.getViewState(route)\n routeRetry = view.retry\n if (view.status === 'loading') {\n return (typeof props.loading === 'function' ? props.loading() : props.loading) ?? null\n }\n if (view.status === 'not-found') return props.notFound?.(route) ?? null\n if (view.status === 'error') {\n throw view.error ?? new Error('路由组件加载失败')\n }\n if (!view.component) return null\n let node = createComponent(view.component, {\n route,\n params: route.params,\n query: route.query\n })\n for (let index = (view.layouts?.length ?? 0) - 1; index >= 0; index--) {\n node = createComponent(view.layouts![index]!, {\n route,\n params: route.params,\n query: route.query,\n children: node\n })\n }\n return node\n }})\n })\n}\n\nexport function useRouter(): Router {\n const router = inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: useRouter 找不到 Router,请安装 routerPlugin')\n return router\n}\n\n/** 路由错误默认兜底界面:类名 .vobs-route-error 供应用覆盖样式;重试重新渲染当前路由 */\nfunction createRouteErrorFallback(error: Error, retry: () => void): HTMLElement {\n // createElement 返回框架中立 Element;兜底界面仅在浏览器端呈现,按 HTMLElement 设置样式\n const box = createElement('div') as HTMLElement\n box.setAttribute('class', 'vobs-route-error')\n box.style.padding = '48px 24px'\n box.style.display = 'flex'\n box.style.flexDirection = 'column'\n box.style.alignItems = 'center'\n box.style.gap = '12px'\n box.style.fontFamily = 'system-ui, -apple-system, sans-serif'\n box.style.color = '#5a5f6a'\n\n const title = createElement('div') as HTMLElement\n title.textContent = '页面渲染出错'\n title.style.fontSize = '16px'\n title.style.fontWeight = '600'\n title.style.color = '#1c1c1e'\n\n const message = createElement('code') as HTMLElement\n message.textContent = error.message\n message.style.fontSize = '12px'\n message.style.maxWidth = '520px'\n message.style.wordBreak = 'break-word'\n message.style.opacity = '0.75'\n\n const button = createElement('button') as HTMLElement\n button.setAttribute('type', 'button')\n button.textContent = '重试'\n button.style.padding = '6px 20px'\n button.style.fontSize = '13px'\n button.style.cursor = 'pointer'\n button.addEventListener('click', retry)\n\n box.append(title, message, button)\n return box\n}\n\nexport function useRoute(): Signal<RouteLocation> {\n return useRouter().currentRoute\n}\n\nexport function routerPlugin(options: RouterPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/router',\n version: '0.1.0',\n install(context) {\n const ownedRouter = options.router ? undefined : createRouter({\n routes: options.routes ?? [],\n history: options.history\n })\n const router = options.router ?? ownedRouter!\n context.provide(ROUTER_KEY, router)\n return () => ownedRouter?.destroy()\n }\n }\n}\n\ninterface RouteMatcher {\n readonly record: RouteRecord\n readonly debugId: string\n readonly chain: readonly RouteRecord[]\n readonly meta: RouteMeta\n readonly regex: RegExp\n readonly keys: readonly string[]\n readonly score: number\n readonly order: number\n}\n\ninterface LazyState {\n status: 'loading' | 'ready' | 'error'\n component?: RouteComponent\n error?: Error\n}\n\ninterface ParsedTarget {\n readonly path: string\n readonly query: RouteQuery\n readonly hash: string\n readonly state?: unknown\n}\n\nfunction defaultHistory(): RouterHistory {\n return typeof window === 'undefined' ? createMemoryHistory('/') : createBrowserHistory()\n}\n\nconst EMPTY_MATCHED: readonly RouteRecord[] = Object.freeze([])\nconst routeDebugIds = new WeakMap<RouteRecord, string>()\n\nfunction buildRouteDebugTree(routes: readonly RouteRecord[], lazyStatuses: ReadonlyMap<string, LazyState['status']> = new Map()): readonly RouteDebugNode[] {\n const visit = (records: readonly RouteRecord[], parentPath: string, parentId: string): RouteDebugNode[] => records.map((record, index) => {\n const path = record.path === undefined ? parentPath || '/' : resolveChildPath(parentPath, record.path)\n const id = `${parentId}.${index}`\n const definition = record.component\n const lazyDefinition = definition !== undefined && isLazyRouteComponent(definition)\n const componentName = definition === undefined\n ? 'Route'\n : lazyDefinition\n ? 'lazy(...)'\n : typeof definition === 'function'\n ? definition.name || 'Anonymous'\n : 'Route'\n return {\n id,\n path,\n name: record.name,\n component: componentName,\n source: record.source,\n lazy: lazyDefinition,\n loader: record.loader !== undefined,\n action: record.action !== undefined,\n status: lazyDefinition ? (lazyStatuses.get(id) ?? 'loading') : 'ready',\n meta: Object.freeze({ ...(record.meta ?? {}) }),\n children: visit(record.children ?? [], path, id)\n }\n })\n return Object.freeze(visit(routes, '', 'route'))\n}\n\nfunction normalizeRoutes(routes: readonly RouteRecord[]): RouteMatcher[] {\n const matchers: RouteMatcher[] = []\n let order = 0\n\n function visit(records: readonly RouteRecord[], parentPath: string, parentChain: readonly RouteRecord[], parentMeta: RouteMeta, parentId = 'route'): void {\n records.forEach((record, index) => {\n const debugId = `${parentId}.${index}`\n const children = record.children ?? []\n const path = record.path === undefined\n ? parentPath\n : resolveChildPath(parentPath, record.path)\n const normalized: RouteRecord = {\n ...record,\n path: record.path === undefined\n ? (children.length > 0 ? undefined : (path || '/'))\n : path,\n meta: record.meta ? { ...record.meta } : {}\n }\n routeDebugIds.set(normalized, debugId)\n const chain = [...parentChain, normalized]\n const meta = Object.freeze({ ...parentMeta, ...(normalized.meta ?? {}) })\n if (children.length > 0) {\n visit(children, path, chain, meta, debugId)\n } else if (normalized.component) {\n matchers.push(createMatcher(normalized, chain, meta, order++, debugId))\n } else if (normalized.path === undefined) {\n throw new Error(`Vobs Router: 第 ${index + 1} 个路由缺少 path 或 children`)\n }\n })\n }\n\n visit(routes, '', [], {})\n return matchers\n}\n\nfunction resolveChildPath(parentPath: string, childPath: string): string {\n const normalizedChild = normalizePath(childPath)\n if (!parentPath || normalizedChild === '/') return normalizedChild === '/' ? (parentPath || '/') : normalizedChild\n if (childPath.startsWith('/')) return normalizedChild\n return normalizePath(`${parentPath}/${childPath}`)\n}\n\nfunction createMatcher(record: RouteRecord, chain: readonly RouteRecord[], meta: RouteMeta, order: number, debugId: string): RouteMatcher {\n const path = record.path ?? '/'\n const segments = path === '/' ? [] : path.slice(1).split('/')\n const keys: string[] = []\n let score = 0\n const pattern = segments.map(segment => {\n if (segment === '*') {\n keys.push('pathMatch')\n return '(.*)'\n }\n if (segment.startsWith(':')) {\n const key = segment.slice(1)\n if (!key) throw new Error(`Vobs Router: 路由 ${path} 的参数名不能为空`)\n if (keys.includes(key)) throw new Error(`Vobs Router: 路由 ${path} 存在重复参数 ${key}`)\n keys.push(key)\n score += 1\n return '([^/]+)'\n }\n score += 3\n return escapeRegExp(segment)\n }).join('/')\n\n return {\n record,\n debugId,\n chain: Object.freeze([...chain]),\n meta,\n regex: new RegExp(segments.length === 0 ? '^/?$' : `^/${pattern}/?$`),\n keys,\n score,\n order\n }\n}\n\nfunction compareMatchers(left: RouteMatcher, right: RouteMatcher): number {\n return right.score - left.score || left.order - right.order\n}\n\nfunction extractParams(matcher: RouteMatcher, path: string): RouteParams {\n const match = matcher.regex.exec(path)\n if (!match) return {}\n const params: Record<string, string> = {}\n matcher.keys.forEach((key, index) => {\n params[key] = decodeRoutePart(match[index + 1] ?? '')\n })\n return Object.freeze(params)\n}\n\nfunction parseTargetString(raw: string): ParsedTarget {\n const hashIndex = raw.indexOf('#')\n const hash = hashIndex >= 0 ? normalizeHash(raw.slice(hashIndex + 1)) : ''\n const withoutHash = hashIndex >= 0 ? raw.slice(0, hashIndex) : raw\n const queryIndex = withoutHash.indexOf('?')\n const path = normalizePath(queryIndex >= 0 ? withoutHash.slice(0, queryIndex) : withoutHash)\n const query = queryIndex >= 0 ? parseQuery(withoutHash.slice(queryIndex + 1)) : {}\n return { path, query, hash }\n}\n\nfunction normalizeTarget(target: RouteLocationRaw, matchers: readonly RouteMatcher[]): ParsedTarget {\n let path = target.path\n if (!path && target.name) {\n const matcher = matchers.find(candidate => candidate.record.name === target.name)\n if (!matcher) throw new Error(`Vobs Router: 找不到名为 ${target.name} 的路由`)\n path = fillRouteParams(matcher.record.path ?? '/', target.params ?? {})\n }\n if (!path) throw new Error('Vobs Router: 导航目标必须提供 path 或 name')\n\n const parsed = parseTargetString(path)\n const filledPath = fillRouteParams(parsed.path, target.params ?? {})\n const query = target.query === undefined ? parsed.query : normalizeQuery(target.query)\n const hash = target.hash === undefined ? parsed.hash : normalizeHash(target.hash)\n return { path: filledPath, query, hash, state: target.state }\n}\n\nfunction fillRouteParams(path: string, params: Record<string, unknown>): string {\n return path.replace(/:([A-Za-z0-9_]+)|\\*/g, (token, key: string | undefined) => {\n const value = key ? params[key] : params.pathMatch\n if (value === undefined || value === null) return token\n return encodeURIComponent(String(value))\n })\n}\n\nfunction buildTargetPath(path: string, query: RouteQuery, hash: string): string {\n const params = new URLSearchParams()\n for (const key of Object.keys(query).sort()) {\n const value = query[key]\n if (typeof value === 'string') {\n params.set(key, value)\n } else {\n for (const item of value) params.append(key, item)\n }\n }\n const serialized = params.toString()\n return `${path}${serialized ? `?${serialized}` : ''}${hash}`\n}\n\nfunction parseQuery(raw: string): RouteQuery {\n const params = new URLSearchParams(raw)\n const result: Record<string, RouteQueryValue> = {}\n params.forEach((value, key) => {\n const previous = result[key]\n if (previous === undefined) result[key] = value\n else if (typeof previous === 'string') result[key] = [previous, value]\n else result[key] = [...previous, value]\n })\n for (const key of Object.keys(result)) {\n if (Array.isArray(result[key])) result[key] = Object.freeze(result[key] as string[])\n }\n return Object.freeze(result)\n}\n\nfunction normalizeQuery(input: RouteQueryInput): RouteQuery {\n if (input instanceof URLSearchParams) return parseQuery(input.toString())\n const result: Record<string, RouteQueryValue> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) result[key] = Object.freeze(value.map(item => String(item)))\n else result[key] = String(value)\n }\n return Object.freeze(result)\n}\n\nfunction normalizePath(path: string): string {\n if (!path) return '/'\n const withoutQuery = path.split(/[?#]/, 1)[0] || '/'\n const withLeadingSlash = withoutQuery.startsWith('/') ? withoutQuery : `/${withoutQuery}`\n if (withLeadingSlash === '/*' || withLeadingSlash === '/') return withLeadingSlash\n return withLeadingSlash.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/'\n}\n\nfunction normalizeHistoryPath(path: string): string {\n const parsed = parseTargetString(path)\n return buildTargetPath(parsed.path, parsed.query, parsed.hash)\n}\n\nfunction normalizeHash(hash: string): string {\n if (!hash) return ''\n return hash.startsWith('#') ? hash : `#${hash}`\n}\n\nfunction normalizeBase(base: string): string {\n if (!base || base === '/') return ''\n return `/${base.replace(/^\\/+|\\/+$/g, '')}`\n}\n\nfunction readBrowserLocation(base: string): string {\n const pathname = window.location.pathname\n const path = base && (pathname === base || pathname.startsWith(`${base}/`))\n ? pathname.slice(base.length) || '/'\n : pathname\n return normalizeHistoryPath(`${path}${window.location.search}${window.location.hash}`)\n}\n\nfunction withBase(path: string, base: string): string {\n return `${base}${path === '/' ? '/' : path}` || '/'\n}\n\nfunction notifyListeners(listeners: Set<(path: string, state: unknown) => void>, path: string, state: unknown): void {\n for (const listener of [...listeners]) listener(path, state)\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction decodeRoutePart(value: string): string {\n try {\n return decodeURIComponent(value)\n } catch {\n return value\n }\n}\n\nfunction isLazyRouteComponent(value: RouteComponentDefinition): value is LazyRouteComponent {\n return typeof value === 'object' && value !== null && value.kind === 'vobs-lazy-route'\n}\n\nfunction isRouteComponentDefinition(value: unknown): value is RouteComponentDefinition {\n return typeof value === 'function' || isLazyRouteComponent(value as RouteComponentDefinition)\n}\n\nasync function loadRouteComponent(loader: LazyRouteComponent): Promise<RouteComponent> {\n const module = await loader.load()\n const component = typeof module === 'function' ? module : module.default\n if (typeof component !== 'function') throw new Error('Vobs Router: 懒加载模块没有默认组件导出')\n return component\n}\n\nfunction isRouteLocationRaw(value: unknown): value is RouteLocationRaw {\n return Boolean(value) && typeof value === 'object'\n}\n\nfunction toError(reason: unknown): Error {\n return reason instanceof Error ? reason : new Error(String(reason))\n}\n\nfunction isAbortError(reason: unknown): boolean {\n return Boolean(reason) && typeof reason === 'object'\n && ((reason as { readonly name?: unknown }).name === 'AbortError'\n || (reason as { readonly code?: unknown }).code === 'ERR_CANCELED')\n}\n","import type { RuntimeDebugContext } from '@vobs/runtime'\n\nexport type RouterDebugEventType =\n | 'navigation:start'\n | 'navigation:end'\n | 'route:update'\n | 'data-request'\n | 'error'\n\nexport interface RouterDebugEvent {\n readonly routerId: string\n readonly type: RouterDebugEventType\n readonly payload: unknown\n readonly context?: RuntimeDebugContext\n}\n\ntype RouterDebugListener = (event: RouterDebugEvent) => void\n\nconst listeners = new Set<RouterDebugListener>()\nlet nextRouterId = 1\n\nexport function createRouterDebugId(): string {\n return `router-${nextRouterId++}`\n}\n\nexport function subscribeRouterDebug(listener: RouterDebugListener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nexport function emitRouterDebug(\n routerId: string,\n type: RouterDebugEventType,\n payload: unknown,\n context?: RuntimeDebugContext\n): void {\n const event: RouterDebugEvent = { routerId, type, payload, context }\n for (const listener of [...listeners]) {\n try { listener(event) } catch { /* diagnostics must not affect navigation */ }\n }\n}\n"],"mappings":"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","names":["import_runtime","listeners","state","options","module"]}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
5
5
|
import { state } from "@vobs/reactivity";
|
|
6
6
|
import {
|
|
7
7
|
createComponent,
|
|
8
|
+
createElement,
|
|
8
9
|
createFragment,
|
|
9
10
|
createInjectionKey,
|
|
10
11
|
inject,
|
|
@@ -553,9 +554,12 @@ function RouterView(props = {}) {
|
|
|
553
554
|
onRetry: /* @__PURE__ */ __name(() => routeRetry(), "onRetry"),
|
|
554
555
|
fallback: /* @__PURE__ */ __name((error, retry) => {
|
|
555
556
|
router.devtools.reportError("render", error, router.currentRoute.value.fullPath);
|
|
556
|
-
return props.error
|
|
557
|
+
if (props.error !== void 0) return props.error(error, () => {
|
|
557
558
|
void retry();
|
|
558
|
-
})
|
|
559
|
+
});
|
|
560
|
+
return createRouteErrorFallback(error, () => {
|
|
561
|
+
void retry();
|
|
562
|
+
});
|
|
559
563
|
}, "fallback"),
|
|
560
564
|
children: /* @__PURE__ */ __name(() => {
|
|
561
565
|
const route = router.currentRoute.value;
|
|
@@ -594,6 +598,38 @@ function useRouter() {
|
|
|
594
598
|
return router;
|
|
595
599
|
}
|
|
596
600
|
__name(useRouter, "useRouter");
|
|
601
|
+
function createRouteErrorFallback(error, retry) {
|
|
602
|
+
const box = createElement("div");
|
|
603
|
+
box.setAttribute("class", "vobs-route-error");
|
|
604
|
+
box.style.padding = "48px 24px";
|
|
605
|
+
box.style.display = "flex";
|
|
606
|
+
box.style.flexDirection = "column";
|
|
607
|
+
box.style.alignItems = "center";
|
|
608
|
+
box.style.gap = "12px";
|
|
609
|
+
box.style.fontFamily = "system-ui, -apple-system, sans-serif";
|
|
610
|
+
box.style.color = "#5a5f6a";
|
|
611
|
+
const title = createElement("div");
|
|
612
|
+
title.textContent = "\u9875\u9762\u6E32\u67D3\u51FA\u9519";
|
|
613
|
+
title.style.fontSize = "16px";
|
|
614
|
+
title.style.fontWeight = "600";
|
|
615
|
+
title.style.color = "#1c1c1e";
|
|
616
|
+
const message = createElement("code");
|
|
617
|
+
message.textContent = error.message;
|
|
618
|
+
message.style.fontSize = "12px";
|
|
619
|
+
message.style.maxWidth = "520px";
|
|
620
|
+
message.style.wordBreak = "break-word";
|
|
621
|
+
message.style.opacity = "0.75";
|
|
622
|
+
const button = createElement("button");
|
|
623
|
+
button.setAttribute("type", "button");
|
|
624
|
+
button.textContent = "\u91CD\u8BD5";
|
|
625
|
+
button.style.padding = "6px 20px";
|
|
626
|
+
button.style.fontSize = "13px";
|
|
627
|
+
button.style.cursor = "pointer";
|
|
628
|
+
button.addEventListener("click", retry);
|
|
629
|
+
box.append(title, message, button);
|
|
630
|
+
return box;
|
|
631
|
+
}
|
|
632
|
+
__name(createRouteErrorFallback, "createRouteErrorFallback");
|
|
597
633
|
function useRoute() {
|
|
598
634
|
return useRouter().currentRoute;
|
|
599
635
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/debug.ts"],"sourcesContent":["import { state, type Signal } from '@vobs/reactivity'\nimport {\n createComponent,\n createFragment,\n createInjectionKey,\n inject,\n insertBoundary,\n type InjectionKey,\n type VobsNode,\n type VobsPlugin\n} from '@vobs/vobs'\nimport {\n createRouterDebugId,\n emitRouterDebug\n} from './debug'\nimport {\n getRuntimeDebugContext,\n runWithRuntimeDebugContext,\n type RuntimeDebugContext\n} from '@vobs/runtime'\n\nexport { createRouterDebugId, emitRouterDebug, subscribeRouterDebug } from './debug'\nexport type { RouterDebugEvent, RouterDebugEventType } from './debug'\n\nexport type RouteParams = Readonly<Record<string, string>>\nexport type RouteQueryValue = string | readonly string[]\nexport type RouteQuery = Readonly<Record<string, RouteQueryValue>>\nexport type RouteMeta = Readonly<Record<string, unknown>>\n\nexport interface RouteLocation {\n readonly path: string\n readonly fullPath: string\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly hash: string\n readonly name: string | undefined\n readonly meta: RouteMeta\n readonly record: RouteRecord | null\n readonly matched: readonly RouteRecord[]\n readonly state?: unknown\n}\n\nexport interface RouteComponentProps {\n readonly route: RouteLocation\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly children?: VobsNode\n}\n\nexport type RouteComponent = (props: RouteComponentProps) => VobsNode\nexport type RouteComponentModule = RouteComponent | { default: RouteComponent }\nexport type RouteComponentLoader = () => PromiseLike<RouteComponentModule>\n\nexport interface LazyRouteComponent {\n readonly kind: 'vobs-lazy-route'\n readonly load: RouteComponentLoader\n}\n\nexport type RouteComponentDefinition = RouteComponent | LazyRouteComponent\n\nexport interface RouteLoaderContext {\n readonly route: RouteLocation\n readonly navigationId?: number\n readonly dataRequestId?: number\n}\n\nexport type RouteLoader = (context: RouteLoaderContext) => unknown | PromiseLike<unknown>\n\nexport interface RouteRecord {\n readonly path?: string\n readonly component?: RouteComponentDefinition\n readonly source?: string\n readonly name?: string\n readonly meta?: Record<string, unknown>\n readonly loader?: RouteLoader\n readonly action?: RouteLoader\n readonly children?: readonly RouteRecord[]\n}\n\nexport type RouteQueryInput = Record<string, unknown> | URLSearchParams\n\nexport interface RouteLocationRaw {\n readonly path?: string\n readonly name?: string\n readonly params?: Record<string, unknown>\n readonly query?: RouteQueryInput\n readonly hash?: string\n readonly state?: unknown\n}\n\nexport type RouteTarget = string | RouteLocationRaw\n\nexport type NavigationGuardResult = void | boolean | RouteTarget\nexport type NavigationGuard = (\n to: RouteLocation,\n from: RouteLocation\n) => NavigationGuardResult | PromiseLike<NavigationGuardResult>\n\nexport class NavigationCancelledError extends Error {\n readonly code = 'NAVIGATION_CANCELLED'\n\n constructor() {\n super('Vobs Router: 导航已被更新的导航取消')\n this.name = 'NavigationCancelledError'\n }\n}\n\nexport class NavigationRedirectError extends Error {\n readonly code = 'NAVIGATION_REDIRECT_LIMIT'\n\n constructor() {\n super('Vobs Router: 导航重定向超过最大次数')\n this.name = 'NavigationRedirectError'\n }\n}\n\nexport interface RouterHistory {\n readonly location: string\n /** 当前 history 条目携带的导航 state(push/replace 时写入,popstate/初始启动时回读)。 */\n readonly state?: unknown\n push(path: string, state?: unknown): void\n replace(path: string, state?: unknown): void\n back(): void\n listen(listener: (path: string, state: unknown) => void): () => void\n}\n\nexport interface RouterOptions {\n readonly routes: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport interface RouterViewState {\n readonly status: 'ready' | 'loading' | 'error' | 'not-found'\n readonly component?: RouteComponent\n readonly layouts?: readonly RouteComponent[]\n readonly error?: Error\n readonly retry: () => void\n}\n\nexport interface RouteDebugNode {\n readonly id: string\n readonly path: string\n readonly name?: string\n readonly component: string\n readonly lazy: boolean\n readonly loader: boolean\n readonly action: boolean\n readonly status: 'ready' | 'loading' | 'error'\n readonly meta: RouteMeta\n readonly source?: string\n readonly children: readonly RouteDebugNode[]\n}\n\nexport interface RouteErrorTrace {\n readonly id: number\n readonly phase: 'navigation' | 'render' | 'lazy' | 'loader' | 'action' | 'fetcher'\n readonly route: string\n readonly message: string\n readonly stack?: string\n readonly timestamp: number\n readonly requestId?: number\n readonly navigationId?: number\n}\n\nexport interface NavigationTrace {\n readonly id: number\n readonly from: string\n readonly to: string\n readonly status: 'success' | 'redirected' | 'cancelled' | 'error'\n readonly source: 'push' | 'replace' | 'history'\n readonly startedAt: number\n readonly endedAt: number\n readonly duration: number\n readonly redirect?: string\n readonly error?: string\n}\n\nexport interface NavigationState {\n readonly status: 'idle' | 'loading' | 'error'\n readonly from: string\n readonly to: string\n readonly traceId?: number\n readonly error?: string\n}\n\nexport interface RouterPerformanceMetrics {\n readonly navigationCount: number\n readonly averageNavigationDuration: number\n readonly slowNavigationCount: number\n}\n\nexport type RouterDataRequestKind = 'loader' | 'action' | 'fetcher'\n\nexport interface RouterDataRequestTrace {\n readonly id: number\n readonly kind: RouterDataRequestKind\n readonly key: string\n readonly route?: string\n readonly status: 'loading' | 'success' | 'error' | 'cancelled'\n readonly startedAt: number\n readonly endedAt?: number\n readonly duration?: number\n readonly result?: unknown\n readonly error?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport interface RouterDataRequestOptions {\n readonly route?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport type RouterDevToolsEvent = 'navigation:start' | 'navigation:end' | 'route:update' | 'data-request' | 'error'\n\nexport interface RouterDevToolsAPI {\n getRouteTree(): readonly RouteDebugNode[]\n getCurrentRoute(): RouteLocation\n getNavigationState(): NavigationState\n getNavigationHistory(): readonly NavigationTrace[]\n getPerformanceMetrics(): RouterPerformanceMetrics\n getDataRequests(): readonly RouterDataRequestTrace[]\n getErrors(): readonly RouteErrorTrace[]\n trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: () => T | PromiseLike<T>,\n options?: RouterDataRequestOptions | string\n ): Promise<T>\n runAction<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n runFetcher<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n reportError(phase: RouteErrorTrace['phase'], error: unknown, route?: string, context?: { readonly requestId?: number; readonly navigationId?: number }): void\n revalidate(route?: string): Promise<void>\n subscribe(event: RouterDevToolsEvent, callback: (payload: unknown) => void): () => void\n}\n\nexport interface Router {\n readonly currentRoute: Signal<RouteLocation>\n readonly history: RouterHistory\n resolve(to: RouteTarget): RouteLocation\n push(to: RouteTarget): Promise<RouteLocation | false>\n replace(to: RouteTarget): Promise<RouteLocation | false>\n back(): void\n beforeEach(guard: NavigationGuard): () => void\n getViewState(route: RouteLocation): RouterViewState\n readonly devtools: RouterDevToolsAPI\n destroy(): void\n}\n\nexport interface RouterViewProps {\n readonly router?: Router\n /** 加载占位:JSX 属性经编译器编译为惰性 getter,手写对象字面量可传节点或工厂。 */\n readonly loading?: VobsNode | (() => VobsNode | null | undefined)\n readonly notFound?: (route: RouteLocation) => VobsNode | null | undefined\n readonly error?: (error: Error, retry: () => void) => VobsNode | null | undefined\n}\n\nexport interface RouterPluginOptions {\n readonly router?: Router\n readonly routes?: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport const ROUTER_KEY: InjectionKey<Router> = createInjectionKey<Router>('vobs.router')\n\nexport function lazy(loader: RouteComponentLoader): LazyRouteComponent {\n return {\n kind: 'vobs-lazy-route',\n load: loader\n }\n}\n\nexport function createMemoryHistory(initial = '/'): RouterHistory {\n let entries = [{ path: normalizeHistoryPath(initial), state: undefined as unknown }]\n let index = 0\n const listeners = new Set<(path: string, state: unknown) => void>()\n\n return {\n get location(): string {\n return entries[index]!.path\n },\n\n get state(): unknown {\n return entries[index]!.state\n },\n\n push(path: string, state?: unknown): void {\n const next = normalizeHistoryPath(path)\n entries = entries.slice(0, index + 1)\n entries.push({ path: next, state })\n index++\n },\n\n replace(path: string, state?: unknown): void {\n entries[index] = { path: normalizeHistoryPath(path), state }\n },\n\n back(): void {\n if (index === 0) return\n index--\n notifyListeners(listeners, entries[index]!.path, entries[index]!.state)\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n }\n}\n\nexport function createBrowserHistory(base = ''): RouterHistory {\n if (typeof window === 'undefined') {\n throw new Error('Vobs Router: createBrowserHistory 需要浏览器环境')\n }\n\n const normalizedBase = normalizeBase(base)\n const listeners = new Set<(path: string, state: unknown) => void>()\n const onPopState = (event: PopStateEvent): void => {\n notifyListeners(listeners, readBrowserLocation(normalizedBase), event.state)\n }\n\n return {\n get location(): string {\n return readBrowserLocation(normalizedBase)\n },\n\n get state(): unknown {\n return window.history.state\n },\n\n push(path: string, state?: unknown): void {\n window.history.pushState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n replace(path: string, state?: unknown): void {\n window.history.replaceState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n back(): void {\n window.history.back()\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n if (listeners.size === 0) window.addEventListener('popstate', onPopState)\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n if (listeners.size === 0) window.removeEventListener('popstate', onPopState)\n }\n }\n }\n}\n\nexport function createRouter(options: RouterOptions): Router {\n const matchers = normalizeRoutes(options.routes)\n const history = options.history ?? defaultHistory()\n const routerDebugId = createRouterDebugId()\n matchers.sort(compareMatchers)\n const currentRoute = state<RouteLocation>(resolvePath(history.location))\n const lazyStates = new Map<RouteRecord, LazyState>()\n const guards: NavigationGuard[] = []\n const navigationHistory: NavigationTrace[] = []\n const dataRequests: RouterDataRequestTrace[] = []\n const errors: RouteErrorTrace[] = []\n const dataLoaders = new Map<string, { kind: RouterDataRequestKind; route: string; task: () => unknown | PromiseLike<unknown> }>()\n const dataRequestContexts = new Map<number, RuntimeDebugContext>()\n const routerListeners = new Map<RouterDevToolsEvent, Set<(payload: unknown) => void>>()\n let navigationState: NavigationState = { status: 'idle', from: currentRoute.value.fullPath, to: currentRoute.value.fullPath }\n let navigationCount = 0\n let totalNavigationDuration = 0\n let slowNavigationCount = 0\n let nextDataRequestId = 1\n let nextErrorId = 1\n let navigationId = 0\n let destroyed = false\n const viewRevision = state(0)\n\n function resolve(to: RouteTarget): RouteLocation {\n ensureActive()\n const target = typeof to === 'string' ? parseTargetString(to) : normalizeTarget(to, matchers)\n return resolvePath(buildTargetPath(target.path, target.query, target.hash), target.state)\n }\n\n function resolvePath(rawPath: string, state?: unknown): RouteLocation {\n const parsed = parseTargetString(rawPath)\n const matched = matchers.find(matcher => matcher.regex.exec(parsed.path))\n const params = matched ? extractParams(matched, parsed.path) : {}\n const record = matched?.record ?? null\n const query = parsed.query\n const hash = parsed.hash\n return {\n path: parsed.path,\n fullPath: buildTargetPath(parsed.path, query, hash),\n params,\n query,\n hash,\n name: record?.name,\n meta: matched?.meta ?? {},\n record,\n matched: matched?.chain ?? EMPTY_MATCHED,\n state\n }\n }\n\n async function navigate(\n to: RouteTarget,\n replaceHistory: boolean,\n fromHistory: boolean,\n historyState?: unknown\n ): Promise<RouteLocation | false> {\n ensureActive()\n const id = ++navigationId\n const from = currentRoute.value\n let target = resolve(to)\n // popstate 回读的 state 保存在 history 条目上,不在目标描述里,这里回填。\n if (fromHistory && historyState !== undefined) target = { ...target, state: historyState }\n const source: NavigationTrace['source'] = fromHistory ? 'history' : replaceHistory ? 'replace' : 'push'\n const startedAt = now()\n const initialTarget = target.fullPath\n let terminalRecorded = false\n navigationState = { status: 'loading', from: from.fullPath, to: target.fullPath, traceId: id }\n emitRouter('navigation:start', navigationState)\n if (target.fullPath === from.fullPath && !fromHistory) {\n navigationState = { status: 'idle', from: from.fullPath, to: target.fullPath }\n return from\n }\n\n try {\n for (let redirectCount = 0; ; redirectCount++) {\n ensureNavigationIsCurrent(id)\n let redirect: RouteTarget | undefined\n for (const guard of [...guards]) {\n let result: NavigationGuardResult\n try {\n result = await guard(target, from)\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) throw reason\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw reason\n }\n ensureNavigationIsCurrent(id)\n if (result === false) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n return false\n }\n if (typeof result === 'string' || isRouteLocationRaw(result)) {\n redirect = result\n break\n }\n }\n\n for (const record of target.matched) {\n if (!record.loader) continue\n // 上一 loader 期间被新导航抢占时立即取消,跳过剩余 loader。\n ensureNavigationIsCurrent(id)\n await trackDataRequest(\n 'loader',\n `${target.fullPath}#${record.path ?? record.name ?? 'route'}`,\n context => record.loader!({ route: target, navigationId: id, dataRequestId: context.dataRequestId }),\n { route: target.fullPath, navigationId: id, trigger: 'navigation' }\n )\n }\n\n // loader 完成后、提交前必须重新校验:飞行期间被抢占的导航不允许覆盖 currentRoute 与 history。\n ensureNavigationIsCurrent(id)\n\n if (redirect !== undefined) {\n if (redirectCount >= 10) {\n const error = new NavigationRedirectError()\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw error\n }\n const redirected = resolve(redirect)\n if (redirected.fullPath === target.fullPath) return false\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'redirected', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: redirected.fullPath })\n target = redirected\n continue\n }\n\n if (target.fullPath === from.fullPath) return from\n if (!fromHistory) {\n if (replaceHistory) history.replace(target.fullPath, target.state)\n else history.push(target.fullPath, target.state)\n }\n currentRoute.value = target\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'success', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: target.fullPath !== initialTarget ? target.fullPath : undefined })\n terminalRecorded = true\n return target\n }\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n } else if (!terminalRecorded) {\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n }\n throw reason\n }\n }\n\n function now(): number {\n return typeof performance === 'undefined' ? Date.now() : performance.now()\n }\n\n function emitRouter(event: RouterDevToolsEvent, payload: unknown): void {\n for (const callback of routerListeners.get(event) ?? []) {\n try { callback(payload) } catch { /* diagnostics must not affect navigation */ }\n }\n emitRouterDebug(routerDebugId, event, payload, getRuntimeDebugContext() ?? undefined)\n }\n\n function recordNavigation(trace: NavigationTrace): void {\n navigationHistory.push(Object.freeze(trace))\n if (navigationHistory.length > 100) navigationHistory.shift()\n navigationCount++\n totalNavigationDuration += trace.duration\n if (trace.duration >= 16) slowNavigationCount++\n if (trace.id === navigationId) {\n navigationState = trace.status === 'error'\n ? { status: 'error', from: trace.from, to: trace.to, traceId: trace.id, error: trace.error }\n : { status: 'idle', from: trace.from, to: trace.to, traceId: trace.id }\n }\n emitRouter('navigation:end', trace)\n emitRouter('route:update', currentRoute.value)\n }\n\n async function trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: ((context: { readonly dataRequestId: number }) => T | PromiseLike<T>) | (() => T | PromiseLike<T>),\n optionsOrRoute: RouterDataRequestOptions | string = {}\n ): Promise<T> {\n ensureActive()\n const options = typeof optionsOrRoute === 'string' ? { route: optionsOrRoute } : optionsOrRoute\n const id = nextDataRequestId++\n const startedAt = now()\n const context = getRuntimeDebugContext()\n const route = options.route ?? currentRoute.value.fullPath\n const requestContext: RuntimeDebugContext = {\n ...context,\n environment: options.environment ?? context?.environment,\n route,\n navigationId: options.navigationId ?? context?.navigationId,\n dataRequestId: id,\n source: kind\n }\n const loading: RouterDataRequestTrace = {\n id,\n kind,\n key,\n route,\n status: 'loading',\n startedAt,\n navigationId: requestContext.navigationId,\n trigger: options.trigger,\n environment: requestContext.environment\n }\n dataRequests.push(loading)\n if (dataRequests.length > 100) dataRequests.shift()\n dataRequestContexts.set(id, requestContext)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', loading)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'start', trace: loading }, requestContext)\n dataLoaders.set(key, { kind, route, task: task as () => unknown | PromiseLike<unknown> })\n try {\n const result = await runWithRuntimeDebugContext(requestContext, () => (task as (context: { readonly dataRequestId: number }) => T | PromiseLike<T>)({ dataRequestId: id }))\n const endedAt = now()\n replaceDataRequest(id, { ...loading, status: 'success', endedAt, duration: endedAt - startedAt, result })\n return result\n } catch (reason) {\n const endedAt = now()\n const error = toError(reason)\n const status = isAbortError(reason) ? 'cancelled' : 'error'\n if (status === 'error') reportError(kind, error, route, { requestId: id, navigationId: requestContext.navigationId })\n replaceDataRequest(id, { ...loading, status, endedAt, duration: endedAt - startedAt, error: status === 'error' ? error.message : undefined })\n throw reason\n }\n }\n\n function replaceDataRequest(id: number, trace: RouterDataRequestTrace): void {\n const index = dataRequests.findIndex(item => item.id === id)\n if (index >= 0) dataRequests[index] = Object.freeze(trace)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', trace)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'end', trace }, dataRequestContexts.get(id))\n dataRequestContexts.delete(id)\n }\n\n function reportError(\n phase: RouteErrorTrace['phase'],\n reason: unknown,\n route = currentRoute.value.fullPath,\n context: { readonly requestId?: number; readonly navigationId?: number } = {}\n ): void {\n const error = toError(reason)\n errors.push(Object.freeze({\n id: nextErrorId++,\n phase,\n route,\n message: error.message,\n stack: error.stack,\n timestamp: now(),\n requestId: context.requestId,\n navigationId: context.navigationId\n }))\n if (errors.length > 100) errors.shift()\n emitRouter('error', errors[errors.length - 1]!)\n emitRouter('route:update', currentRoute.value)\n }\n\n function routeTree(): readonly RouteDebugNode[] {\n const statuses = new Map<string, LazyState['status']>()\n for (const matcher of matchers) {\n for (const record of matcher.chain) {\n if (record.component && isLazyRouteComponent(record.component)) {\n const debugId = routeDebugIds.get(record)\n if (debugId) statuses.set(debugId, lazyStates.get(record)?.status ?? 'loading')\n }\n }\n }\n return buildRouteDebugTree(options.routes, statuses)\n }\n\n function handleHistoryNavigation(path: string, state: unknown): void {\n void navigate(path, false, true, state).then(result => {\n if (destroyed) return\n if (result === false) {\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n } else if (result.fullPath !== normalizeHistoryPath(path)) {\n history.replace(result.fullPath, result.state)\n }\n }).catch(error => {\n if (!(error instanceof NavigationCancelledError) && !destroyed) {\n const current = currentRoute.value.fullPath\n const failed = toError(error)\n reportError('navigation', failed, normalizeHistoryPath(path))\n navigationState = { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message }\n emitRouter('navigation:end', { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message })\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n }\n })\n }\n\n const stopHistory = history.listen(handleHistoryNavigation)\n\n const router: Router = {\n currentRoute,\n history,\n\n resolve,\n\n push(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, false, false)\n },\n\n replace(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, true, false)\n },\n\n back(): void {\n ensureActive()\n history.back()\n },\n\n beforeEach(guard: NavigationGuard): () => void {\n ensureActive()\n guards.push(guard)\n return () => {\n const index = guards.indexOf(guard)\n if (index >= 0) guards.splice(index, 1)\n }\n },\n\n getViewState(route: RouteLocation): RouterViewState {\n viewRevision.value\n const records = route.matched.length > 0 ? route.matched : route.record ? [route.record] : []\n const entries = records\n .map(record => ({ record, definition: record.component }))\n .filter((entry): entry is { record: RouteRecord; definition: RouteComponentDefinition } =>\n isRouteComponentDefinition(entry.definition))\n if (!route.record || entries.length === 0) return { status: 'not-found', retry: () => undefined }\n\n const loaded: RouteComponent[] = []\n const lazyRecords: RouteRecord[] = []\n for (const entry of entries) {\n const { record, definition } = entry\n if (!isLazyRouteComponent(definition)) {\n loaded.push(definition)\n continue\n }\n lazyRecords.push(record)\n const lazyState = ensureLazyState(record, definition)\n if (lazyState.status === 'loading') return { status: 'loading', retry: () => retryLazyRoutes(lazyRecords) }\n if (lazyState.status === 'error') {\n return { status: 'error', error: lazyState.error, retry: () => retryLazyRoutes(lazyRecords) }\n }\n if (lazyState.component) loaded.push(lazyState.component)\n }\n\n const component = loaded[loaded.length - 1]\n if (!component) return { status: 'not-found', retry: () => undefined }\n return {\n status: 'ready',\n component,\n layouts: loaded.slice(0, -1),\n retry: () => retryLazyRoutes(lazyRecords)\n }\n },\n\n devtools: {\n getRouteTree: routeTree,\n getCurrentRoute: () => currentRoute.value,\n getNavigationState: () => navigationState,\n getNavigationHistory: () => [...navigationHistory],\n getPerformanceMetrics: () => ({\n navigationCount,\n averageNavigationDuration: navigationCount === 0 ? 0 : totalNavigationDuration / navigationCount,\n slowNavigationCount\n }),\n getDataRequests: () => [...dataRequests],\n getErrors: () => [...errors],\n trackDataRequest,\n runAction: (key, task) => trackDataRequest('action', key, task, { trigger: 'manual' }),\n runFetcher: (key, task) => trackDataRequest('fetcher', key, task, { trigger: 'manual' }),\n reportError,\n revalidate: async (route) => {\n await Promise.all([...dataLoaders.entries()]\n .filter(([, loader]) => loader.kind === 'loader' && (route === undefined || loader.route === route))\n .map(([key, loader]) => trackDataRequest(loader.kind, key, loader.task, { route: loader.route, trigger: 'revalidate' })))\n },\n subscribe(event, callback) {\n let listeners = routerListeners.get(event)\n if (!listeners) { listeners = new Set(); routerListeners.set(event, listeners) }\n listeners.add(callback)\n return () => listeners?.delete(callback)\n }\n },\n\n destroy(): void {\n if (destroyed) return\n destroyed = true\n navigationId++\n stopHistory()\n guards.length = 0\n routerListeners.clear()\n lazyStates.clear()\n errors.length = 0\n dataRequestContexts.clear()\n currentRoute.dispose()\n viewRevision.dispose()\n }\n }\n\n function ensureLazyState(record: RouteRecord, definition: LazyRouteComponent): LazyState {\n let lazyState = lazyStates.get(record)\n if (!lazyState) {\n lazyState = { status: 'loading' }\n lazyStates.set(record, lazyState)\n void loadRouteComponent(definition).then(component => {\n if (destroyed) return\n lazyState!.status = 'ready'\n lazyState!.component = component\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n }).catch(reason => {\n if (destroyed) return\n lazyState!.status = 'error'\n lazyState!.error = toError(reason)\n reportError('lazy', reason, currentRoute.value.fullPath)\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n })\n }\n return lazyState\n }\n\n function retryLazyRoutes(records: readonly RouteRecord[]): void {\n for (const record of records) lazyStates.delete(record)\n viewRevision.value++\n }\n\n function ensureActive(): void {\n if (destroyed) throw new Error('Vobs Router: 已销毁的 Router 不能继续使用')\n }\n\n function ensureNavigationIsCurrent(id: number): void {\n if (id !== navigationId) throw new NavigationCancelledError()\n }\n\n return router\n}\n\nexport function RouterView(props: RouterViewProps = {}): VobsNode {\n const router = props.router ?? inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: RouterView 找不到 Router,请安装 routerPlugin')\n\n return createFragment((parent, anchor) => {\n let routeRetry: () => void = () => undefined\n insertBoundary(parent, anchor, {\n resetKey: () => router.currentRoute.value.fullPath,\n onRetry: () => routeRetry(),\n fallback: (error, retry) => {\n router.devtools.reportError('render', error, router.currentRoute.value.fullPath)\n return props.error?.(error, () => { void retry() }) ?? null\n },\n children: () => {\n const route = router.currentRoute.value\n const view = router.getViewState(route)\n routeRetry = view.retry\n if (view.status === 'loading') {\n return (typeof props.loading === 'function' ? props.loading() : props.loading) ?? null\n }\n if (view.status === 'not-found') return props.notFound?.(route) ?? null\n if (view.status === 'error') {\n throw view.error ?? new Error('路由组件加载失败')\n }\n if (!view.component) return null\n let node = createComponent(view.component, {\n route,\n params: route.params,\n query: route.query\n })\n for (let index = (view.layouts?.length ?? 0) - 1; index >= 0; index--) {\n node = createComponent(view.layouts![index]!, {\n route,\n params: route.params,\n query: route.query,\n children: node\n })\n }\n return node\n }})\n })\n}\n\nexport function useRouter(): Router {\n const router = inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: useRouter 找不到 Router,请安装 routerPlugin')\n return router\n}\n\nexport function useRoute(): Signal<RouteLocation> {\n return useRouter().currentRoute\n}\n\nexport function routerPlugin(options: RouterPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/router',\n version: '0.1.0',\n install(context) {\n const ownedRouter = options.router ? undefined : createRouter({\n routes: options.routes ?? [],\n history: options.history\n })\n const router = options.router ?? ownedRouter!\n context.provide(ROUTER_KEY, router)\n return () => ownedRouter?.destroy()\n }\n }\n}\n\ninterface RouteMatcher {\n readonly record: RouteRecord\n readonly debugId: string\n readonly chain: readonly RouteRecord[]\n readonly meta: RouteMeta\n readonly regex: RegExp\n readonly keys: readonly string[]\n readonly score: number\n readonly order: number\n}\n\ninterface LazyState {\n status: 'loading' | 'ready' | 'error'\n component?: RouteComponent\n error?: Error\n}\n\ninterface ParsedTarget {\n readonly path: string\n readonly query: RouteQuery\n readonly hash: string\n readonly state?: unknown\n}\n\nfunction defaultHistory(): RouterHistory {\n return typeof window === 'undefined' ? createMemoryHistory('/') : createBrowserHistory()\n}\n\nconst EMPTY_MATCHED: readonly RouteRecord[] = Object.freeze([])\nconst routeDebugIds = new WeakMap<RouteRecord, string>()\n\nfunction buildRouteDebugTree(routes: readonly RouteRecord[], lazyStatuses: ReadonlyMap<string, LazyState['status']> = new Map()): readonly RouteDebugNode[] {\n const visit = (records: readonly RouteRecord[], parentPath: string, parentId: string): RouteDebugNode[] => records.map((record, index) => {\n const path = record.path === undefined ? parentPath || '/' : resolveChildPath(parentPath, record.path)\n const id = `${parentId}.${index}`\n const definition = record.component\n const lazyDefinition = definition !== undefined && isLazyRouteComponent(definition)\n const componentName = definition === undefined\n ? 'Route'\n : lazyDefinition\n ? 'lazy(...)'\n : typeof definition === 'function'\n ? definition.name || 'Anonymous'\n : 'Route'\n return {\n id,\n path,\n name: record.name,\n component: componentName,\n source: record.source,\n lazy: lazyDefinition,\n loader: record.loader !== undefined,\n action: record.action !== undefined,\n status: lazyDefinition ? (lazyStatuses.get(id) ?? 'loading') : 'ready',\n meta: Object.freeze({ ...(record.meta ?? {}) }),\n children: visit(record.children ?? [], path, id)\n }\n })\n return Object.freeze(visit(routes, '', 'route'))\n}\n\nfunction normalizeRoutes(routes: readonly RouteRecord[]): RouteMatcher[] {\n const matchers: RouteMatcher[] = []\n let order = 0\n\n function visit(records: readonly RouteRecord[], parentPath: string, parentChain: readonly RouteRecord[], parentMeta: RouteMeta, parentId = 'route'): void {\n records.forEach((record, index) => {\n const debugId = `${parentId}.${index}`\n const children = record.children ?? []\n const path = record.path === undefined\n ? parentPath\n : resolveChildPath(parentPath, record.path)\n const normalized: RouteRecord = {\n ...record,\n path: record.path === undefined\n ? (children.length > 0 ? undefined : (path || '/'))\n : path,\n meta: record.meta ? { ...record.meta } : {}\n }\n routeDebugIds.set(normalized, debugId)\n const chain = [...parentChain, normalized]\n const meta = Object.freeze({ ...parentMeta, ...(normalized.meta ?? {}) })\n if (children.length > 0) {\n visit(children, path, chain, meta, debugId)\n } else if (normalized.component) {\n matchers.push(createMatcher(normalized, chain, meta, order++, debugId))\n } else if (normalized.path === undefined) {\n throw new Error(`Vobs Router: 第 ${index + 1} 个路由缺少 path 或 children`)\n }\n })\n }\n\n visit(routes, '', [], {})\n return matchers\n}\n\nfunction resolveChildPath(parentPath: string, childPath: string): string {\n const normalizedChild = normalizePath(childPath)\n if (!parentPath || normalizedChild === '/') return normalizedChild === '/' ? (parentPath || '/') : normalizedChild\n if (childPath.startsWith('/')) return normalizedChild\n return normalizePath(`${parentPath}/${childPath}`)\n}\n\nfunction createMatcher(record: RouteRecord, chain: readonly RouteRecord[], meta: RouteMeta, order: number, debugId: string): RouteMatcher {\n const path = record.path ?? '/'\n const segments = path === '/' ? [] : path.slice(1).split('/')\n const keys: string[] = []\n let score = 0\n const pattern = segments.map(segment => {\n if (segment === '*') {\n keys.push('pathMatch')\n return '(.*)'\n }\n if (segment.startsWith(':')) {\n const key = segment.slice(1)\n if (!key) throw new Error(`Vobs Router: 路由 ${path} 的参数名不能为空`)\n if (keys.includes(key)) throw new Error(`Vobs Router: 路由 ${path} 存在重复参数 ${key}`)\n keys.push(key)\n score += 1\n return '([^/]+)'\n }\n score += 3\n return escapeRegExp(segment)\n }).join('/')\n\n return {\n record,\n debugId,\n chain: Object.freeze([...chain]),\n meta,\n regex: new RegExp(segments.length === 0 ? '^/?$' : `^/${pattern}/?$`),\n keys,\n score,\n order\n }\n}\n\nfunction compareMatchers(left: RouteMatcher, right: RouteMatcher): number {\n return right.score - left.score || left.order - right.order\n}\n\nfunction extractParams(matcher: RouteMatcher, path: string): RouteParams {\n const match = matcher.regex.exec(path)\n if (!match) return {}\n const params: Record<string, string> = {}\n matcher.keys.forEach((key, index) => {\n params[key] = decodeRoutePart(match[index + 1] ?? '')\n })\n return Object.freeze(params)\n}\n\nfunction parseTargetString(raw: string): ParsedTarget {\n const hashIndex = raw.indexOf('#')\n const hash = hashIndex >= 0 ? normalizeHash(raw.slice(hashIndex + 1)) : ''\n const withoutHash = hashIndex >= 0 ? raw.slice(0, hashIndex) : raw\n const queryIndex = withoutHash.indexOf('?')\n const path = normalizePath(queryIndex >= 0 ? withoutHash.slice(0, queryIndex) : withoutHash)\n const query = queryIndex >= 0 ? parseQuery(withoutHash.slice(queryIndex + 1)) : {}\n return { path, query, hash }\n}\n\nfunction normalizeTarget(target: RouteLocationRaw, matchers: readonly RouteMatcher[]): ParsedTarget {\n let path = target.path\n if (!path && target.name) {\n const matcher = matchers.find(candidate => candidate.record.name === target.name)\n if (!matcher) throw new Error(`Vobs Router: 找不到名为 ${target.name} 的路由`)\n path = fillRouteParams(matcher.record.path ?? '/', target.params ?? {})\n }\n if (!path) throw new Error('Vobs Router: 导航目标必须提供 path 或 name')\n\n const parsed = parseTargetString(path)\n const filledPath = fillRouteParams(parsed.path, target.params ?? {})\n const query = target.query === undefined ? parsed.query : normalizeQuery(target.query)\n const hash = target.hash === undefined ? parsed.hash : normalizeHash(target.hash)\n return { path: filledPath, query, hash, state: target.state }\n}\n\nfunction fillRouteParams(path: string, params: Record<string, unknown>): string {\n return path.replace(/:([A-Za-z0-9_]+)|\\*/g, (token, key: string | undefined) => {\n const value = key ? params[key] : params.pathMatch\n if (value === undefined || value === null) return token\n return encodeURIComponent(String(value))\n })\n}\n\nfunction buildTargetPath(path: string, query: RouteQuery, hash: string): string {\n const params = new URLSearchParams()\n for (const key of Object.keys(query).sort()) {\n const value = query[key]\n if (typeof value === 'string') {\n params.set(key, value)\n } else {\n for (const item of value) params.append(key, item)\n }\n }\n const serialized = params.toString()\n return `${path}${serialized ? `?${serialized}` : ''}${hash}`\n}\n\nfunction parseQuery(raw: string): RouteQuery {\n const params = new URLSearchParams(raw)\n const result: Record<string, RouteQueryValue> = {}\n params.forEach((value, key) => {\n const previous = result[key]\n if (previous === undefined) result[key] = value\n else if (typeof previous === 'string') result[key] = [previous, value]\n else result[key] = [...previous, value]\n })\n for (const key of Object.keys(result)) {\n if (Array.isArray(result[key])) result[key] = Object.freeze(result[key] as string[])\n }\n return Object.freeze(result)\n}\n\nfunction normalizeQuery(input: RouteQueryInput): RouteQuery {\n if (input instanceof URLSearchParams) return parseQuery(input.toString())\n const result: Record<string, RouteQueryValue> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) result[key] = Object.freeze(value.map(item => String(item)))\n else result[key] = String(value)\n }\n return Object.freeze(result)\n}\n\nfunction normalizePath(path: string): string {\n if (!path) return '/'\n const withoutQuery = path.split(/[?#]/, 1)[0] || '/'\n const withLeadingSlash = withoutQuery.startsWith('/') ? withoutQuery : `/${withoutQuery}`\n if (withLeadingSlash === '/*' || withLeadingSlash === '/') return withLeadingSlash\n return withLeadingSlash.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/'\n}\n\nfunction normalizeHistoryPath(path: string): string {\n const parsed = parseTargetString(path)\n return buildTargetPath(parsed.path, parsed.query, parsed.hash)\n}\n\nfunction normalizeHash(hash: string): string {\n if (!hash) return ''\n return hash.startsWith('#') ? hash : `#${hash}`\n}\n\nfunction normalizeBase(base: string): string {\n if (!base || base === '/') return ''\n return `/${base.replace(/^\\/+|\\/+$/g, '')}`\n}\n\nfunction readBrowserLocation(base: string): string {\n const pathname = window.location.pathname\n const path = base && (pathname === base || pathname.startsWith(`${base}/`))\n ? pathname.slice(base.length) || '/'\n : pathname\n return normalizeHistoryPath(`${path}${window.location.search}${window.location.hash}`)\n}\n\nfunction withBase(path: string, base: string): string {\n return `${base}${path === '/' ? '/' : path}` || '/'\n}\n\nfunction notifyListeners(listeners: Set<(path: string, state: unknown) => void>, path: string, state: unknown): void {\n for (const listener of [...listeners]) listener(path, state)\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction decodeRoutePart(value: string): string {\n try {\n return decodeURIComponent(value)\n } catch {\n return value\n }\n}\n\nfunction isLazyRouteComponent(value: RouteComponentDefinition): value is LazyRouteComponent {\n return typeof value === 'object' && value !== null && value.kind === 'vobs-lazy-route'\n}\n\nfunction isRouteComponentDefinition(value: unknown): value is RouteComponentDefinition {\n return typeof value === 'function' || isLazyRouteComponent(value as RouteComponentDefinition)\n}\n\nasync function loadRouteComponent(loader: LazyRouteComponent): Promise<RouteComponent> {\n const module = await loader.load()\n const component = typeof module === 'function' ? module : module.default\n if (typeof component !== 'function') throw new Error('Vobs Router: 懒加载模块没有默认组件导出')\n return component\n}\n\nfunction isRouteLocationRaw(value: unknown): value is RouteLocationRaw {\n return Boolean(value) && typeof value === 'object'\n}\n\nfunction toError(reason: unknown): Error {\n return reason instanceof Error ? reason : new Error(String(reason))\n}\n\nfunction isAbortError(reason: unknown): boolean {\n return Boolean(reason) && typeof reason === 'object'\n && ((reason as { readonly name?: unknown }).name === 'AbortError'\n || (reason as { readonly code?: unknown }).code === 'ERR_CANCELED')\n}\n","import type { RuntimeDebugContext } from '@vobs/runtime'\n\nexport type RouterDebugEventType =\n | 'navigation:start'\n | 'navigation:end'\n | 'route:update'\n | 'data-request'\n | 'error'\n\nexport interface RouterDebugEvent {\n readonly routerId: string\n readonly type: RouterDebugEventType\n readonly payload: unknown\n readonly context?: RuntimeDebugContext\n}\n\ntype RouterDebugListener = (event: RouterDebugEvent) => void\n\nconst listeners = new Set<RouterDebugListener>()\nlet nextRouterId = 1\n\nexport function createRouterDebugId(): string {\n return `router-${nextRouterId++}`\n}\n\nexport function subscribeRouterDebug(listener: RouterDebugListener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nexport function emitRouterDebug(\n routerId: string,\n type: RouterDebugEventType,\n payload: unknown,\n context?: RuntimeDebugContext\n): void {\n const event: RouterDebugEvent = { routerId, type, payload, context }\n for (const listener of [...listeners]) {\n try { listener(event) } catch { /* diagnostics must not affect navigation */ }\n }\n}\n"],"mappings":";;;;AAAA,SAAS,aAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;;;ACQP,IAAM,YAAY,oBAAI,IAAyB;AAC/C,IAAI,eAAe;AAEZ,SAAS,sBAA8B;AAC5C,SAAO,UAAU,cAAc;AACjC;AAFgB;AAIT,SAAS,qBAAqB,UAA2C;AAC9E,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM,UAAU,OAAO,QAAQ;AACxC;AAHgB;AAKT,SAAS,gBACd,UACA,MACA,SACA,SACM;AACN,QAAM,QAA0B,EAAE,UAAU,MAAM,SAAS,QAAQ;AACnE,aAAW,YAAY,CAAC,GAAG,SAAS,GAAG;AACrC,QAAI;AAAE,eAAS,KAAK;AAAA,IAAE,QAAQ;AAAA,IAA+C;AAAA,EAC/E;AACF;AAVgB;;;ADfhB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AA+EA,IAAM,4BAAN,MAAM,kCAAiC,MAAM;AAAA,EAGlD,cAAc;AACZ,UAAM,iFAA0B;AAHlC,SAAS,OAAO;AAId,SAAK,OAAO;AAAA,EACd;AACF;AAPoD;AAA7C,IAAM,2BAAN;AASA,IAAM,2BAAN,MAAM,iCAAgC,MAAM;AAAA,EAGjD,cAAc;AACZ,UAAM,iFAA0B;AAHlC,SAAS,OAAO;AAId,SAAK,OAAO;AAAA,EACd;AACF;AAPmD;AAA5C,IAAM,0BAAN;AA+JA,IAAM,aAAmC,mBAA2B,aAAa;AAEjF,SAAS,KAAK,QAAkD;AACrE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACF;AALgB;AAOT,SAAS,oBAAoB,UAAU,KAAoB;AAChE,MAAI,UAAU,CAAC,EAAE,MAAM,qBAAqB,OAAO,GAAG,OAAO,OAAqB,CAAC;AACnF,MAAI,QAAQ;AACZ,QAAMA,aAAY,oBAAI,IAA4C;AAElE,SAAO;AAAA,IACL,IAAI,WAAmB;AACrB,aAAO,QAAQ,KAAK,EAAG;AAAA,IACzB;AAAA,IAEA,IAAI,QAAiB;AACnB,aAAO,QAAQ,KAAK,EAAG;AAAA,IACzB;AAAA,IAEA,KAAK,MAAcC,QAAuB;AACxC,YAAM,OAAO,qBAAqB,IAAI;AACtC,gBAAU,QAAQ,MAAM,GAAG,QAAQ,CAAC;AACpC,cAAQ,KAAK,EAAE,MAAM,MAAM,OAAAA,OAAM,CAAC;AAClC;AAAA,IACF;AAAA,IAEA,QAAQ,MAAcA,QAAuB;AAC3C,cAAQ,KAAK,IAAI,EAAE,MAAM,qBAAqB,IAAI,GAAG,OAAAA,OAAM;AAAA,IAC7D;AAAA,IAEA,OAAa;AACX,UAAI,UAAU,EAAG;AACjB;AACA,sBAAgBD,YAAW,QAAQ,KAAK,EAAG,MAAM,QAAQ,KAAK,EAAG,KAAK;AAAA,IACxE;AAAA,IAEA,OAAO,UAA8D;AACnE,MAAAA,WAAU,IAAI,QAAQ;AACtB,aAAO,MAAMA,WAAU,OAAO,QAAQ;AAAA,IACxC;AAAA,EACF;AACF;AApCgB;AAsCT,SAAS,qBAAqB,OAAO,IAAmB;AAC7D,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,MAAM,8EAA2C;AAAA,EAC7D;AAEA,QAAM,iBAAiB,cAAc,IAAI;AACzC,QAAMA,aAAY,oBAAI,IAA4C;AAClE,QAAM,aAAa,wBAAC,UAA+B;AACjD,oBAAgBA,YAAW,oBAAoB,cAAc,GAAG,MAAM,KAAK;AAAA,EAC7E,GAFmB;AAInB,SAAO;AAAA,IACL,IAAI,WAAmB;AACrB,aAAO,oBAAoB,cAAc;AAAA,IAC3C;AAAA,IAEA,IAAI,QAAiB;AACnB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAAA,IAEA,KAAK,MAAcC,QAAuB;AACxC,aAAO,QAAQ,UAAUA,UAAS,MAAM,IAAI,SAAS,qBAAqB,IAAI,GAAG,cAAc,CAAC;AAAA,IAClG;AAAA,IAEA,QAAQ,MAAcA,QAAuB;AAC3C,aAAO,QAAQ,aAAaA,UAAS,MAAM,IAAI,SAAS,qBAAqB,IAAI,GAAG,cAAc,CAAC;AAAA,IACrG;AAAA,IAEA,OAAa;AACX,aAAO,QAAQ,KAAK;AAAA,IACtB;AAAA,IAEA,OAAO,UAA8D;AACnE,UAAID,WAAU,SAAS,EAAG,QAAO,iBAAiB,YAAY,UAAU;AACxE,MAAAA,WAAU,IAAI,QAAQ;AACtB,aAAO,MAAM;AACX,QAAAA,WAAU,OAAO,QAAQ;AACzB,YAAIA,WAAU,SAAS,EAAG,QAAO,oBAAoB,YAAY,UAAU;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AACF;AAzCgB;AA2CT,SAAS,aAAa,SAAgC;AAC3D,QAAM,WAAW,gBAAgB,QAAQ,MAAM;AAC/C,QAAM,UAAU,QAAQ,WAAW,eAAe;AAClD,QAAM,gBAAgB,oBAAoB;AAC1C,WAAS,KAAK,eAAe;AAC7B,QAAM,eAAe,MAAqB,YAAY,QAAQ,QAAQ,CAAC;AACvE,QAAM,aAAa,oBAAI,IAA4B;AACnD,QAAM,SAA4B,CAAC;AACnC,QAAM,oBAAuC,CAAC;AAC9C,QAAM,eAAyC,CAAC;AAChD,QAAM,SAA4B,CAAC;AACnC,QAAM,cAAc,oBAAI,IAAwG;AAChI,QAAM,sBAAsB,oBAAI,IAAiC;AACjE,QAAM,kBAAkB,oBAAI,IAA0D;AACtF,MAAI,kBAAmC,EAAE,QAAQ,QAAQ,MAAM,aAAa,MAAM,UAAU,IAAI,aAAa,MAAM,SAAS;AAC5H,MAAI,kBAAkB;AACtB,MAAI,0BAA0B;AAC9B,MAAI,sBAAsB;AAC1B,MAAI,oBAAoB;AACxB,MAAI,cAAc;AAClB,MAAI,eAAe;AACnB,MAAI,YAAY;AAChB,QAAM,eAAe,MAAM,CAAC;AAE5B,WAAS,QAAQ,IAAgC;AAC/C,iBAAa;AACb,UAAM,SAAS,OAAO,OAAO,WAAW,kBAAkB,EAAE,IAAI,gBAAgB,IAAI,QAAQ;AAC5F,WAAO,YAAY,gBAAgB,OAAO,MAAM,OAAO,OAAO,OAAO,IAAI,GAAG,OAAO,KAAK;AAAA,EAC1F;AAJS;AAMT,WAAS,YAAY,SAAiBC,QAAgC;AACpE,UAAM,SAAS,kBAAkB,OAAO;AACxC,UAAM,UAAU,SAAS,KAAK,aAAW,QAAQ,MAAM,KAAK,OAAO,IAAI,CAAC;AACxE,UAAM,SAAS,UAAU,cAAc,SAAS,OAAO,IAAI,IAAI,CAAC;AAChE,UAAM,SAAS,SAAS,UAAU;AAClC,UAAM,QAAQ,OAAO;AACrB,UAAM,OAAO,OAAO;AACpB,WAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,UAAU,gBAAgB,OAAO,MAAM,OAAO,IAAI;AAAA,MAClD;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,QAAQ;AAAA,MACd,MAAM,SAAS,QAAQ,CAAC;AAAA,MACxB;AAAA,MACA,SAAS,SAAS,SAAS;AAAA,MAC3B,OAAAA;AAAA,IACF;AAAA,EACF;AAnBS;AAqBT,iBAAe,SACb,IACA,gBACA,aACA,cACgC;AAChC,iBAAa;AACb,UAAM,KAAK,EAAE;AACb,UAAM,OAAO,aAAa;AAC1B,QAAI,SAAS,QAAQ,EAAE;AAEvB,QAAI,eAAe,iBAAiB,OAAW,UAAS,EAAE,GAAG,QAAQ,OAAO,aAAa;AACzF,UAAM,SAAoC,cAAc,YAAY,iBAAiB,YAAY;AACjG,UAAM,YAAY,IAAI;AACtB,UAAM,gBAAgB,OAAO;AAC7B,QAAI,mBAAmB;AACvB,sBAAkB,EAAE,QAAQ,WAAW,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,SAAS,GAAG;AAC7F,eAAW,oBAAoB,eAAe;AAC9C,QAAI,OAAO,aAAa,KAAK,YAAY,CAAC,aAAa;AACrD,wBAAkB,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,IAAI,OAAO,SAAS;AAC7E,aAAO;AAAA,IACT;AAEA,QAAI;AACF,eAAS,gBAAgB,KAAK,iBAAiB;AAC7C,kCAA0B,EAAE;AAC5B,YAAI;AACJ,mBAAW,SAAS,CAAC,GAAG,MAAM,GAAG;AAC/B,cAAI;AACJ,cAAI;AACF,qBAAS,MAAM,MAAM,QAAQ,IAAI;AAAA,UACnC,SAAS,QAAQ;AACf,gBAAI,kBAAkB,yBAA0B,OAAM;AACtD,kBAAM,QAAQ,QAAQ,MAAM;AAC5B,wBAAY,cAAc,OAAO,OAAO,QAAQ;AAChD,6BAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,SAAS,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,WAAW,OAAO,MAAM,QAAQ,CAAC;AACxK,+BAAmB;AACnB,kBAAM;AAAA,UACR;AACA,oCAA0B,EAAE;AAC5B,cAAI,WAAW,OAAO;AACpB,6BAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,aAAa,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,UAAU,CAAC;AACtJ,+BAAmB;AACnB,mBAAO;AAAA,UACT;AACA,cAAI,OAAO,WAAW,YAAY,mBAAmB,MAAM,GAAG;AAC5D,uBAAW;AACX;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,UAAU,OAAO,SAAS;AACnC,cAAI,CAAC,OAAO,OAAQ;AAEpB,oCAA0B,EAAE;AAC5B,gBAAM;AAAA,YACJ;AAAA,YACA,GAAG,OAAO,QAAQ,IAAI,OAAO,QAAQ,OAAO,QAAQ,OAAO;AAAA,YAC3D,aAAW,OAAO,OAAQ,EAAE,OAAO,QAAQ,cAAc,IAAI,eAAe,QAAQ,cAAc,CAAC;AAAA,YACnG,EAAE,OAAO,OAAO,UAAU,cAAc,IAAI,SAAS,aAAa;AAAA,UACpE;AAAA,QACF;AAGA,kCAA0B,EAAE;AAE5B,YAAI,aAAa,QAAW;AAC1B,cAAI,iBAAiB,IAAI;AACvB,kBAAM,QAAQ,IAAI,wBAAwB;AAC1C,6BAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,SAAS,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,WAAW,OAAO,MAAM,QAAQ,CAAC;AACxK,+BAAmB;AACnB,kBAAM;AAAA,UACR;AACA,gBAAM,aAAa,QAAQ,QAAQ;AACnC,cAAI,WAAW,aAAa,OAAO,SAAU,QAAO;AACpD,2BAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,cAAc,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,WAAW,UAAU,WAAW,SAAS,CAAC;AACtL,mBAAS;AACT;AAAA,QACF;AAEA,YAAI,OAAO,aAAa,KAAK,SAAU,QAAO;AAC9C,YAAI,CAAC,aAAa;AAChB,cAAI,eAAgB,SAAQ,QAAQ,OAAO,UAAU,OAAO,KAAK;AAAA,cAC5D,SAAQ,KAAK,OAAO,UAAU,OAAO,KAAK;AAAA,QACjD;AACA,qBAAa,QAAQ;AACrB,yBAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,WAAW,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,WAAW,UAAU,OAAO,aAAa,gBAAgB,OAAO,WAAW,OAAU,CAAC;AAC/N,2BAAmB;AACnB,eAAO;AAAA,MACT;AAAA,IACF,SAAS,QAAQ;AACf,UAAI,kBAAkB,0BAA0B;AAC9C,yBAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,aAAa,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,UAAU,CAAC;AACtJ,2BAAmB;AAAA,MACrB,WAAW,CAAC,kBAAkB;AAC5B,cAAM,QAAQ,QAAQ,MAAM;AAC5B,oBAAY,cAAc,OAAO,OAAO,QAAQ;AAChD,yBAAiB,EAAE,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,UAAU,QAAQ,SAAS,QAAQ,WAAW,SAAS,IAAI,GAAG,UAAU,IAAI,IAAI,WAAW,OAAO,MAAM,QAAQ,CAAC;AACxK,2BAAmB;AAAA,MACrB;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAtGe;AAwGf,WAAS,MAAc;AACrB,WAAO,OAAO,gBAAgB,cAAc,KAAK,IAAI,IAAI,YAAY,IAAI;AAAA,EAC3E;AAFS;AAIT,WAAS,WAAW,OAA4B,SAAwB;AACtE,eAAW,YAAY,gBAAgB,IAAI,KAAK,KAAK,CAAC,GAAG;AACvD,UAAI;AAAE,iBAAS,OAAO;AAAA,MAAE,QAAQ;AAAA,MAA+C;AAAA,IACjF;AACA,oBAAgB,eAAe,OAAO,SAAS,uBAAuB,KAAK,MAAS;AAAA,EACtF;AALS;AAOT,WAAS,iBAAiB,OAA8B;AACtD,sBAAkB,KAAK,OAAO,OAAO,KAAK,CAAC;AAC3C,QAAI,kBAAkB,SAAS,IAAK,mBAAkB,MAAM;AAC5D;AACA,+BAA2B,MAAM;AACjC,QAAI,MAAM,YAAY,GAAI;AAC1B,QAAI,MAAM,OAAO,cAAc;AAC7B,wBAAkB,MAAM,WAAW,UAC/B,EAAE,QAAQ,SAAS,MAAM,MAAM,MAAM,IAAI,MAAM,IAAI,SAAS,MAAM,IAAI,OAAO,MAAM,MAAM,IACzF,EAAE,QAAQ,QAAQ,MAAM,MAAM,MAAM,IAAI,MAAM,IAAI,SAAS,MAAM,GAAG;AAAA,IAC1E;AACA,eAAW,kBAAkB,KAAK;AAClC,eAAW,gBAAgB,aAAa,KAAK;AAAA,EAC/C;AAbS;AAeT,iBAAe,iBACb,MACA,KACA,MACA,iBAAoD,CAAC,GACzC;AACZ,iBAAa;AACb,UAAMC,WAAU,OAAO,mBAAmB,WAAW,EAAE,OAAO,eAAe,IAAI;AACjF,UAAM,KAAK;AACX,UAAM,YAAY,IAAI;AACtB,UAAM,UAAU,uBAAuB;AACvC,UAAM,QAAQA,SAAQ,SAAS,aAAa,MAAM;AAClD,UAAM,iBAAsC;AAAA,MAC1C,GAAG;AAAA,MACH,aAAaA,SAAQ,eAAe,SAAS;AAAA,MAC7C;AAAA,MACA,cAAcA,SAAQ,gBAAgB,SAAS;AAAA,MAC/C,eAAe;AAAA,MACf,QAAQ;AAAA,IACV;AACA,UAAM,UAAkC;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,cAAc,eAAe;AAAA,MAC7B,SAASA,SAAQ;AAAA,MACjB,aAAa,eAAe;AAAA,IAC9B;AACA,iBAAa,KAAK,OAAO;AACzB,QAAI,aAAa,SAAS,IAAK,cAAa,MAAM;AAClD,wBAAoB,IAAI,IAAI,cAAc;AAC1C,eAAW,gBAAgB,aAAa,KAAK;AAC7C,eAAW,gBAAgB,OAAO;AAClC,oBAAgB,eAAe,gBAAgB,EAAE,OAAO,SAAS,OAAO,QAAQ,GAAG,cAAc;AACjG,gBAAY,IAAI,KAAK,EAAE,MAAM,OAAO,KAAmD,CAAC;AACxF,QAAI;AACF,YAAM,SAAS,MAAM,2BAA2B,gBAAgB,MAAO,KAA6E,EAAE,eAAe,GAAG,CAAC,CAAC;AAC1K,YAAM,UAAU,IAAI;AACpB,yBAAmB,IAAI,EAAE,GAAG,SAAS,QAAQ,WAAW,SAAS,UAAU,UAAU,WAAW,OAAO,CAAC;AACxG,aAAO;AAAA,IACT,SAAS,QAAQ;AACf,YAAM,UAAU,IAAI;AACpB,YAAM,QAAQ,QAAQ,MAAM;AAC5B,YAAM,SAAS,aAAa,MAAM,IAAI,cAAc;AACpD,UAAI,WAAW,QAAS,aAAY,MAAM,OAAO,OAAO,EAAE,WAAW,IAAI,cAAc,eAAe,aAAa,CAAC;AACpH,yBAAmB,IAAI,EAAE,GAAG,SAAS,QAAQ,SAAS,UAAU,UAAU,WAAW,OAAO,WAAW,UAAU,MAAM,UAAU,OAAU,CAAC;AAC5I,YAAM;AAAA,IACR;AAAA,EACF;AAnDe;AAqDf,WAAS,mBAAmB,IAAY,OAAqC;AAC3E,UAAM,QAAQ,aAAa,UAAU,UAAQ,KAAK,OAAO,EAAE;AAC3D,QAAI,SAAS,EAAG,cAAa,KAAK,IAAI,OAAO,OAAO,KAAK;AACzD,eAAW,gBAAgB,aAAa,KAAK;AAC7C,eAAW,gBAAgB,KAAK;AAChC,oBAAgB,eAAe,gBAAgB,EAAE,OAAO,OAAO,MAAM,GAAG,oBAAoB,IAAI,EAAE,CAAC;AACnG,wBAAoB,OAAO,EAAE;AAAA,EAC/B;AAPS;AAST,WAAS,YACP,OACA,QACA,QAAQ,aAAa,MAAM,UAC3B,UAA2E,CAAC,GACtE;AACN,UAAM,QAAQ,QAAQ,MAAM;AAC5B,WAAO,KAAK,OAAO,OAAO;AAAA,MACxB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,WAAW,IAAI;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ;AAAA,IACxB,CAAC,CAAC;AACF,QAAI,OAAO,SAAS,IAAK,QAAO,MAAM;AACtC,eAAW,SAAS,OAAO,OAAO,SAAS,CAAC,CAAE;AAC9C,eAAW,gBAAgB,aAAa,KAAK;AAAA,EAC/C;AApBS;AAsBT,WAAS,YAAuC;AAC9C,UAAM,WAAW,oBAAI,IAAiC;AACtD,eAAW,WAAW,UAAU;AAC9B,iBAAW,UAAU,QAAQ,OAAO;AAClC,YAAI,OAAO,aAAa,qBAAqB,OAAO,SAAS,GAAG;AAC9D,gBAAM,UAAU,cAAc,IAAI,MAAM;AACxC,cAAI,QAAS,UAAS,IAAI,SAAS,WAAW,IAAI,MAAM,GAAG,UAAU,SAAS;AAAA,QAChF;AAAA,MACF;AAAA,IACF;AACA,WAAO,oBAAoB,QAAQ,QAAQ,QAAQ;AAAA,EACrD;AAXS;AAaT,WAAS,wBAAwB,MAAcD,QAAsB;AACnE,SAAK,SAAS,MAAM,OAAO,MAAMA,MAAK,EAAE,KAAK,YAAU;AACrD,UAAI,UAAW;AACf,UAAI,WAAW,OAAO;AACpB,gBAAQ,QAAQ,aAAa,MAAM,UAAU,aAAa,MAAM,KAAK;AAAA,MACvE,WAAW,OAAO,aAAa,qBAAqB,IAAI,GAAG;AACzD,gBAAQ,QAAQ,OAAO,UAAU,OAAO,KAAK;AAAA,MAC/C;AAAA,IACF,CAAC,EAAE,MAAM,WAAS;AAChB,UAAI,EAAE,iBAAiB,6BAA6B,CAAC,WAAW;AAC9D,cAAM,UAAU,aAAa,MAAM;AACnC,cAAM,SAAS,QAAQ,KAAK;AAC5B,oBAAY,cAAc,QAAQ,qBAAqB,IAAI,CAAC;AAC5D,0BAAkB,EAAE,QAAQ,SAAS,MAAM,SAAS,IAAI,qBAAqB,IAAI,GAAG,OAAO,OAAO,QAAQ;AAC1G,mBAAW,kBAAkB,EAAE,QAAQ,SAAS,MAAM,SAAS,IAAI,qBAAqB,IAAI,GAAG,OAAO,OAAO,QAAQ,CAAC;AACtH,gBAAQ,QAAQ,aAAa,MAAM,UAAU,aAAa,MAAM,KAAK;AAAA,MACvE;AAAA,IACF,CAAC;AAAA,EACH;AAlBS;AAoBT,QAAM,cAAc,QAAQ,OAAO,uBAAuB;AAE1D,QAAM,SAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IAEA;AAAA,IAEA,KAAK,IAAiD;AACpD,aAAO,SAAS,IAAI,OAAO,KAAK;AAAA,IAClC;AAAA,IAEA,QAAQ,IAAiD;AACvD,aAAO,SAAS,IAAI,MAAM,KAAK;AAAA,IACjC;AAAA,IAEA,OAAa;AACX,mBAAa;AACb,cAAQ,KAAK;AAAA,IACf;AAAA,IAEA,WAAW,OAAoC;AAC7C,mBAAa;AACb,aAAO,KAAK,KAAK;AACjB,aAAO,MAAM;AACX,cAAM,QAAQ,OAAO,QAAQ,KAAK;AAClC,YAAI,SAAS,EAAG,QAAO,OAAO,OAAO,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,IAEA,aAAa,OAAuC;AAClD,mBAAa;AACb,YAAM,UAAU,MAAM,QAAQ,SAAS,IAAI,MAAM,UAAU,MAAM,SAAS,CAAC,MAAM,MAAM,IAAI,CAAC;AAC5F,YAAM,UAAU,QACb,IAAI,aAAW,EAAE,QAAQ,YAAY,OAAO,UAAU,EAAE,EACxD,OAAO,CAAC,UACP,2BAA2B,MAAM,UAAU,CAAC;AAChD,UAAI,CAAC,MAAM,UAAU,QAAQ,WAAW,EAAG,QAAO,EAAE,QAAQ,aAAa,OAAO,6BAAM,QAAN,SAAgB;AAEhG,YAAM,SAA2B,CAAC;AAClC,YAAM,cAA6B,CAAC;AACpC,iBAAW,SAAS,SAAS;AAC3B,cAAM,EAAE,QAAQ,WAAW,IAAI;AAC/B,YAAI,CAAC,qBAAqB,UAAU,GAAG;AACrC,iBAAO,KAAK,UAAU;AACtB;AAAA,QACF;AACA,oBAAY,KAAK,MAAM;AACvB,cAAM,YAAY,gBAAgB,QAAQ,UAAU;AACpD,YAAI,UAAU,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,OAAO,6BAAM,gBAAgB,WAAW,GAAjC,SAAmC;AAC1G,YAAI,UAAU,WAAW,SAAS;AAChC,iBAAO,EAAE,QAAQ,SAAS,OAAO,UAAU,OAAO,OAAO,6BAAM,gBAAgB,WAAW,GAAjC,SAAmC;AAAA,QAC9F;AACA,YAAI,UAAU,UAAW,QAAO,KAAK,UAAU,SAAS;AAAA,MAC1D;AAEA,YAAM,YAAY,OAAO,OAAO,SAAS,CAAC;AAC1C,UAAI,CAAC,UAAW,QAAO,EAAE,QAAQ,aAAa,OAAO,6BAAM,QAAN,SAAgB;AACrE,aAAO;AAAA,QACL,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,OAAO,MAAM,GAAG,EAAE;AAAA,QAC3B,OAAO,6BAAM,gBAAgB,WAAW,GAAjC;AAAA,MACT;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,6BAAM,aAAa,OAAnB;AAAA,MACjB,oBAAoB,6BAAM,iBAAN;AAAA,MACpB,sBAAsB,6BAAM,CAAC,GAAG,iBAAiB,GAA3B;AAAA,MACtB,uBAAuB,8BAAO;AAAA,QAC5B;AAAA,QACA,2BAA2B,oBAAoB,IAAI,IAAI,0BAA0B;AAAA,QACjF;AAAA,MACF,IAJuB;AAAA,MAKvB,iBAAiB,6BAAM,CAAC,GAAG,YAAY,GAAtB;AAAA,MACjB,WAAW,6BAAM,CAAC,GAAG,MAAM,GAAhB;AAAA,MACX;AAAA,MACA,WAAW,wBAAC,KAAK,SAAS,iBAAiB,UAAU,KAAK,MAAM,EAAE,SAAS,SAAS,CAAC,GAA1E;AAAA,MACX,YAAY,wBAAC,KAAK,SAAS,iBAAiB,WAAW,KAAK,MAAM,EAAE,SAAS,SAAS,CAAC,GAA3E;AAAA,MACZ;AAAA,MACA,YAAY,8BAAO,UAAU;AAC3B,cAAM,QAAQ,IAAI,CAAC,GAAG,YAAY,QAAQ,CAAC,EACxC,OAAO,CAAC,CAAC,EAAE,MAAM,MAAM,OAAO,SAAS,aAAa,UAAU,UAAa,OAAO,UAAU,MAAM,EAClG,IAAI,CAAC,CAAC,KAAK,MAAM,MAAM,iBAAiB,OAAO,MAAM,KAAK,OAAO,MAAM,EAAE,OAAO,OAAO,OAAO,SAAS,aAAa,CAAC,CAAC,CAAC;AAAA,MAC5H,GAJY;AAAA,MAKZ,UAAU,OAAO,UAAU;AACzB,YAAID,aAAY,gBAAgB,IAAI,KAAK;AACzC,YAAI,CAACA,YAAW;AAAE,UAAAA,aAAY,oBAAI,IAAI;AAAG,0BAAgB,IAAI,OAAOA,UAAS;AAAA,QAAE;AAC/E,QAAAA,WAAU,IAAI,QAAQ;AACtB,eAAO,MAAMA,YAAW,OAAO,QAAQ;AAAA,MACzC;AAAA,IACF;AAAA,IAEA,UAAgB;AACd,UAAI,UAAW;AACf,kBAAY;AACZ;AACA,kBAAY;AACZ,aAAO,SAAS;AAChB,sBAAgB,MAAM;AACtB,iBAAW,MAAM;AACjB,aAAO,SAAS;AAChB,0BAAoB,MAAM;AAC1B,mBAAa,QAAQ;AACrB,mBAAa,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,WAAS,gBAAgB,QAAqB,YAA2C;AACvF,QAAI,YAAY,WAAW,IAAI,MAAM;AACrC,QAAI,CAAC,WAAW;AACd,kBAAY,EAAE,QAAQ,UAAU;AAChC,iBAAW,IAAI,QAAQ,SAAS;AAChC,WAAK,mBAAmB,UAAU,EAAE,KAAK,eAAa;AACpD,YAAI,UAAW;AACf,kBAAW,SAAS;AACpB,kBAAW,YAAY;AACvB,qBAAa;AACb,mBAAW,gBAAgB,aAAa,KAAK;AAAA,MAC/C,CAAC,EAAE,MAAM,YAAU;AACjB,YAAI,UAAW;AACf,kBAAW,SAAS;AACpB,kBAAW,QAAQ,QAAQ,MAAM;AACjC,oBAAY,QAAQ,QAAQ,aAAa,MAAM,QAAQ;AACvD,qBAAa;AACb,mBAAW,gBAAgB,aAAa,KAAK;AAAA,MAC/C,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AArBS;AAuBT,WAAS,gBAAgB,SAAuC;AAC9D,eAAW,UAAU,QAAS,YAAW,OAAO,MAAM;AACtD,iBAAa;AAAA,EACf;AAHS;AAKT,WAAS,eAAqB;AAC5B,QAAI,UAAW,OAAM,IAAI,MAAM,mFAAiC;AAAA,EAClE;AAFS;AAIT,WAAS,0BAA0B,IAAkB;AACnD,QAAI,OAAO,aAAc,OAAM,IAAI,yBAAyB;AAAA,EAC9D;AAFS;AAIT,SAAO;AACT;AA7bgB;AA+bT,SAAS,WAAW,QAAyB,CAAC,GAAa;AAChE,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAChD,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,wFAAqD;AAElF,SAAO,eAAe,CAAC,QAAQ,WAAW;AACxC,QAAI,aAAyB,6BAAM,QAAN;AAC7B,mBAAe,QAAQ,QAAQ;AAAA,MAC7B,UAAU,6BAAM,OAAO,aAAa,MAAM,UAAhC;AAAA,MACV,SAAS,6BAAM,WAAW,GAAjB;AAAA,MACT,UAAU,wBAAC,OAAO,UAAU;AAC1B,eAAO,SAAS,YAAY,UAAU,OAAO,OAAO,aAAa,MAAM,QAAQ;AAC/E,eAAO,MAAM,QAAQ,OAAO,MAAM;AAAE,eAAK,MAAM;AAAA,QAAE,CAAC,KAAK;AAAA,MACzD,GAHU;AAAA,MAIV,UAAU,6BAAM;AAChB,cAAM,QAAQ,OAAO,aAAa;AAClC,cAAM,OAAO,OAAO,aAAa,KAAK;AACtC,qBAAa,KAAK;AAClB,YAAI,KAAK,WAAW,WAAW;AAC7B,kBAAQ,OAAO,MAAM,YAAY,aAAa,MAAM,QAAQ,IAAI,MAAM,YAAY;AAAA,QACpF;AACA,YAAI,KAAK,WAAW,YAAa,QAAO,MAAM,WAAW,KAAK,KAAK;AACnE,YAAI,KAAK,WAAW,SAAS;AAC3B,gBAAM,KAAK,SAAS,IAAI,MAAM,kDAAU;AAAA,QAC1C;AACA,YAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,YAAI,OAAO,gBAAgB,KAAK,WAAW;AAAA,UACzC;AAAA,UACA,QAAQ,MAAM;AAAA,UACd,OAAO,MAAM;AAAA,QACf,CAAC;AACD,iBAAS,SAAS,KAAK,SAAS,UAAU,KAAK,GAAG,SAAS,GAAG,SAAS;AACrE,iBAAO,gBAAgB,KAAK,QAAS,KAAK,GAAI;AAAA,YAC5C;AAAA,YACA,QAAQ,MAAM;AAAA,YACd,OAAO,MAAM;AAAA,YACb,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT,GA1BY;AAAA,IA0BX,CAAC;AAAA,EACJ,CAAC;AACH;AAzCgB;AA2CT,SAAS,YAAoB;AAClC,QAAM,SAAS,OAAO,UAAU;AAChC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,uFAAoD;AACjF,SAAO;AACT;AAJgB;AAMT,SAAS,WAAkC;AAChD,SAAO,UAAU,EAAE;AACrB;AAFgB;AAIT,SAAS,aAAa,UAA+B,CAAC,GAAe;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,SAAS;AACf,YAAM,cAAc,QAAQ,SAAS,SAAY,aAAa;AAAA,QAC5D,QAAQ,QAAQ,UAAU,CAAC;AAAA,QAC3B,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,SAAS,QAAQ,UAAU;AACjC,cAAQ,QAAQ,YAAY,MAAM;AAClC,aAAO,MAAM,aAAa,QAAQ;AAAA,IACpC;AAAA,EACF;AACF;AAdgB;AAwChB,SAAS,iBAAgC;AACvC,SAAO,OAAO,WAAW,cAAc,oBAAoB,GAAG,IAAI,qBAAqB;AACzF;AAFS;AAIT,IAAM,gBAAwC,OAAO,OAAO,CAAC,CAAC;AAC9D,IAAM,gBAAgB,oBAAI,QAA6B;AAEvD,SAAS,oBAAoB,QAAgC,eAAyD,oBAAI,IAAI,GAA8B;AAC1J,QAAM,QAAQ,wBAAC,SAAiC,YAAoB,aAAuC,QAAQ,IAAI,CAAC,QAAQ,UAAU;AACxI,UAAM,OAAO,OAAO,SAAS,SAAY,cAAc,MAAM,iBAAiB,YAAY,OAAO,IAAI;AACrG,UAAM,KAAK,GAAG,QAAQ,IAAI,KAAK;AAC/B,UAAM,aAAa,OAAO;AAC1B,UAAM,iBAAiB,eAAe,UAAa,qBAAqB,UAAU;AAClF,UAAM,gBAAgB,eAAe,SACjC,UACA,iBACE,cACA,OAAO,eAAe,aACpB,WAAW,QAAQ,cACnB;AACR,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,MAAM,OAAO;AAAA,MACb,WAAW;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,MAAM;AAAA,MACN,QAAQ,OAAO,WAAW;AAAA,MAC1B,QAAQ,OAAO,WAAW;AAAA,MAC1B,QAAQ,iBAAkB,aAAa,IAAI,EAAE,KAAK,YAAa;AAAA,MAC/D,MAAM,OAAO,OAAO,EAAE,GAAI,OAAO,QAAQ,CAAC,EAAG,CAAC;AAAA,MAC9C,UAAU,MAAM,OAAO,YAAY,CAAC,GAAG,MAAM,EAAE;AAAA,IACjD;AAAA,EACF,CAAC,GAzBa;AA0Bd,SAAO,OAAO,OAAO,MAAM,QAAQ,IAAI,OAAO,CAAC;AACjD;AA5BS;AA8BT,SAAS,gBAAgB,QAAgD;AACvE,QAAM,WAA2B,CAAC;AAClC,MAAI,QAAQ;AAEZ,WAAS,MAAM,SAAiC,YAAoB,aAAqC,YAAuB,WAAW,SAAe;AACxJ,YAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,YAAM,UAAU,GAAG,QAAQ,IAAI,KAAK;AACpC,YAAM,WAAW,OAAO,YAAY,CAAC;AACrC,YAAM,OAAO,OAAO,SAAS,SACzB,aACA,iBAAiB,YAAY,OAAO,IAAI;AAC5C,YAAM,aAA0B;AAAA,QAC9B,GAAG;AAAA,QACH,MAAM,OAAO,SAAS,SACjB,SAAS,SAAS,IAAI,SAAa,QAAQ,MAC5C;AAAA,QACJ,MAAM,OAAO,OAAO,EAAE,GAAG,OAAO,KAAK,IAAI,CAAC;AAAA,MAC5C;AACA,oBAAc,IAAI,YAAY,OAAO;AACrC,YAAM,QAAQ,CAAC,GAAG,aAAa,UAAU;AACzC,YAAM,OAAO,OAAO,OAAO,EAAE,GAAG,YAAY,GAAI,WAAW,QAAQ,CAAC,EAAG,CAAC;AACxE,UAAI,SAAS,SAAS,GAAG;AACvB,cAAM,UAAU,MAAM,OAAO,MAAM,OAAO;AAAA,MAC5C,WAAW,WAAW,WAAW;AAC/B,iBAAS,KAAK,cAAc,YAAY,OAAO,MAAM,SAAS,OAAO,CAAC;AAAA,MACxE,WAAW,WAAW,SAAS,QAAW;AACxC,cAAM,IAAI,MAAM,uBAAkB,QAAQ,CAAC,sDAAwB;AAAA,MACrE;AAAA,IACF,CAAC;AAAA,EACH;AAzBS;AA2BT,QAAM,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,SAAO;AACT;AAjCS;AAmCT,SAAS,iBAAiB,YAAoB,WAA2B;AACvE,QAAM,kBAAkB,cAAc,SAAS;AAC/C,MAAI,CAAC,cAAc,oBAAoB,IAAK,QAAO,oBAAoB,MAAO,cAAc,MAAO;AACnG,MAAI,UAAU,WAAW,GAAG,EAAG,QAAO;AACtC,SAAO,cAAc,GAAG,UAAU,IAAI,SAAS,EAAE;AACnD;AALS;AAOT,SAAS,cAAc,QAAqB,OAA+B,MAAiB,OAAe,SAA+B;AACxI,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,WAAW,SAAS,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,MAAM,GAAG;AAC5D,QAAM,OAAiB,CAAC;AACxB,MAAI,QAAQ;AACZ,QAAM,UAAU,SAAS,IAAI,aAAW;AACtC,QAAI,YAAY,KAAK;AACnB,WAAK,KAAK,WAAW;AACrB,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,YAAM,MAAM,QAAQ,MAAM,CAAC;AAC3B,UAAI,CAAC,IAAK,OAAM,IAAI,MAAM,6BAAmB,IAAI,mDAAW;AAC5D,UAAI,KAAK,SAAS,GAAG,EAAG,OAAM,IAAI,MAAM,6BAAmB,IAAI,yCAAW,GAAG,EAAE;AAC/E,WAAK,KAAK,GAAG;AACb,eAAS;AACT,aAAO;AAAA,IACT;AACA,aAAS;AACT,WAAO,aAAa,OAAO;AAAA,EAC7B,CAAC,EAAE,KAAK,GAAG;AAEX,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC;AAAA,IAC/B;AAAA,IACA,OAAO,IAAI,OAAO,SAAS,WAAW,IAAI,SAAS,KAAK,OAAO,KAAK;AAAA,IACpE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAhCS;AAkCT,SAAS,gBAAgB,MAAoB,OAA6B;AACxE,SAAO,MAAM,QAAQ,KAAK,SAAS,KAAK,QAAQ,MAAM;AACxD;AAFS;AAIT,SAAS,cAAc,SAAuB,MAA2B;AACvE,QAAM,QAAQ,QAAQ,MAAM,KAAK,IAAI;AACrC,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,SAAiC,CAAC;AACxC,UAAQ,KAAK,QAAQ,CAAC,KAAK,UAAU;AACnC,WAAO,GAAG,IAAI,gBAAgB,MAAM,QAAQ,CAAC,KAAK,EAAE;AAAA,EACtD,CAAC;AACD,SAAO,OAAO,OAAO,MAAM;AAC7B;AARS;AAUT,SAAS,kBAAkB,KAA2B;AACpD,QAAM,YAAY,IAAI,QAAQ,GAAG;AACjC,QAAM,OAAO,aAAa,IAAI,cAAc,IAAI,MAAM,YAAY,CAAC,CAAC,IAAI;AACxE,QAAM,cAAc,aAAa,IAAI,IAAI,MAAM,GAAG,SAAS,IAAI;AAC/D,QAAM,aAAa,YAAY,QAAQ,GAAG;AAC1C,QAAM,OAAO,cAAc,cAAc,IAAI,YAAY,MAAM,GAAG,UAAU,IAAI,WAAW;AAC3F,QAAM,QAAQ,cAAc,IAAI,WAAW,YAAY,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC;AACjF,SAAO,EAAE,MAAM,OAAO,KAAK;AAC7B;AARS;AAUT,SAAS,gBAAgB,QAA0B,UAAiD;AAClG,MAAI,OAAO,OAAO;AAClB,MAAI,CAAC,QAAQ,OAAO,MAAM;AACxB,UAAM,UAAU,SAAS,KAAK,eAAa,UAAU,OAAO,SAAS,OAAO,IAAI;AAChF,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,+CAAsB,OAAO,IAAI,qBAAM;AACrE,WAAO,gBAAgB,QAAQ,OAAO,QAAQ,KAAK,OAAO,UAAU,CAAC,CAAC;AAAA,EACxE;AACA,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,gFAAmC;AAE9D,QAAM,SAAS,kBAAkB,IAAI;AACrC,QAAM,aAAa,gBAAgB,OAAO,MAAM,OAAO,UAAU,CAAC,CAAC;AACnE,QAAM,QAAQ,OAAO,UAAU,SAAY,OAAO,QAAQ,eAAe,OAAO,KAAK;AACrF,QAAM,OAAO,OAAO,SAAS,SAAY,OAAO,OAAO,cAAc,OAAO,IAAI;AAChF,SAAO,EAAE,MAAM,YAAY,OAAO,MAAM,OAAO,OAAO,MAAM;AAC9D;AAdS;AAgBT,SAAS,gBAAgB,MAAc,QAAyC;AAC9E,SAAO,KAAK,QAAQ,wBAAwB,CAAC,OAAO,QAA4B;AAC9E,UAAM,QAAQ,MAAM,OAAO,GAAG,IAAI,OAAO;AACzC,QAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,WAAO,mBAAmB,OAAO,KAAK,CAAC;AAAA,EACzC,CAAC;AACH;AANS;AAQT,SAAS,gBAAgB,MAAc,OAAmB,MAAsB;AAC9E,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,OAAO,OAAO,KAAK,KAAK,EAAE,KAAK,GAAG;AAC3C,UAAM,QAAQ,MAAM,GAAG;AACvB,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,IAAI,KAAK,KAAK;AAAA,IACvB,OAAO;AACL,iBAAW,QAAQ,MAAO,QAAO,OAAO,KAAK,IAAI;AAAA,IACnD;AAAA,EACF;AACA,QAAM,aAAa,OAAO,SAAS;AACnC,SAAO,GAAG,IAAI,GAAG,aAAa,IAAI,UAAU,KAAK,EAAE,GAAG,IAAI;AAC5D;AAZS;AAcT,SAAS,WAAW,KAAyB;AAC3C,QAAM,SAAS,IAAI,gBAAgB,GAAG;AACtC,QAAM,SAA0C,CAAC;AACjD,SAAO,QAAQ,CAAC,OAAO,QAAQ;AAC7B,UAAM,WAAW,OAAO,GAAG;AAC3B,QAAI,aAAa,OAAW,QAAO,GAAG,IAAI;AAAA,aACjC,OAAO,aAAa,SAAU,QAAO,GAAG,IAAI,CAAC,UAAU,KAAK;AAAA,QAChE,QAAO,GAAG,IAAI,CAAC,GAAG,UAAU,KAAK;AAAA,EACxC,CAAC;AACD,aAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,QAAI,MAAM,QAAQ,OAAO,GAAG,CAAC,EAAG,QAAO,GAAG,IAAI,OAAO,OAAO,OAAO,GAAG,CAAa;AAAA,EACrF;AACA,SAAO,OAAO,OAAO,MAAM;AAC7B;AAbS;AAeT,SAAS,eAAe,OAAoC;AAC1D,MAAI,iBAAiB,gBAAiB,QAAO,WAAW,MAAM,SAAS,CAAC;AACxE,QAAM,SAA0C,CAAC;AACjD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,GAAG,IAAI,OAAO,OAAO,MAAM,IAAI,UAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,QAChF,QAAO,GAAG,IAAI,OAAO,KAAK;AAAA,EACjC;AACA,SAAO,OAAO,OAAO,MAAM;AAC7B;AATS;AAWT,SAAS,cAAc,MAAsB;AAC3C,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,eAAe,KAAK,MAAM,QAAQ,CAAC,EAAE,CAAC,KAAK;AACjD,QAAM,mBAAmB,aAAa,WAAW,GAAG,IAAI,eAAe,IAAI,YAAY;AACvF,MAAI,qBAAqB,QAAQ,qBAAqB,IAAK,QAAO;AAClE,SAAO,iBAAiB,QAAQ,QAAQ,GAAG,EAAE,QAAQ,OAAO,EAAE,KAAK;AACrE;AANS;AAQT,SAAS,qBAAqB,MAAsB;AAClD,QAAM,SAAS,kBAAkB,IAAI;AACrC,SAAO,gBAAgB,OAAO,MAAM,OAAO,OAAO,OAAO,IAAI;AAC/D;AAHS;AAKT,SAAS,cAAc,MAAsB;AAC3C,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAC/C;AAHS;AAKT,SAAS,cAAc,MAAsB;AAC3C,MAAI,CAAC,QAAQ,SAAS,IAAK,QAAO;AAClC,SAAO,IAAI,KAAK,QAAQ,cAAc,EAAE,CAAC;AAC3C;AAHS;AAKT,SAAS,oBAAoB,MAAsB;AACjD,QAAM,WAAW,OAAO,SAAS;AACjC,QAAM,OAAO,SAAS,aAAa,QAAQ,SAAS,WAAW,GAAG,IAAI,GAAG,KACrE,SAAS,MAAM,KAAK,MAAM,KAAK,MAC/B;AACJ,SAAO,qBAAqB,GAAG,IAAI,GAAG,OAAO,SAAS,MAAM,GAAG,OAAO,SAAS,IAAI,EAAE;AACvF;AANS;AAQT,SAAS,SAAS,MAAc,MAAsB;AACpD,SAAO,GAAG,IAAI,GAAG,SAAS,MAAM,MAAM,IAAI,MAAM;AAClD;AAFS;AAIT,SAAS,gBAAgBA,YAAwD,MAAcC,QAAsB;AACnH,aAAW,YAAY,CAAC,GAAGD,UAAS,EAAG,UAAS,MAAMC,MAAK;AAC7D;AAFS;AAIT,SAAS,aAAa,OAAuB;AAC3C,SAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;AAFS;AAIT,SAAS,gBAAgB,OAAuB;AAC9C,MAAI;AACF,WAAO,mBAAmB,KAAK;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AANS;AAQT,SAAS,qBAAqB,OAA8D;AAC1F,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,SAAS;AACvE;AAFS;AAIT,SAAS,2BAA2B,OAAmD;AACrF,SAAO,OAAO,UAAU,cAAc,qBAAqB,KAAiC;AAC9F;AAFS;AAIT,eAAe,mBAAmB,QAAqD;AACrF,QAAM,SAAS,MAAM,OAAO,KAAK;AACjC,QAAM,YAAY,OAAO,WAAW,aAAa,SAAS,OAAO;AACjE,MAAI,OAAO,cAAc,WAAY,OAAM,IAAI,MAAM,6FAA4B;AACjF,SAAO;AACT;AALe;AAOf,SAAS,mBAAmB,OAA2C;AACrE,SAAO,QAAQ,KAAK,KAAK,OAAO,UAAU;AAC5C;AAFS;AAIT,SAAS,QAAQ,QAAwB;AACvC,SAAO,kBAAkB,QAAQ,SAAS,IAAI,MAAM,OAAO,MAAM,CAAC;AACpE;AAFS;AAIT,SAAS,aAAa,QAA0B;AAC9C,SAAO,QAAQ,MAAM,KAAK,OAAO,WAAW,aACrC,OAAuC,SAAS,gBAC/C,OAAuC,SAAS;AAC1D;AAJS;","names":["listeners","state","options"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/debug.ts"],"sourcesContent":["import { state, type Signal } from '@vobs/reactivity'\nimport {\n createComponent,\n createElement,\n createFragment,\n createInjectionKey,\n inject,\n insertBoundary,\n type InjectionKey,\n type VobsNode,\n type VobsPlugin\n} from '@vobs/vobs'\nimport {\n createRouterDebugId,\n emitRouterDebug\n} from './debug'\nimport {\n getRuntimeDebugContext,\n runWithRuntimeDebugContext,\n type RuntimeDebugContext\n} from '@vobs/runtime'\n\nexport { createRouterDebugId, emitRouterDebug, subscribeRouterDebug } from './debug'\nexport type { RouterDebugEvent, RouterDebugEventType } from './debug'\n\nexport type RouteParams = Readonly<Record<string, string>>\nexport type RouteQueryValue = string | readonly string[]\nexport type RouteQuery = Readonly<Record<string, RouteQueryValue>>\nexport type RouteMeta = Readonly<Record<string, unknown>>\n\nexport interface RouteLocation {\n readonly path: string\n readonly fullPath: string\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly hash: string\n readonly name: string | undefined\n readonly meta: RouteMeta\n readonly record: RouteRecord | null\n readonly matched: readonly RouteRecord[]\n readonly state?: unknown\n}\n\nexport interface RouteComponentProps {\n readonly route: RouteLocation\n readonly params: RouteParams\n readonly query: RouteQuery\n readonly children?: VobsNode\n}\n\nexport type RouteComponent = (props: RouteComponentProps) => VobsNode\nexport type RouteComponentModule = RouteComponent | { default: RouteComponent }\nexport type RouteComponentLoader = () => PromiseLike<RouteComponentModule>\n\nexport interface LazyRouteComponent {\n readonly kind: 'vobs-lazy-route'\n readonly load: RouteComponentLoader\n}\n\nexport type RouteComponentDefinition = RouteComponent | LazyRouteComponent\n\nexport interface RouteLoaderContext {\n readonly route: RouteLocation\n readonly navigationId?: number\n readonly dataRequestId?: number\n}\n\nexport type RouteLoader = (context: RouteLoaderContext) => unknown | PromiseLike<unknown>\n\nexport interface RouteRecord {\n readonly path?: string\n readonly component?: RouteComponentDefinition\n readonly source?: string\n readonly name?: string\n readonly meta?: Record<string, unknown>\n readonly loader?: RouteLoader\n readonly action?: RouteLoader\n readonly children?: readonly RouteRecord[]\n}\n\nexport type RouteQueryInput = Record<string, unknown> | URLSearchParams\n\nexport interface RouteLocationRaw {\n readonly path?: string\n readonly name?: string\n readonly params?: Record<string, unknown>\n readonly query?: RouteQueryInput\n readonly hash?: string\n readonly state?: unknown\n}\n\nexport type RouteTarget = string | RouteLocationRaw\n\nexport type NavigationGuardResult = void | boolean | RouteTarget\nexport type NavigationGuard = (\n to: RouteLocation,\n from: RouteLocation\n) => NavigationGuardResult | PromiseLike<NavigationGuardResult>\n\nexport class NavigationCancelledError extends Error {\n readonly code = 'NAVIGATION_CANCELLED'\n\n constructor() {\n super('Vobs Router: 导航已被更新的导航取消')\n this.name = 'NavigationCancelledError'\n }\n}\n\nexport class NavigationRedirectError extends Error {\n readonly code = 'NAVIGATION_REDIRECT_LIMIT'\n\n constructor() {\n super('Vobs Router: 导航重定向超过最大次数')\n this.name = 'NavigationRedirectError'\n }\n}\n\nexport interface RouterHistory {\n readonly location: string\n /** 当前 history 条目携带的导航 state(push/replace 时写入,popstate/初始启动时回读)。 */\n readonly state?: unknown\n push(path: string, state?: unknown): void\n replace(path: string, state?: unknown): void\n back(): void\n listen(listener: (path: string, state: unknown) => void): () => void\n}\n\nexport interface RouterOptions {\n readonly routes: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport interface RouterViewState {\n readonly status: 'ready' | 'loading' | 'error' | 'not-found'\n readonly component?: RouteComponent\n readonly layouts?: readonly RouteComponent[]\n readonly error?: Error\n readonly retry: () => void\n}\n\nexport interface RouteDebugNode {\n readonly id: string\n readonly path: string\n readonly name?: string\n readonly component: string\n readonly lazy: boolean\n readonly loader: boolean\n readonly action: boolean\n readonly status: 'ready' | 'loading' | 'error'\n readonly meta: RouteMeta\n readonly source?: string\n readonly children: readonly RouteDebugNode[]\n}\n\nexport interface RouteErrorTrace {\n readonly id: number\n readonly phase: 'navigation' | 'render' | 'lazy' | 'loader' | 'action' | 'fetcher'\n readonly route: string\n readonly message: string\n readonly stack?: string\n readonly timestamp: number\n readonly requestId?: number\n readonly navigationId?: number\n}\n\nexport interface NavigationTrace {\n readonly id: number\n readonly from: string\n readonly to: string\n readonly status: 'success' | 'redirected' | 'cancelled' | 'error'\n readonly source: 'push' | 'replace' | 'history'\n readonly startedAt: number\n readonly endedAt: number\n readonly duration: number\n readonly redirect?: string\n readonly error?: string\n}\n\nexport interface NavigationState {\n readonly status: 'idle' | 'loading' | 'error'\n readonly from: string\n readonly to: string\n readonly traceId?: number\n readonly error?: string\n}\n\nexport interface RouterPerformanceMetrics {\n readonly navigationCount: number\n readonly averageNavigationDuration: number\n readonly slowNavigationCount: number\n}\n\nexport type RouterDataRequestKind = 'loader' | 'action' | 'fetcher'\n\nexport interface RouterDataRequestTrace {\n readonly id: number\n readonly kind: RouterDataRequestKind\n readonly key: string\n readonly route?: string\n readonly status: 'loading' | 'success' | 'error' | 'cancelled'\n readonly startedAt: number\n readonly endedAt?: number\n readonly duration?: number\n readonly result?: unknown\n readonly error?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport interface RouterDataRequestOptions {\n readonly route?: string\n readonly navigationId?: number\n readonly trigger?: 'navigation' | 'revalidate' | 'manual' | 'resource'\n readonly environment?: 'client' | 'server'\n}\n\nexport type RouterDevToolsEvent = 'navigation:start' | 'navigation:end' | 'route:update' | 'data-request' | 'error'\n\nexport interface RouterDevToolsAPI {\n getRouteTree(): readonly RouteDebugNode[]\n getCurrentRoute(): RouteLocation\n getNavigationState(): NavigationState\n getNavigationHistory(): readonly NavigationTrace[]\n getPerformanceMetrics(): RouterPerformanceMetrics\n getDataRequests(): readonly RouterDataRequestTrace[]\n getErrors(): readonly RouteErrorTrace[]\n trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: () => T | PromiseLike<T>,\n options?: RouterDataRequestOptions | string\n ): Promise<T>\n runAction<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n runFetcher<T>(key: string, task: () => T | PromiseLike<T>): Promise<T>\n reportError(phase: RouteErrorTrace['phase'], error: unknown, route?: string, context?: { readonly requestId?: number; readonly navigationId?: number }): void\n revalidate(route?: string): Promise<void>\n subscribe(event: RouterDevToolsEvent, callback: (payload: unknown) => void): () => void\n}\n\nexport interface Router {\n readonly currentRoute: Signal<RouteLocation>\n readonly history: RouterHistory\n resolve(to: RouteTarget): RouteLocation\n push(to: RouteTarget): Promise<RouteLocation | false>\n replace(to: RouteTarget): Promise<RouteLocation | false>\n back(): void\n beforeEach(guard: NavigationGuard): () => void\n getViewState(route: RouteLocation): RouterViewState\n readonly devtools: RouterDevToolsAPI\n destroy(): void\n}\n\nexport interface RouterViewProps {\n readonly router?: Router\n /** 加载占位:JSX 属性经编译器编译为惰性 getter,手写对象字面量可传节点或工厂。 */\n readonly loading?: VobsNode | (() => VobsNode | null | undefined)\n readonly notFound?: (route: RouteLocation) => VobsNode | null | undefined\n readonly error?: (error: Error, retry: () => void) => VobsNode | null | undefined\n}\n\nexport interface RouterPluginOptions {\n readonly router?: Router\n readonly routes?: readonly RouteRecord[]\n readonly history?: RouterHistory\n}\n\nexport const ROUTER_KEY: InjectionKey<Router> = createInjectionKey<Router>('vobs.router')\n\nexport function lazy(loader: RouteComponentLoader): LazyRouteComponent {\n return {\n kind: 'vobs-lazy-route',\n load: loader\n }\n}\n\nexport function createMemoryHistory(initial = '/'): RouterHistory {\n let entries = [{ path: normalizeHistoryPath(initial), state: undefined as unknown }]\n let index = 0\n const listeners = new Set<(path: string, state: unknown) => void>()\n\n return {\n get location(): string {\n return entries[index]!.path\n },\n\n get state(): unknown {\n return entries[index]!.state\n },\n\n push(path: string, state?: unknown): void {\n const next = normalizeHistoryPath(path)\n entries = entries.slice(0, index + 1)\n entries.push({ path: next, state })\n index++\n },\n\n replace(path: string, state?: unknown): void {\n entries[index] = { path: normalizeHistoryPath(path), state }\n },\n\n back(): void {\n if (index === 0) return\n index--\n notifyListeners(listeners, entries[index]!.path, entries[index]!.state)\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n }\n}\n\nexport function createBrowserHistory(base = ''): RouterHistory {\n if (typeof window === 'undefined') {\n throw new Error('Vobs Router: createBrowserHistory 需要浏览器环境')\n }\n\n const normalizedBase = normalizeBase(base)\n const listeners = new Set<(path: string, state: unknown) => void>()\n const onPopState = (event: PopStateEvent): void => {\n notifyListeners(listeners, readBrowserLocation(normalizedBase), event.state)\n }\n\n return {\n get location(): string {\n return readBrowserLocation(normalizedBase)\n },\n\n get state(): unknown {\n return window.history.state\n },\n\n push(path: string, state?: unknown): void {\n window.history.pushState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n replace(path: string, state?: unknown): void {\n window.history.replaceState(state ?? null, '', withBase(normalizeHistoryPath(path), normalizedBase))\n },\n\n back(): void {\n window.history.back()\n },\n\n listen(listener: (path: string, state: unknown) => void): () => void {\n if (listeners.size === 0) window.addEventListener('popstate', onPopState)\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n if (listeners.size === 0) window.removeEventListener('popstate', onPopState)\n }\n }\n }\n}\n\nexport function createRouter(options: RouterOptions): Router {\n const matchers = normalizeRoutes(options.routes)\n const history = options.history ?? defaultHistory()\n const routerDebugId = createRouterDebugId()\n matchers.sort(compareMatchers)\n const currentRoute = state<RouteLocation>(resolvePath(history.location))\n const lazyStates = new Map<RouteRecord, LazyState>()\n const guards: NavigationGuard[] = []\n const navigationHistory: NavigationTrace[] = []\n const dataRequests: RouterDataRequestTrace[] = []\n const errors: RouteErrorTrace[] = []\n const dataLoaders = new Map<string, { kind: RouterDataRequestKind; route: string; task: () => unknown | PromiseLike<unknown> }>()\n const dataRequestContexts = new Map<number, RuntimeDebugContext>()\n const routerListeners = new Map<RouterDevToolsEvent, Set<(payload: unknown) => void>>()\n let navigationState: NavigationState = { status: 'idle', from: currentRoute.value.fullPath, to: currentRoute.value.fullPath }\n let navigationCount = 0\n let totalNavigationDuration = 0\n let slowNavigationCount = 0\n let nextDataRequestId = 1\n let nextErrorId = 1\n let navigationId = 0\n let destroyed = false\n const viewRevision = state(0)\n\n function resolve(to: RouteTarget): RouteLocation {\n ensureActive()\n const target = typeof to === 'string' ? parseTargetString(to) : normalizeTarget(to, matchers)\n return resolvePath(buildTargetPath(target.path, target.query, target.hash), target.state)\n }\n\n function resolvePath(rawPath: string, state?: unknown): RouteLocation {\n const parsed = parseTargetString(rawPath)\n const matched = matchers.find(matcher => matcher.regex.exec(parsed.path))\n const params = matched ? extractParams(matched, parsed.path) : {}\n const record = matched?.record ?? null\n const query = parsed.query\n const hash = parsed.hash\n return {\n path: parsed.path,\n fullPath: buildTargetPath(parsed.path, query, hash),\n params,\n query,\n hash,\n name: record?.name,\n meta: matched?.meta ?? {},\n record,\n matched: matched?.chain ?? EMPTY_MATCHED,\n state\n }\n }\n\n async function navigate(\n to: RouteTarget,\n replaceHistory: boolean,\n fromHistory: boolean,\n historyState?: unknown\n ): Promise<RouteLocation | false> {\n ensureActive()\n const id = ++navigationId\n const from = currentRoute.value\n let target = resolve(to)\n // popstate 回读的 state 保存在 history 条目上,不在目标描述里,这里回填。\n if (fromHistory && historyState !== undefined) target = { ...target, state: historyState }\n const source: NavigationTrace['source'] = fromHistory ? 'history' : replaceHistory ? 'replace' : 'push'\n const startedAt = now()\n const initialTarget = target.fullPath\n let terminalRecorded = false\n navigationState = { status: 'loading', from: from.fullPath, to: target.fullPath, traceId: id }\n emitRouter('navigation:start', navigationState)\n if (target.fullPath === from.fullPath && !fromHistory) {\n navigationState = { status: 'idle', from: from.fullPath, to: target.fullPath }\n return from\n }\n\n try {\n for (let redirectCount = 0; ; redirectCount++) {\n ensureNavigationIsCurrent(id)\n let redirect: RouteTarget | undefined\n for (const guard of [...guards]) {\n let result: NavigationGuardResult\n try {\n result = await guard(target, from)\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) throw reason\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw reason\n }\n ensureNavigationIsCurrent(id)\n if (result === false) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n return false\n }\n if (typeof result === 'string' || isRouteLocationRaw(result)) {\n redirect = result\n break\n }\n }\n\n for (const record of target.matched) {\n if (!record.loader) continue\n // 上一 loader 期间被新导航抢占时立即取消,跳过剩余 loader。\n ensureNavigationIsCurrent(id)\n await trackDataRequest(\n 'loader',\n `${target.fullPath}#${record.path ?? record.name ?? 'route'}`,\n context => record.loader!({ route: target, navigationId: id, dataRequestId: context.dataRequestId }),\n { route: target.fullPath, navigationId: id, trigger: 'navigation' }\n )\n }\n\n // loader 完成后、提交前必须重新校验:飞行期间被抢占的导航不允许覆盖 currentRoute 与 history。\n ensureNavigationIsCurrent(id)\n\n if (redirect !== undefined) {\n if (redirectCount >= 10) {\n const error = new NavigationRedirectError()\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n throw error\n }\n const redirected = resolve(redirect)\n if (redirected.fullPath === target.fullPath) return false\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'redirected', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: redirected.fullPath })\n target = redirected\n continue\n }\n\n if (target.fullPath === from.fullPath) return from\n if (!fromHistory) {\n if (replaceHistory) history.replace(target.fullPath, target.state)\n else history.push(target.fullPath, target.state)\n }\n currentRoute.value = target\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'success', source, startedAt, endedAt: now(), duration: now() - startedAt, redirect: target.fullPath !== initialTarget ? target.fullPath : undefined })\n terminalRecorded = true\n return target\n }\n } catch (reason) {\n if (reason instanceof NavigationCancelledError) {\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'cancelled', source, startedAt, endedAt: now(), duration: now() - startedAt })\n terminalRecorded = true\n } else if (!terminalRecorded) {\n const error = toError(reason)\n reportError('navigation', error, target.fullPath)\n recordNavigation({ id, from: from.fullPath, to: target.fullPath, status: 'error', source, startedAt, endedAt: now(), duration: now() - startedAt, error: error.message })\n terminalRecorded = true\n }\n throw reason\n }\n }\n\n function now(): number {\n return typeof performance === 'undefined' ? Date.now() : performance.now()\n }\n\n function emitRouter(event: RouterDevToolsEvent, payload: unknown): void {\n for (const callback of routerListeners.get(event) ?? []) {\n try { callback(payload) } catch { /* diagnostics must not affect navigation */ }\n }\n emitRouterDebug(routerDebugId, event, payload, getRuntimeDebugContext() ?? undefined)\n }\n\n function recordNavigation(trace: NavigationTrace): void {\n navigationHistory.push(Object.freeze(trace))\n if (navigationHistory.length > 100) navigationHistory.shift()\n navigationCount++\n totalNavigationDuration += trace.duration\n if (trace.duration >= 16) slowNavigationCount++\n if (trace.id === navigationId) {\n navigationState = trace.status === 'error'\n ? { status: 'error', from: trace.from, to: trace.to, traceId: trace.id, error: trace.error }\n : { status: 'idle', from: trace.from, to: trace.to, traceId: trace.id }\n }\n emitRouter('navigation:end', trace)\n emitRouter('route:update', currentRoute.value)\n }\n\n async function trackDataRequest<T>(\n kind: RouterDataRequestKind,\n key: string,\n task: ((context: { readonly dataRequestId: number }) => T | PromiseLike<T>) | (() => T | PromiseLike<T>),\n optionsOrRoute: RouterDataRequestOptions | string = {}\n ): Promise<T> {\n ensureActive()\n const options = typeof optionsOrRoute === 'string' ? { route: optionsOrRoute } : optionsOrRoute\n const id = nextDataRequestId++\n const startedAt = now()\n const context = getRuntimeDebugContext()\n const route = options.route ?? currentRoute.value.fullPath\n const requestContext: RuntimeDebugContext = {\n ...context,\n environment: options.environment ?? context?.environment,\n route,\n navigationId: options.navigationId ?? context?.navigationId,\n dataRequestId: id,\n source: kind\n }\n const loading: RouterDataRequestTrace = {\n id,\n kind,\n key,\n route,\n status: 'loading',\n startedAt,\n navigationId: requestContext.navigationId,\n trigger: options.trigger,\n environment: requestContext.environment\n }\n dataRequests.push(loading)\n if (dataRequests.length > 100) dataRequests.shift()\n dataRequestContexts.set(id, requestContext)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', loading)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'start', trace: loading }, requestContext)\n dataLoaders.set(key, { kind, route, task: task as () => unknown | PromiseLike<unknown> })\n try {\n const result = await runWithRuntimeDebugContext(requestContext, () => (task as (context: { readonly dataRequestId: number }) => T | PromiseLike<T>)({ dataRequestId: id }))\n const endedAt = now()\n replaceDataRequest(id, { ...loading, status: 'success', endedAt, duration: endedAt - startedAt, result })\n return result\n } catch (reason) {\n const endedAt = now()\n const error = toError(reason)\n const status = isAbortError(reason) ? 'cancelled' : 'error'\n if (status === 'error') reportError(kind, error, route, { requestId: id, navigationId: requestContext.navigationId })\n replaceDataRequest(id, { ...loading, status, endedAt, duration: endedAt - startedAt, error: status === 'error' ? error.message : undefined })\n throw reason\n }\n }\n\n function replaceDataRequest(id: number, trace: RouterDataRequestTrace): void {\n const index = dataRequests.findIndex(item => item.id === id)\n if (index >= 0) dataRequests[index] = Object.freeze(trace)\n emitRouter('route:update', currentRoute.value)\n emitRouter('data-request', trace)\n emitRouterDebug(routerDebugId, 'data-request', { phase: 'end', trace }, dataRequestContexts.get(id))\n dataRequestContexts.delete(id)\n }\n\n function reportError(\n phase: RouteErrorTrace['phase'],\n reason: unknown,\n route = currentRoute.value.fullPath,\n context: { readonly requestId?: number; readonly navigationId?: number } = {}\n ): void {\n const error = toError(reason)\n errors.push(Object.freeze({\n id: nextErrorId++,\n phase,\n route,\n message: error.message,\n stack: error.stack,\n timestamp: now(),\n requestId: context.requestId,\n navigationId: context.navigationId\n }))\n if (errors.length > 100) errors.shift()\n emitRouter('error', errors[errors.length - 1]!)\n emitRouter('route:update', currentRoute.value)\n }\n\n function routeTree(): readonly RouteDebugNode[] {\n const statuses = new Map<string, LazyState['status']>()\n for (const matcher of matchers) {\n for (const record of matcher.chain) {\n if (record.component && isLazyRouteComponent(record.component)) {\n const debugId = routeDebugIds.get(record)\n if (debugId) statuses.set(debugId, lazyStates.get(record)?.status ?? 'loading')\n }\n }\n }\n return buildRouteDebugTree(options.routes, statuses)\n }\n\n function handleHistoryNavigation(path: string, state: unknown): void {\n void navigate(path, false, true, state).then(result => {\n if (destroyed) return\n if (result === false) {\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n } else if (result.fullPath !== normalizeHistoryPath(path)) {\n history.replace(result.fullPath, result.state)\n }\n }).catch(error => {\n if (!(error instanceof NavigationCancelledError) && !destroyed) {\n const current = currentRoute.value.fullPath\n const failed = toError(error)\n reportError('navigation', failed, normalizeHistoryPath(path))\n navigationState = { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message }\n emitRouter('navigation:end', { status: 'error', from: current, to: normalizeHistoryPath(path), error: failed.message })\n history.replace(currentRoute.value.fullPath, currentRoute.value.state)\n }\n })\n }\n\n const stopHistory = history.listen(handleHistoryNavigation)\n\n const router: Router = {\n currentRoute,\n history,\n\n resolve,\n\n push(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, false, false)\n },\n\n replace(to: RouteTarget): Promise<RouteLocation | false> {\n return navigate(to, true, false)\n },\n\n back(): void {\n ensureActive()\n history.back()\n },\n\n beforeEach(guard: NavigationGuard): () => void {\n ensureActive()\n guards.push(guard)\n return () => {\n const index = guards.indexOf(guard)\n if (index >= 0) guards.splice(index, 1)\n }\n },\n\n getViewState(route: RouteLocation): RouterViewState {\n viewRevision.value\n const records = route.matched.length > 0 ? route.matched : route.record ? [route.record] : []\n const entries = records\n .map(record => ({ record, definition: record.component }))\n .filter((entry): entry is { record: RouteRecord; definition: RouteComponentDefinition } =>\n isRouteComponentDefinition(entry.definition))\n if (!route.record || entries.length === 0) return { status: 'not-found', retry: () => undefined }\n\n const loaded: RouteComponent[] = []\n const lazyRecords: RouteRecord[] = []\n for (const entry of entries) {\n const { record, definition } = entry\n if (!isLazyRouteComponent(definition)) {\n loaded.push(definition)\n continue\n }\n lazyRecords.push(record)\n const lazyState = ensureLazyState(record, definition)\n if (lazyState.status === 'loading') return { status: 'loading', retry: () => retryLazyRoutes(lazyRecords) }\n if (lazyState.status === 'error') {\n return { status: 'error', error: lazyState.error, retry: () => retryLazyRoutes(lazyRecords) }\n }\n if (lazyState.component) loaded.push(lazyState.component)\n }\n\n const component = loaded[loaded.length - 1]\n if (!component) return { status: 'not-found', retry: () => undefined }\n return {\n status: 'ready',\n component,\n layouts: loaded.slice(0, -1),\n retry: () => retryLazyRoutes(lazyRecords)\n }\n },\n\n devtools: {\n getRouteTree: routeTree,\n getCurrentRoute: () => currentRoute.value,\n getNavigationState: () => navigationState,\n getNavigationHistory: () => [...navigationHistory],\n getPerformanceMetrics: () => ({\n navigationCount,\n averageNavigationDuration: navigationCount === 0 ? 0 : totalNavigationDuration / navigationCount,\n slowNavigationCount\n }),\n getDataRequests: () => [...dataRequests],\n getErrors: () => [...errors],\n trackDataRequest,\n runAction: (key, task) => trackDataRequest('action', key, task, { trigger: 'manual' }),\n runFetcher: (key, task) => trackDataRequest('fetcher', key, task, { trigger: 'manual' }),\n reportError,\n revalidate: async (route) => {\n await Promise.all([...dataLoaders.entries()]\n .filter(([, loader]) => loader.kind === 'loader' && (route === undefined || loader.route === route))\n .map(([key, loader]) => trackDataRequest(loader.kind, key, loader.task, { route: loader.route, trigger: 'revalidate' })))\n },\n subscribe(event, callback) {\n let listeners = routerListeners.get(event)\n if (!listeners) { listeners = new Set(); routerListeners.set(event, listeners) }\n listeners.add(callback)\n return () => listeners?.delete(callback)\n }\n },\n\n destroy(): void {\n if (destroyed) return\n destroyed = true\n navigationId++\n stopHistory()\n guards.length = 0\n routerListeners.clear()\n lazyStates.clear()\n errors.length = 0\n dataRequestContexts.clear()\n currentRoute.dispose()\n viewRevision.dispose()\n }\n }\n\n function ensureLazyState(record: RouteRecord, definition: LazyRouteComponent): LazyState {\n let lazyState = lazyStates.get(record)\n if (!lazyState) {\n lazyState = { status: 'loading' }\n lazyStates.set(record, lazyState)\n void loadRouteComponent(definition).then(component => {\n if (destroyed) return\n lazyState!.status = 'ready'\n lazyState!.component = component\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n }).catch(reason => {\n if (destroyed) return\n lazyState!.status = 'error'\n lazyState!.error = toError(reason)\n reportError('lazy', reason, currentRoute.value.fullPath)\n viewRevision.value++\n emitRouter('route:update', currentRoute.value)\n })\n }\n return lazyState\n }\n\n function retryLazyRoutes(records: readonly RouteRecord[]): void {\n for (const record of records) lazyStates.delete(record)\n viewRevision.value++\n }\n\n function ensureActive(): void {\n if (destroyed) throw new Error('Vobs Router: 已销毁的 Router 不能继续使用')\n }\n\n function ensureNavigationIsCurrent(id: number): void {\n if (id !== navigationId) throw new NavigationCancelledError()\n }\n\n return router\n}\n\nexport function RouterView(props: RouterViewProps = {}): VobsNode {\n const router = props.router ?? inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: RouterView 找不到 Router,请安装 routerPlugin')\n\n return createFragment((parent, anchor) => {\n let routeRetry: () => void = () => undefined\n insertBoundary(parent, anchor, {\n resetKey: () => router.currentRoute.value.fullPath,\n onRetry: () => routeRetry(),\n fallback: (error, retry) => {\n router.devtools.reportError('render', error, router.currentRoute.value.fullPath)\n // 提供了 error 兜底时完全尊重其返回值(含显式 null);\n // 未提供时渲染内置错误界面(含重试),不再静默渲染空白页——\n // 子 effect 抛错(如弹窗条件 children 内层裸读可空信号)会把整页换成空白\n if (props.error !== undefined) return props.error(error, () => { void retry() })\n return createRouteErrorFallback(error, () => { void retry() })\n },\n children: () => {\n const route = router.currentRoute.value\n const view = router.getViewState(route)\n routeRetry = view.retry\n if (view.status === 'loading') {\n return (typeof props.loading === 'function' ? props.loading() : props.loading) ?? null\n }\n if (view.status === 'not-found') return props.notFound?.(route) ?? null\n if (view.status === 'error') {\n throw view.error ?? new Error('路由组件加载失败')\n }\n if (!view.component) return null\n let node = createComponent(view.component, {\n route,\n params: route.params,\n query: route.query\n })\n for (let index = (view.layouts?.length ?? 0) - 1; index >= 0; index--) {\n node = createComponent(view.layouts![index]!, {\n route,\n params: route.params,\n query: route.query,\n children: node\n })\n }\n return node\n }})\n })\n}\n\nexport function useRouter(): Router {\n const router = inject(ROUTER_KEY)\n if (!router) throw new Error('Vobs Router: useRouter 找不到 Router,请安装 routerPlugin')\n return router\n}\n\n/** 路由错误默认兜底界面:类名 .vobs-route-error 供应用覆盖样式;重试重新渲染当前路由 */\nfunction createRouteErrorFallback(error: Error, retry: () => void): HTMLElement {\n // createElement 返回框架中立 Element;兜底界面仅在浏览器端呈现,按 HTMLElement 设置样式\n const box = createElement('div') as HTMLElement\n box.setAttribute('class', 'vobs-route-error')\n box.style.padding = '48px 24px'\n box.style.display = 'flex'\n box.style.flexDirection = 'column'\n box.style.alignItems = 'center'\n box.style.gap = '12px'\n box.style.fontFamily = 'system-ui, -apple-system, sans-serif'\n box.style.color = '#5a5f6a'\n\n const title = createElement('div') as HTMLElement\n title.textContent = '页面渲染出错'\n title.style.fontSize = '16px'\n title.style.fontWeight = '600'\n title.style.color = '#1c1c1e'\n\n const message = createElement('code') as HTMLElement\n message.textContent = error.message\n message.style.fontSize = '12px'\n message.style.maxWidth = '520px'\n message.style.wordBreak = 'break-word'\n message.style.opacity = '0.75'\n\n const button = createElement('button') as HTMLElement\n button.setAttribute('type', 'button')\n button.textContent = '重试'\n button.style.padding = '6px 20px'\n button.style.fontSize = '13px'\n button.style.cursor = 'pointer'\n button.addEventListener('click', retry)\n\n box.append(title, message, button)\n return box\n}\n\nexport function useRoute(): Signal<RouteLocation> {\n return useRouter().currentRoute\n}\n\nexport function routerPlugin(options: RouterPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/router',\n version: '0.1.0',\n install(context) {\n const ownedRouter = options.router ? undefined : createRouter({\n routes: options.routes ?? [],\n history: options.history\n })\n const router = options.router ?? ownedRouter!\n context.provide(ROUTER_KEY, router)\n return () => ownedRouter?.destroy()\n }\n }\n}\n\ninterface RouteMatcher {\n readonly record: RouteRecord\n readonly debugId: string\n readonly chain: readonly RouteRecord[]\n readonly meta: RouteMeta\n readonly regex: RegExp\n readonly keys: readonly string[]\n readonly score: number\n readonly order: number\n}\n\ninterface LazyState {\n status: 'loading' | 'ready' | 'error'\n component?: RouteComponent\n error?: Error\n}\n\ninterface ParsedTarget {\n readonly path: string\n readonly query: RouteQuery\n readonly hash: string\n readonly state?: unknown\n}\n\nfunction defaultHistory(): RouterHistory {\n return typeof window === 'undefined' ? createMemoryHistory('/') : createBrowserHistory()\n}\n\nconst EMPTY_MATCHED: readonly RouteRecord[] = Object.freeze([])\nconst routeDebugIds = new WeakMap<RouteRecord, string>()\n\nfunction buildRouteDebugTree(routes: readonly RouteRecord[], lazyStatuses: ReadonlyMap<string, LazyState['status']> = new Map()): readonly RouteDebugNode[] {\n const visit = (records: readonly RouteRecord[], parentPath: string, parentId: string): RouteDebugNode[] => records.map((record, index) => {\n const path = record.path === undefined ? parentPath || '/' : resolveChildPath(parentPath, record.path)\n const id = `${parentId}.${index}`\n const definition = record.component\n const lazyDefinition = definition !== undefined && isLazyRouteComponent(definition)\n const componentName = definition === undefined\n ? 'Route'\n : lazyDefinition\n ? 'lazy(...)'\n : typeof definition === 'function'\n ? definition.name || 'Anonymous'\n : 'Route'\n return {\n id,\n path,\n name: record.name,\n component: componentName,\n source: record.source,\n lazy: lazyDefinition,\n loader: record.loader !== undefined,\n action: record.action !== undefined,\n status: lazyDefinition ? (lazyStatuses.get(id) ?? 'loading') : 'ready',\n meta: Object.freeze({ ...(record.meta ?? {}) }),\n children: visit(record.children ?? [], path, id)\n }\n })\n return Object.freeze(visit(routes, '', 'route'))\n}\n\nfunction normalizeRoutes(routes: readonly RouteRecord[]): RouteMatcher[] {\n const matchers: RouteMatcher[] = []\n let order = 0\n\n function visit(records: readonly RouteRecord[], parentPath: string, parentChain: readonly RouteRecord[], parentMeta: RouteMeta, parentId = 'route'): void {\n records.forEach((record, index) => {\n const debugId = `${parentId}.${index}`\n const children = record.children ?? []\n const path = record.path === undefined\n ? parentPath\n : resolveChildPath(parentPath, record.path)\n const normalized: RouteRecord = {\n ...record,\n path: record.path === undefined\n ? (children.length > 0 ? undefined : (path || '/'))\n : path,\n meta: record.meta ? { ...record.meta } : {}\n }\n routeDebugIds.set(normalized, debugId)\n const chain = [...parentChain, normalized]\n const meta = Object.freeze({ ...parentMeta, ...(normalized.meta ?? {}) })\n if (children.length > 0) {\n visit(children, path, chain, meta, debugId)\n } else if (normalized.component) {\n matchers.push(createMatcher(normalized, chain, meta, order++, debugId))\n } else if (normalized.path === undefined) {\n throw new Error(`Vobs Router: 第 ${index + 1} 个路由缺少 path 或 children`)\n }\n })\n }\n\n visit(routes, '', [], {})\n return matchers\n}\n\nfunction resolveChildPath(parentPath: string, childPath: string): string {\n const normalizedChild = normalizePath(childPath)\n if (!parentPath || normalizedChild === '/') return normalizedChild === '/' ? (parentPath || '/') : normalizedChild\n if (childPath.startsWith('/')) return normalizedChild\n return normalizePath(`${parentPath}/${childPath}`)\n}\n\nfunction createMatcher(record: RouteRecord, chain: readonly RouteRecord[], meta: RouteMeta, order: number, debugId: string): RouteMatcher {\n const path = record.path ?? '/'\n const segments = path === '/' ? [] : path.slice(1).split('/')\n const keys: string[] = []\n let score = 0\n const pattern = segments.map(segment => {\n if (segment === '*') {\n keys.push('pathMatch')\n return '(.*)'\n }\n if (segment.startsWith(':')) {\n const key = segment.slice(1)\n if (!key) throw new Error(`Vobs Router: 路由 ${path} 的参数名不能为空`)\n if (keys.includes(key)) throw new Error(`Vobs Router: 路由 ${path} 存在重复参数 ${key}`)\n keys.push(key)\n score += 1\n return '([^/]+)'\n }\n score += 3\n return escapeRegExp(segment)\n }).join('/')\n\n return {\n record,\n debugId,\n chain: Object.freeze([...chain]),\n meta,\n regex: new RegExp(segments.length === 0 ? '^/?$' : `^/${pattern}/?$`),\n keys,\n score,\n order\n }\n}\n\nfunction compareMatchers(left: RouteMatcher, right: RouteMatcher): number {\n return right.score - left.score || left.order - right.order\n}\n\nfunction extractParams(matcher: RouteMatcher, path: string): RouteParams {\n const match = matcher.regex.exec(path)\n if (!match) return {}\n const params: Record<string, string> = {}\n matcher.keys.forEach((key, index) => {\n params[key] = decodeRoutePart(match[index + 1] ?? '')\n })\n return Object.freeze(params)\n}\n\nfunction parseTargetString(raw: string): ParsedTarget {\n const hashIndex = raw.indexOf('#')\n const hash = hashIndex >= 0 ? normalizeHash(raw.slice(hashIndex + 1)) : ''\n const withoutHash = hashIndex >= 0 ? raw.slice(0, hashIndex) : raw\n const queryIndex = withoutHash.indexOf('?')\n const path = normalizePath(queryIndex >= 0 ? withoutHash.slice(0, queryIndex) : withoutHash)\n const query = queryIndex >= 0 ? parseQuery(withoutHash.slice(queryIndex + 1)) : {}\n return { path, query, hash }\n}\n\nfunction normalizeTarget(target: RouteLocationRaw, matchers: readonly RouteMatcher[]): ParsedTarget {\n let path = target.path\n if (!path && target.name) {\n const matcher = matchers.find(candidate => candidate.record.name === target.name)\n if (!matcher) throw new Error(`Vobs Router: 找不到名为 ${target.name} 的路由`)\n path = fillRouteParams(matcher.record.path ?? '/', target.params ?? {})\n }\n if (!path) throw new Error('Vobs Router: 导航目标必须提供 path 或 name')\n\n const parsed = parseTargetString(path)\n const filledPath = fillRouteParams(parsed.path, target.params ?? {})\n const query = target.query === undefined ? parsed.query : normalizeQuery(target.query)\n const hash = target.hash === undefined ? parsed.hash : normalizeHash(target.hash)\n return { path: filledPath, query, hash, state: target.state }\n}\n\nfunction fillRouteParams(path: string, params: Record<string, unknown>): string {\n return path.replace(/:([A-Za-z0-9_]+)|\\*/g, (token, key: string | undefined) => {\n const value = key ? params[key] : params.pathMatch\n if (value === undefined || value === null) return token\n return encodeURIComponent(String(value))\n })\n}\n\nfunction buildTargetPath(path: string, query: RouteQuery, hash: string): string {\n const params = new URLSearchParams()\n for (const key of Object.keys(query).sort()) {\n const value = query[key]\n if (typeof value === 'string') {\n params.set(key, value)\n } else {\n for (const item of value) params.append(key, item)\n }\n }\n const serialized = params.toString()\n return `${path}${serialized ? `?${serialized}` : ''}${hash}`\n}\n\nfunction parseQuery(raw: string): RouteQuery {\n const params = new URLSearchParams(raw)\n const result: Record<string, RouteQueryValue> = {}\n params.forEach((value, key) => {\n const previous = result[key]\n if (previous === undefined) result[key] = value\n else if (typeof previous === 'string') result[key] = [previous, value]\n else result[key] = [...previous, value]\n })\n for (const key of Object.keys(result)) {\n if (Array.isArray(result[key])) result[key] = Object.freeze(result[key] as string[])\n }\n return Object.freeze(result)\n}\n\nfunction normalizeQuery(input: RouteQueryInput): RouteQuery {\n if (input instanceof URLSearchParams) return parseQuery(input.toString())\n const result: Record<string, RouteQueryValue> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null) continue\n if (Array.isArray(value)) result[key] = Object.freeze(value.map(item => String(item)))\n else result[key] = String(value)\n }\n return Object.freeze(result)\n}\n\nfunction normalizePath(path: string): string {\n if (!path) return '/'\n const withoutQuery = path.split(/[?#]/, 1)[0] || '/'\n const withLeadingSlash = withoutQuery.startsWith('/') ? withoutQuery : `/${withoutQuery}`\n if (withLeadingSlash === '/*' || withLeadingSlash === '/') return withLeadingSlash\n return withLeadingSlash.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/'\n}\n\nfunction normalizeHistoryPath(path: string): string {\n const parsed = parseTargetString(path)\n return buildTargetPath(parsed.path, parsed.query, parsed.hash)\n}\n\nfunction normalizeHash(hash: string): string {\n if (!hash) return ''\n return hash.startsWith('#') ? hash : `#${hash}`\n}\n\nfunction normalizeBase(base: string): string {\n if (!base || base === '/') return ''\n return `/${base.replace(/^\\/+|\\/+$/g, '')}`\n}\n\nfunction readBrowserLocation(base: string): string {\n const pathname = window.location.pathname\n const path = base && (pathname === base || pathname.startsWith(`${base}/`))\n ? pathname.slice(base.length) || '/'\n : pathname\n return normalizeHistoryPath(`${path}${window.location.search}${window.location.hash}`)\n}\n\nfunction withBase(path: string, base: string): string {\n return `${base}${path === '/' ? '/' : path}` || '/'\n}\n\nfunction notifyListeners(listeners: Set<(path: string, state: unknown) => void>, path: string, state: unknown): void {\n for (const listener of [...listeners]) listener(path, state)\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction decodeRoutePart(value: string): string {\n try {\n return decodeURIComponent(value)\n } catch {\n return value\n }\n}\n\nfunction isLazyRouteComponent(value: RouteComponentDefinition): value is LazyRouteComponent {\n return typeof value === 'object' && value !== null && value.kind === 'vobs-lazy-route'\n}\n\nfunction isRouteComponentDefinition(value: unknown): value is RouteComponentDefinition {\n return typeof value === 'function' || isLazyRouteComponent(value as RouteComponentDefinition)\n}\n\nasync function loadRouteComponent(loader: LazyRouteComponent): Promise<RouteComponent> {\n const module = await loader.load()\n const component = typeof module === 'function' ? module : module.default\n if (typeof component !== 'function') throw new Error('Vobs Router: 懒加载模块没有默认组件导出')\n return component\n}\n\nfunction isRouteLocationRaw(value: unknown): value is RouteLocationRaw {\n return Boolean(value) && typeof value === 'object'\n}\n\nfunction toError(reason: unknown): Error {\n return reason instanceof Error ? reason : new Error(String(reason))\n}\n\nfunction isAbortError(reason: unknown): boolean {\n return Boolean(reason) && typeof reason === 'object'\n && ((reason as { readonly name?: unknown }).name === 'AbortError'\n || (reason as { readonly code?: unknown }).code === 'ERR_CANCELED')\n}\n","import type { RuntimeDebugContext } from '@vobs/runtime'\n\nexport type RouterDebugEventType =\n | 'navigation:start'\n | 'navigation:end'\n | 'route:update'\n | 'data-request'\n | 'error'\n\nexport interface RouterDebugEvent {\n readonly routerId: string\n readonly type: RouterDebugEventType\n readonly payload: unknown\n readonly context?: RuntimeDebugContext\n}\n\ntype RouterDebugListener = (event: RouterDebugEvent) => void\n\nconst listeners = new Set<RouterDebugListener>()\nlet nextRouterId = 1\n\nexport function createRouterDebugId(): string {\n return `router-${nextRouterId++}`\n}\n\nexport function subscribeRouterDebug(listener: RouterDebugListener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nexport function emitRouterDebug(\n routerId: string,\n type: RouterDebugEventType,\n payload: unknown,\n context?: RuntimeDebugContext\n): void {\n const event: RouterDebugEvent = { routerId, type, payload, context }\n for (const listener of [...listeners]) {\n try { listener(event) } catch { /* diagnostics must not affect navigation */ }\n }\n}\n"],"mappings":"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","names":["listeners","state","options"]}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/vobsjs/vobs.git"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.4.1",
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"./source/*": "./src/*"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@vobs/reactivity": "1.
|
|
37
|
-
"@vobs/runtime": "1.
|
|
38
|
-
"@vobs/vobs": "1.
|
|
36
|
+
"@vobs/reactivity": "1.4.1",
|
|
37
|
+
"@vobs/runtime": "1.4.1",
|
|
38
|
+
"@vobs/vobs": "1.4.1"
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/index.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
2
|
import { createElement, createText, createVobs, insertBefore, setRenderer, createDOMRenderer, type VobsNode } from '@vobs/vobs'
|
|
3
|
+
import { effect, state } from '@vobs/reactivity'
|
|
3
4
|
import {
|
|
4
5
|
createMemoryHistory,
|
|
5
6
|
createBrowserHistory,
|
|
@@ -571,4 +572,129 @@ describe('@vobs/router', () => {
|
|
|
571
572
|
stop()
|
|
572
573
|
router.destroy()
|
|
573
574
|
})
|
|
575
|
+
|
|
576
|
+
// 回归:未提供 error 兜底时,路由子树抛错不能静默渲染成空白页。
|
|
577
|
+
// 真实场景:弹窗条件 children 内层绑定裸读可空信号,信号置 null 时
|
|
578
|
+
// 子 effect(depth 深)先于结构卸载 effect 执行 → null.message 抛错 →
|
|
579
|
+
// RouterView boundary 捕获 → 旧实现 fallback 返回 null → 整页空白。
|
|
580
|
+
it('路由渲染抛错且未提供 error 时渲染内置兜底界面(非空白)', async () => {
|
|
581
|
+
const router = createRouter({
|
|
582
|
+
history: createMemoryHistory('/'),
|
|
583
|
+
routes: [
|
|
584
|
+
{ path: '/', component: () => createText('home') },
|
|
585
|
+
{
|
|
586
|
+
path: '/boom',
|
|
587
|
+
component: () => {
|
|
588
|
+
throw new Error('render exploded')
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
]
|
|
592
|
+
})
|
|
593
|
+
const container = document.createElement('div')
|
|
594
|
+
const app = createVobs({ render: () => RouterView({ router }), plugins: [routerPlugin({ router })] })
|
|
595
|
+
app.mount(container)
|
|
596
|
+
expect(container.textContent).toBe('home')
|
|
597
|
+
|
|
598
|
+
void router.push('/boom')
|
|
599
|
+
await vi.waitFor(() => {
|
|
600
|
+
const fallback = container.querySelector('.vobs-route-error')
|
|
601
|
+
expect(fallback).not.toBeNull()
|
|
602
|
+
expect(fallback?.textContent).toContain('页面渲染出错')
|
|
603
|
+
expect(fallback?.textContent).toContain('render exploded')
|
|
604
|
+
expect(fallback?.querySelector('button')).not.toBeNull()
|
|
605
|
+
})
|
|
606
|
+
app.destroy()
|
|
607
|
+
router.destroy()
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
it('显式 error 兜底返回 null 时尊重用户选择渲染空白', () => {
|
|
611
|
+
const router = createRouter({
|
|
612
|
+
history: createMemoryHistory('/'),
|
|
613
|
+
routes: [
|
|
614
|
+
{
|
|
615
|
+
path: '/',
|
|
616
|
+
component: () => {
|
|
617
|
+
throw new Error('boom')
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
]
|
|
621
|
+
})
|
|
622
|
+
const container = document.createElement('div')
|
|
623
|
+
const app = createVobs({
|
|
624
|
+
render: () => RouterView({ router, error: () => null }),
|
|
625
|
+
plugins: [routerPlugin({ router })]
|
|
626
|
+
})
|
|
627
|
+
app.mount(container)
|
|
628
|
+
expect(container.textContent).toBe('')
|
|
629
|
+
expect(container.querySelector('.vobs-route-error')).toBeNull()
|
|
630
|
+
app.destroy()
|
|
631
|
+
router.destroy()
|
|
632
|
+
})
|
|
633
|
+
|
|
634
|
+
it('兜底界面点击重试可恢复渲染', async () => {
|
|
635
|
+
let shouldThrow = true
|
|
636
|
+
const router = createRouter({
|
|
637
|
+
history: createMemoryHistory('/'),
|
|
638
|
+
routes: [{
|
|
639
|
+
path: '/',
|
|
640
|
+
component: () => {
|
|
641
|
+
if (shouldThrow) throw new Error('first render fails')
|
|
642
|
+
return createText('recovered')
|
|
643
|
+
}
|
|
644
|
+
}]
|
|
645
|
+
})
|
|
646
|
+
const container = document.createElement('div')
|
|
647
|
+
const app = createVobs({ render: () => RouterView({ router }), plugins: [routerPlugin({ router })] })
|
|
648
|
+
app.mount(container)
|
|
649
|
+
await vi.waitFor(() => {
|
|
650
|
+
expect(container.querySelector('.vobs-route-error')).not.toBeNull()
|
|
651
|
+
})
|
|
652
|
+
|
|
653
|
+
shouldThrow = false
|
|
654
|
+
const button = container.querySelector('.vobs-route-error button') as HTMLButtonElement
|
|
655
|
+
button.click()
|
|
656
|
+
await vi.waitFor(() => {
|
|
657
|
+
expect(container.textContent).toBe('recovered')
|
|
658
|
+
})
|
|
659
|
+
app.destroy()
|
|
660
|
+
router.destroy()
|
|
661
|
+
})
|
|
662
|
+
|
|
663
|
+
it('路由子树内 effect 抛错由 boundary 捕获并切换到兜底(弹窗卸载竞态场景)', async () => {
|
|
664
|
+
// 复刻 Labelune 崩溃链:条件渲染的子树内层 effect 裸读可空信号,
|
|
665
|
+
// 信号置 null 时该 effect 先于结构卸载执行并抛错,错误必须被
|
|
666
|
+
// RouterView boundary 兜住(默认兜底界面),而不是炸掉整个页面。
|
|
667
|
+
const data = state<{ message: string } | null>({ message: 'init' })
|
|
668
|
+
const router = createRouter({
|
|
669
|
+
history: createMemoryHistory('/'),
|
|
670
|
+
routes: [{
|
|
671
|
+
path: '/',
|
|
672
|
+
component: () => {
|
|
673
|
+
const box = createElement('div')
|
|
674
|
+
box.className = 'page-content'
|
|
675
|
+
const text = document.createTextNode('')
|
|
676
|
+
box.appendChild(text)
|
|
677
|
+
// 模拟编译产物:{req.value.message} → bindText 裸读可空信号
|
|
678
|
+
effect(() => {
|
|
679
|
+
text.textContent = `msg:${data.value!.message}`
|
|
680
|
+
})
|
|
681
|
+
return box
|
|
682
|
+
}
|
|
683
|
+
}]
|
|
684
|
+
})
|
|
685
|
+
const container = document.createElement('div')
|
|
686
|
+
const app = createVobs({ render: () => RouterView({ router }), plugins: [routerPlugin({ router })] })
|
|
687
|
+
app.mount(container)
|
|
688
|
+
expect(container.querySelector('.page-content')).not.toBeNull()
|
|
689
|
+
|
|
690
|
+
// 置 null:内层 effect 抛 null.message(depth 优先,先于任何结构卸载执行),
|
|
691
|
+
// 错误必须被 boundary 接住并显示兜底界面
|
|
692
|
+
data.set(null)
|
|
693
|
+
await vi.waitFor(() => {
|
|
694
|
+
expect(container.querySelector('.vobs-route-error')).not.toBeNull()
|
|
695
|
+
})
|
|
696
|
+
expect(container.textContent).toContain('页面渲染出错')
|
|
697
|
+
app.destroy()
|
|
698
|
+
router.destroy()
|
|
699
|
+
})
|
|
574
700
|
})
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { state, type Signal } from '@vobs/reactivity'
|
|
2
2
|
import {
|
|
3
3
|
createComponent,
|
|
4
|
+
createElement,
|
|
4
5
|
createFragment,
|
|
5
6
|
createInjectionKey,
|
|
6
7
|
inject,
|
|
@@ -812,7 +813,11 @@ export function RouterView(props: RouterViewProps = {}): VobsNode {
|
|
|
812
813
|
onRetry: () => routeRetry(),
|
|
813
814
|
fallback: (error, retry) => {
|
|
814
815
|
router.devtools.reportError('render', error, router.currentRoute.value.fullPath)
|
|
815
|
-
|
|
816
|
+
// 提供了 error 兜底时完全尊重其返回值(含显式 null);
|
|
817
|
+
// 未提供时渲染内置错误界面(含重试),不再静默渲染空白页——
|
|
818
|
+
// 子 effect 抛错(如弹窗条件 children 内层裸读可空信号)会把整页换成空白
|
|
819
|
+
if (props.error !== undefined) return props.error(error, () => { void retry() })
|
|
820
|
+
return createRouteErrorFallback(error, () => { void retry() })
|
|
816
821
|
},
|
|
817
822
|
children: () => {
|
|
818
823
|
const route = router.currentRoute.value
|
|
@@ -850,6 +855,44 @@ export function useRouter(): Router {
|
|
|
850
855
|
return router
|
|
851
856
|
}
|
|
852
857
|
|
|
858
|
+
/** 路由错误默认兜底界面:类名 .vobs-route-error 供应用覆盖样式;重试重新渲染当前路由 */
|
|
859
|
+
function createRouteErrorFallback(error: Error, retry: () => void): HTMLElement {
|
|
860
|
+
// createElement 返回框架中立 Element;兜底界面仅在浏览器端呈现,按 HTMLElement 设置样式
|
|
861
|
+
const box = createElement('div') as HTMLElement
|
|
862
|
+
box.setAttribute('class', 'vobs-route-error')
|
|
863
|
+
box.style.padding = '48px 24px'
|
|
864
|
+
box.style.display = 'flex'
|
|
865
|
+
box.style.flexDirection = 'column'
|
|
866
|
+
box.style.alignItems = 'center'
|
|
867
|
+
box.style.gap = '12px'
|
|
868
|
+
box.style.fontFamily = 'system-ui, -apple-system, sans-serif'
|
|
869
|
+
box.style.color = '#5a5f6a'
|
|
870
|
+
|
|
871
|
+
const title = createElement('div') as HTMLElement
|
|
872
|
+
title.textContent = '页面渲染出错'
|
|
873
|
+
title.style.fontSize = '16px'
|
|
874
|
+
title.style.fontWeight = '600'
|
|
875
|
+
title.style.color = '#1c1c1e'
|
|
876
|
+
|
|
877
|
+
const message = createElement('code') as HTMLElement
|
|
878
|
+
message.textContent = error.message
|
|
879
|
+
message.style.fontSize = '12px'
|
|
880
|
+
message.style.maxWidth = '520px'
|
|
881
|
+
message.style.wordBreak = 'break-word'
|
|
882
|
+
message.style.opacity = '0.75'
|
|
883
|
+
|
|
884
|
+
const button = createElement('button') as HTMLElement
|
|
885
|
+
button.setAttribute('type', 'button')
|
|
886
|
+
button.textContent = '重试'
|
|
887
|
+
button.style.padding = '6px 20px'
|
|
888
|
+
button.style.fontSize = '13px'
|
|
889
|
+
button.style.cursor = 'pointer'
|
|
890
|
+
button.addEventListener('click', retry)
|
|
891
|
+
|
|
892
|
+
box.append(title, message, button)
|
|
893
|
+
return box
|
|
894
|
+
}
|
|
895
|
+
|
|
853
896
|
export function useRoute(): Signal<RouteLocation> {
|
|
854
897
|
return useRouter().currentRoute
|
|
855
898
|
}
|