@relax.dev/router
Version:
Router for VKUI
196 lines (195 loc) • 9.68 kB
TypeScript
import { Page } from './Page';
import { History } from './History';
import { Route as MyRoute } from './Route';
import { State } from './State';
import { EventEmitter } from 'tsee';
import { RouterConfig } from './RouterConfig';
import { Location } from './Location';
import { HistoryUpdateType, InfinityPanelIdTitle, PageParams, RouterGenericBase } from './Types';
import { Fixer } from './HotFixers';
export declare type RouteList<T extends RouterGenericBase = RouterGenericBase> = Partial<Record<T['pageId'], Page<T>>>;
export declare type ReplaceUnknownRouteFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute?: MyRoute<T>) => MyRoute<T>;
/**
* @ignore
*/
export declare type UpdateEventFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute: MyRoute<T> | undefined, isNewRoute: boolean, type: HistoryUpdateType) => void;
/**
* @ignore
*/
export declare type EnterEventFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute?: MyRoute<T>) => void;
/**
* @ignore
*/
export declare type LeaveEventFn<T extends RouterGenericBase = RouterGenericBase> = (newRoute: MyRoute<T>, oldRoute: MyRoute<T>, isNewRoute: boolean, type: HistoryUpdateType) => void;
export declare type RouterMiddleware<T extends RouterGenericBase = RouterGenericBase> = (route: MyRoute<T>, hash: string) => MyRoute<T>;
export declare class Router<T extends RouterGenericBase = RouterGenericBase> extends EventEmitter<{
update: UpdateEventFn<T>;
enter: EnterEventFn<T>;
}> {
routes: RouteList<T>;
history: History<T>;
enableLogging: boolean;
defaultPage: string;
defaultView: string;
defaultRoot: string;
defaultPanel: string;
alwaysStartWithSlash: boolean;
blankMiddleware: Array<RouterMiddleware<T>>;
preventSameLocationChange: boolean;
hotFixes: Set<Fixer>;
hashParamName: string;
/**
* Значение window.location.hash которое было на момент старта роутера
*/
startHash: string;
private deferOnGoBack;
private startHistoryOffset;
private started;
private readonly infinityPanelCacheInstance;
private readonly performBlankMiddleware;
/**
*
* ```javascript
* export const PAGE_MAIN = '/';
* export const PAGE_PERSIK = '/persik';
* export const PANEL_MAIN = 'panel_main';
* export const PANEL_PERSIK = 'panel_persik';
* export const VIEW_MAIN = 'view_main';
* const routes = {
* [PAGE_MAIN]: new Page(PANEL_MAIN, VIEW_MAIN),
* [PAGE_PERSIK]: new Page(PANEL_PERSIK, VIEW_MAIN),
* };
* export const router = new Router(routes);
* router.start();
* ```
* @param routes
* @param routerConfig
*/
constructor(routes: RouteList<T>, routerConfig?: RouterConfig<T> | null);
private static back;
private static backTo;
replacerUnknownRoute: ReplaceUnknownRouteFn<T>;
private extractHashFromParam;
private get currentHash();
start(hashParamName?: string): void;
stop(): void;
getCurrentRouteOrDef(): MyRoute<T>;
getCurrentStateOrDef(): State<T>;
log(...args: any): void;
/**
* Добавляет новую страницу в историю
* @param pageId страница указанная в конструкторе {@link Router.constructor}
* @param params можно получить из {@link Location.getParams}
*/
pushPage(pageId: T['pageId'], params?: PageParams): void;
/**
* Заменяет текущую страницу на переданную
* @param pageId страница указанная в конструкторе {@link Router.constructor}
* @param params можно получить из {@link Location.getParams}
*/
replacePage(pageId: T['pageId'], params?: PageParams): void;
pushPageAfterPreviews(prevPageId: T['pageId'], pageId: T['pageId'], params?: PageParams): void;
/**
* Переход по истории назад
*/
popPage(): void;
/**
* Если x - число, то осуществляется переход на указанное количество шагов
* Если x - строка, то в истории будет найдена страница с указанным pageId и осуществлен переход до нее
* @param {string|number} x
*/
popPageTo(x: number | T['pageId']): void;
popPageToAndPush(x: number, pageId: T['pageId'], params?: PageParams): void;
popPageToAndReplace(x: number, pageId: T['pageId'], params?: PageParams): void;
/**
* История ломается когда открывается VKPay или пост из колокольчика
*/
isHistoryBroken(): boolean;
/**
* Способ починить историю браузера когда ее сломали снаружи из фрейма
* например перейдя по колокольчику или открыв вкпей
* проблема: миниап запущен фо фрейме и у него обшая исторя страниц с родительской страницей
* все происходит хорошо когда только миниап пушит в историю страницы
* [X1, X2, X3]
* когда приходит родительская страница и пуши что-то в историю
* [X1, X2, X3, Y1, Y1]
* то случается беда, в истории перремешаны страницы, следующий popPage приведет в неожиданное место
* в даннмо слусе ожидалось что popPage перейдет с X3 на X2, но фактически придут на Y1
* идея решения -- запушить снова все "нужные страницы поверх истории"
* [X1, X2, X3, Y1, Y1, X1, X2, X3]
*/
fixBrokenHistory(): void;
/**
* @param modalId
* @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы
*/
pushModal(modalId: T['modalId'], params?: PageParams): void;
/**
* @param popupId
* @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы
*/
pushPopup(popupId: T['popupId'], params?: PageParams): void;
/**
* @param modalId
* @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы
*/
replaceModal(modalId: T['modalId'], params?: PageParams): void;
/**
* @param popupId
* @param params Будьте аккуратны с параметрами, не допускайте чтобы ваши параметры пересекались с параметрами страницы
*/
replacePopup(popupId: string, params?: PageParams): void;
popPageIfModal(): void;
popPageIfPopup(): void;
/**
* @deprecated use popPageIfHasOverlay
*/
popPageIfModalOrPopup(): void;
popPageIfHasOverlay(): void;
/**
* @param pageId
* @param fn
* @return unsubscribe function
*/
onEnterPage(pageId: string, fn: UpdateEventFn): () => void;
/**
* @param pageId
* @param fn
* @return unsubscribe function
*/
onLeavePage(pageId: T['pageId'], fn: LeaveEventFn): () => void;
getCurrentLocation(): Location<T>;
getPreviousLocation(): Location<T> | undefined;
/**
* @param safety - true будет ждать события не дольше 700мс, если вы уверены что надо ждать дольше передайте false
*/
afterUpdate(safety?: boolean): Promise<void>;
private static checkParams;
private getDefaultRoute;
private readonly onPopState;
private replace;
private push;
/**
* @param location значение window.location.hash
* @private
*/
createRouteFromLocationWithReplace(location: T['pageId']): MyRoute<T>;
private createRouteFromLocation;
private static isErrorThrowingEnabled;
/**
* Чтобы отрендерить бесконечне панели надо знать их id
* этот метод возвращает все id панелей которые хоть раз были отрендерены
* это не эффективно, однако сейчас точно нельзя сказать когда панель нужна а когда нет
* это обусловленно тем что панели надо убирать из дерева только после того как пройдет анимация vkui
* кроме того панели могут убираться из середины, благодоря useThrottlingLocation.ts
*
* текущее решение -- рендерить все панели всегда
*
* @param viewId
*/
getInfinityPanelList(viewId: T['viewId']): Array<InfinityPanelIdTitle<T['panelId']>>;
private static isSameLocation;
private needPreventSameLocationChange;
onVKWebAppChangeFragment(location: string): void;
private hasFixer;
}