rvx
Version:
A signal based rendering library
60 lines • 1.98 kB
JavaScript
import { ENV } from "../core/env.js";
import { teardown } from "../core/lifecycle.js";
import { $, batch } from "../core/signals.js";
import { join, relative } from "./path.js";
import { formatQuery, Query } from "./query.js";
export class HistoryRouter {
#env = ENV.current;
#basePath;
#path = $(undefined);
#query = $(undefined);
constructor(options) {
const env = this.#env;
this.#basePath = options?.basePath ?? "";
const parseEvents = options?.parseEvents ?? ["popstate", "rvx:router:update"];
const parse = this.parse.bind(this);
for (const name of parseEvents) {
env.window.addEventListener(name, parse, { passive: true });
teardown(() => env.window.removeEventListener(name, parse));
}
this.parse();
}
parse() {
batch(() => {
const env = this.#env;
this.#path.value = relative(this.#basePath, env.location.pathname);
this.#query.value = env.location.search.length > 0 ? new Query(env.location.search.slice(1)) : undefined;
});
}
;
#format(path, query) {
let href = join(this.#basePath, path) || "/";
if (query !== undefined) {
href += "?" + formatQuery(query);
}
return href;
}
get root() {
return this;
}
get parent() {
return undefined;
}
get path() {
return this.#path.value;
}
get query() {
return this.#query.value;
}
push(path, query) {
const env = this.#env;
env.history.pushState(null, "", this.#format(path, query));
env.window.dispatchEvent(new env.CustomEvent("rvx:router:update"));
}
replace(path, query) {
const env = this.#env;
env.history.replaceState(null, "", this.#format(path, query));
env.window.dispatchEvent(new env.CustomEvent("rvx:router:update"));
}
}
//# sourceMappingURL=history-router.js.map