import { parse } from '@tinkoff/url' ; import type { Options } from './abstract' ; import { AbstractRouter } from './abstract' ; import type { Navigation , NavigateOptions } from '../types' ; import { isSameHost } from '../utils' ; import { logger } from '../logger' ; import { ClientHistory } from '../history/client' ; export abstract class ClientRouter extends AbstractRouter { constructor ( options ) { super ( options ) ; this . history = new ClientHistory ( ) ; this . history . listen ( async ( { type , url , navigateState , replace , history } ) => { const currentUrl = this . getCurrentUrl ( ) ; const { pathname , query } = this . resolveUrl ( { url } ) ; const isSameUrlNavigation = currentUrl . pathname === pathname ; if ( type === 'updateCurrentRoute' || ( ! type && isSameUrlNavigation ) ) { const route = this . tree ?. getRoute ( pathname ) ; await this . internalUpdateCurrentRoute ( { params : route ?. params , query , replace , navigateState , } , { history } ) ; } else { await this . internalNavigate ( { url , replace , navigateState , } , { history } ) ; } } ) ; } async rehydrate ( navigation ) { logger . debug ( { event : 'rehydrate' , navigation , } ) ; const url = parse ( window . location . href ) ; this . currentNavigation = { ... navigation , type : 'navigate' , url , } ; this . lastNavigation = this . currentNavigation ; await this . runGuards ( this . currentNavigation ) ; this . history . init ( this . currentNavigation ) ; this . currentNavigation = null ; if ( navigation . to ) { this . addRoute ( { name : navigation . to . name , path : navigation . to . path , config : navigation . to . config , alias : url . pathname , } ) ; } } protected resolveRoute ( ... options ) { const { url } = options [ 0 ] ; if ( url && ! isSameHost ( url ) ) { return ; } return super . resolveRoute ( ... options ) ; } protected async notfound ( navigation ) { await super . notfound ( navigation ) ; if ( navigation . replace ) { window . location . replace ( navigation . url . href ) ; } else { window . location . assign ( navigation . url . href ) ; } return new Promise < void > ( ( ) => { } ) ; } protected async block ( navigation ) { return this . notfound ( navigation ) ; } protected async redirect ( navigation , target ) { await super . redirect ( navigation , target ) ; return this . navigate ( { ... target , replace : target . replace || navigation . replace } ) ; } }