financial-assistant
55 строк · 1.5 Кб
1import { EventTypes, Links } from "../contracts/enums";
2import EventObserver from "../observer/observer";
3
4class Router {
5private observer: EventObserver;
6private routes: Map<Links, () => void> = new Map();
7
8constructor(observer: EventObserver) {
9this.observer = observer;
10this.subscribeToUrlChange();
11}
12
13private subscribeToUrlChange() {
14this.observer.subscribe(EventTypes.CHANGE_PAGE, this.navigate.bind(this));
15window.addEventListener("popstate", () => this.resolveRoute());
16window.addEventListener("hashchange", () => this.resolveRoute());
17}
18
19public getPath(): Links {
20const url = new URL(window.location.href);
21const path = url.pathname.slice(1);
22
23if (!this.isValidPath(path)) {
24throw new Error("Unavailable URL: " + path);
25}
26return path === "" ? Links.home : (path as Links);
27}
28
29private isValidPath(path: string): boolean {
30return Object.values(Links).includes(path as Links) || path === "";
31}
32
33public resolveRoute() {
34const callback = this.routes.get(this.getPath());
35if (callback) callback();
36}
37
38public route(path: Links, callback: () => void): void {
39this.routes.set(path, callback);
40}
41
42private updateURL(path: Links): void {
43const url = new URL(location.toString());
44url.pathname = path;
45history.pushState(null, "", url.toString());
46}
47
48private navigate(path: Links = Links.home) {
49this.updateURL(path);
50const callback = this.routes.get(path);
51if (callback) callback();
52}
53}
54
55export default Router;
56
57