@jadis/core
Version:
Jadis is a minimal JavaScript library for building web interfaces using native Web Components.
1 lines • 47.4 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../src/helpers/assert.helper.ts","../../src/helpers/change.helper.ts","../../src/helpers/string.helper.ts","../../src/helpers/element.helper.ts","../../src/base-component.ts","../../src/helpers/bus.helper.ts","../../src/helpers/component.helper.ts","../../src/helpers/router.helper.ts","../../src/helpers/template.helper.ts","../../src/router/router-constants.ts","../../src/router/router.ts"],"sourcesContent":["/**\n * A helper function to assert conditions in the code.\n * It throws an error if the condition is not met.\n * @param {unknown} condition The condition to check\n * @param {string} message The error message to throw if the condition is not met\n * @returns {asserts condition} --- TypeScript assertion ---\n * @throws Will throw an error if the condition is false\n */\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n","export class ChangeHandler<T> {\n private _value: T;\n\n constructor(\n initialValue: T,\n private onChange: (newValue: T, oldValue: T) => void\n ) {\n this._value = initialValue;\n }\n\n get() {\n return this._value;\n }\n set(setter: T | ((val: T) => T)) {\n const oldValue = structuredClone(this._value);\n this._value = typeof setter === 'function' ? (setter as (val: T) => T)(this._value) : setter;\n this.onChange(this._value, oldValue);\n }\n}\n","/**\n * Converts a string to kebab-case.\n * This function replaces uppercase letters with their lowercase equivalents,\n * prefixing them with a hyphen if they are not at the start of the string.\n * @example\n * toKebabCase('myVariableName'); // 'my-variable-name'\n * toKebabCase('MyVariableName'); // 'my-variable-name'\n * @param str The input string\n * @returns The kebab-cased string\n */\nexport const toKebabCase = (str: string): string => {\n return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());\n};\n","import { ChangeHandler } from './change.helper';\nimport { toKebabCase } from './string.helper';\n\nimport type { JadisConstructor } from '../base-component';\nimport type { AppendableElement, ElementValues, OptionsWithProps } from './type.helper';\n\n/**\n * Creates a new HTML element.\n * This function allows you to create an HTML element with specified attributes\n * and append it to a specified parent element.\n * @param tag The tag name of the element to create\n * @param options An optional set of properties and attributes to set on the component {attrs: {}, props: {}}\n * @param appendTo The element to append the new element to\n * @returns The created HTML element\n * @example\n * const newElement = createElement('div', {attrs: { class: 'my-class', id: 'my-id' },\n * props: {myProp: propValue}}, document.body);\n */\nexport function createElement<Tag extends keyof HTMLElementTagNameMap>(\n tag: Tag,\n options?: OptionsWithProps<ElementValues<HTMLElementTagNameMap[Tag]>>,\n appendTo?: AppendableElement\n): HTMLElementTagNameMap[Tag];\nexport function createElement<T extends HTMLElement>(\n tag: string,\n options?: OptionsWithProps<ElementValues<T>>,\n appendTo?: AppendableElement\n): T;\nexport function createElement<Component extends JadisConstructor>(\n tag: Component,\n options?: OptionsWithProps<ElementValues<InstanceType<Component>>>,\n appendTo?: AppendableElement\n): InstanceType<Component>;\nexport function createElement(\n tag: string,\n options: OptionsWithProps<Record<string, unknown>> = {},\n appendTo?: AppendableElement\n): HTMLElement {\n const el = document.createElement(tag.toString());\n Object.entries(options.props ?? {}).forEach(([key, value]) => {\n const prop = el as HTMLElement & Record<string, unknown>;\n if (prop[key] instanceof ChangeHandler) {\n prop[key].set(value);\n } else {\n prop[key] = value;\n }\n });\n Object.entries(options.attrs ?? {}).forEach(([key, value]) => {\n el.setAttribute(toKebabCase(key), String(value));\n });\n appendTo?.appendChild(el);\n return el;\n}\n","/** biome-ignore-all lint/complexity/noThisInStatic: I explicitly need to refer to \"this\" and not Jadis for code hint when creating components */\nimport { assert } from './helpers/assert.helper';\nimport { ChangeHandler } from './helpers/change.helper';\nimport { createElement } from './helpers/element.helper';\n\nimport type { Bus } from './helpers/bus.helper';\nimport type {\n ComponentSelector,\n Constructor,\n ElementValues,\n OptionalIfUndefined,\n OptionsWithProps,\n Primitive,\n SelectorToElementWithFallback,\n} from './helpers/type.helper.ts';\nimport type { ChangeOptions, UseEventsHandler } from './types/jadis.type';\n\nexport interface JadisConstructor<T extends Jadis = Jadis> {\n new (): T;\n readonly selector: ComponentSelector;\n readonly observedAttributes: Array<string>;\n}\n\n/**\n * Base class for all Jadis components.\n * It provides a structure for creating web components with a shadow DOM,\n * event handling, and attribute management.\n */\nexport abstract class Jadis extends HTMLElement {\n static readonly selector: ComponentSelector;\n static readonly template: string = '';\n static readonly observedAttributes: Array<string> = [];\n readonly shadowRoot: ShadowRoot;\n\n protected readonly attributesCallback: Partial<Record<string, (value: string, oldValue: string) => void>> = {};\n\n /** Actions to perform when the component is connected to the DOM. */\n protected onConnectActions: Array<() => void> = [];\n\n private readonly _abortController = new AbortController();\n private _isConnected = false;\n\n /**\n * Callback invoked when the component is connected to the DOM.\n * This method can be overridden to perform actions when the component is added to the document.\n * This is the place to initialize component state, start any necessary processes and add event listeners.\n */\n onConnect?(): void;\n\n /**\n * Callback invoked when the component is disconnected from the DOM.\n */\n onDisconnect?(): void;\n\n /**\n * The HTML template for the component.\n * This method should return a string containing the HTML structure of the component.\n * It can be overridden to provide custom templates.\n * @returns The HTML template as a string\n * @example\n * ```typescript\n * templateHtml() {\n * return `<div>Hello, World!</div>`;\n * }\n * ```\n */\n templateHtml?(): DocumentFragment;\n\n /**\n * The CSS styles for the component.\n * This method should return a string containing the CSS styles for the component.\n * It can be overridden to provide custom styles.\n * @returns The CSS styles as a string\n * @example\n * ```typescript\n * templateCss() {\n * return `:host { display: block; }`;\n * }\n * ```\n */\n templateCss?(): string;\n\n constructor() {\n super();\n this.shadowRoot = this.attachShadow({ mode: 'open' });\n this.shadowRoot.appendChild(this.buildTemplate());\n }\n\n /**\n * Creates a new instance with the defined children\n * @param options An optional set of properties and attributes to set on the component {attrs: {}, props: {}}\n * @param slotted The DOM to slot inside the component\n * @returns The created component instance\n */\n static toTemplate<T extends Jadis>(\n this: JadisConstructor<T>,\n options: OptionsWithProps<ElementValues<T>> = {},\n slotted: DocumentFragment = document.createDocumentFragment()\n ): T {\n const element = createElement(this.selector, options);\n element.appendChild(slotted.cloneNode(true));\n return element;\n }\n\n /**\n * Registers the component as a custom element.\n * This method should be called once to define the custom element in the browser.\n * It checks if the selector is defined and if the custom element is not already registered.\n * @throws Will throw an error if the selector is not defined for the component\n */\n static register(): void {\n assert(this.selector, `selector is not defined for ${this.name}`);\n if (!customElements.get(this.typeOfClass.selector)) {\n customElements.define(this.typeOfClass.selector, this.typeOfClass);\n }\n }\n\n static toString(): string {\n return this.selector;\n }\n\n /**\n * Checks if the component is connected to the DOM.\n * @returns True if the component is connected, false otherwise\n */\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n connectedCallback(): void {\n this._isConnected = true;\n this.onConnectActions.forEach((fn) => {\n fn();\n });\n setTimeout(() => this.onConnect?.());\n }\n\n disconnectedCallback(): void {\n this._abortController.abort();\n this.onDisconnect?.();\n }\n\n attributeChangedCallback(name: string, oldValue: string, newValue: string): void {\n this.attributesCallback[name]?.(newValue, oldValue);\n }\n\n /**\n * Returns the AbortSignal associated with this component.\n * This signal can be used to cancel ongoing operations or event listeners.\n * @returns The AbortSignal for this component\n */\n protected get killSignal(): AbortSignal {\n return this._abortController.signal;\n }\n\n /**\n * Retrieves an element from the component's template.\n * @param query The query string to find the element\n * @returns The found element\n * @throws Will throw an error if the element is not found\n */\n protected getElement<Element extends HTMLElement, Tag extends keyof HTMLElementTagNameMap | string = string>(\n query: Tag\n ): SelectorToElementWithFallback<Tag, Element> {\n const el = query.split('>>>').reduce((nextEl: HTMLElement, nextQuery: string) => {\n const found = (nextEl.shadowRoot ?? nextEl).querySelector<HTMLElement>(nextQuery);\n assert(found, `Jadis.getElement: ${nextQuery} element is not reachable`);\n return found;\n }, this);\n assert(el, `${query} element is not reachable`);\n\n return el as SelectorToElementWithFallback<Tag, Element>;\n }\n\n /**\n * Toggles a class on the component based on a condition.\n * If the condition is true, the class will be added; if false, it will be removed.\n * @param className The name of the class to toggle\n * @param condition The binary condition to determine whether to add or remove the class\n */\n protected toggleClass(className: string, condition: boolean): void {\n this.classList[condition ? 'add' : 'remove'](className);\n }\n\n /**\n * Registers a callback for a specific event on a bus.\n * @param bus The event bus to register the callback on\n * @param eventName The event name to listen to\n * @param callback The callback to invoke when the event is emitted\n */\n protected onBus<BusType, BusEventKey extends keyof BusType>(\n bus: Bus<BusType>,\n eventName: BusEventKey,\n callback: (detail: Primitive<BusType[BusEventKey]>) => void\n ): void {\n bus.register(eventName, callback, this.killSignal);\n }\n\n /**\n * Creates getters for the specified attributes on the component.\n * This method allows you to define a list of attribute names and automatically\n * creates corresponding getters that retrieve the attribute values.\n * @param attributes The list of attribute names to create getters for\n * @returns An object with getters for the specified attributes\n */\n protected useAttributes<Attr extends string>(...attributes: Attr[]): Record<Attr, string | null> {\n return attributes.reduce(\n (acc, name) => {\n Object.defineProperty(acc, name, {\n enumerable: true,\n get: () => this.getAttribute(name),\n });\n return acc;\n },\n {} as Record<Attr, string | null>\n );\n }\n\n /**\n * Creates a handler for events on the component.\n * This handler allows registering and emitting events in a type-safe manner.\n * @template EventTypes The type of events to handle\n * @returns An object with methods to register and emit events\n * @example\n * // Typescript usage:\n * const events = this.useEvents<{ someEvent: string }>();\n * events.register('someEvent', (detail) => {\n * console.log('Event detail:', detail);\n * });\n * events.emit('someEvent', 'Hello World');\n *\n * // Javascript usage:\n * const events = this.useEvents({someEvent: String});\n * events.register('someEvent', (detail) => {\n * console.log('Event detail:', detail);\n * });\n * events.emit('someEvent', 'Hello World');\n */\n protected useEvents<EventTypes>(\n _schema?: {\n [EventName in keyof EventTypes]: Constructor<EventTypes[EventName]> | undefined;\n }\n ): Readonly<UseEventsHandler<EventTypes>> {\n return Object.freeze({\n emit: <EventName extends keyof EventTypes>(\n eventName: EventName,\n ...params: OptionalIfUndefined<Primitive<EventTypes[EventName]>>\n ): void => {\n this.dispatchEvent(new CustomEvent(eventName as string, { detail: params[0] }));\n },\n register: <EventName extends keyof EventTypes>(\n eventName: EventName,\n callback: (detail: Primitive<EventTypes[EventName]>) => void\n ): void => {\n const listener = ({ detail }: CustomEvent<Primitive<EventTypes[EventName]>>) => callback(detail);\n this.addEventListener(eventName as string, listener as EventListener, {\n signal: this.killSignal,\n });\n },\n });\n }\n\n /**\n * Registers a callback for a specific event on an element.\n * @param element The element to listen for events on\n * @param eventName The event key to listen for\n * @param callback The callback to invoke when the event is emitted\n */\n protected on<Element extends HTMLElement, EventName extends keyof HTMLElementEventMap>(\n element: Element,\n eventName: EventName,\n callback: (event: HTMLElementEventMap[EventName]) => void\n ): void {\n element.addEventListener(eventName as string, callback as EventListener, {\n signal: this.killSignal,\n });\n }\n\n /**\n * Creates references to elements within the component's template.\n * This method allows you to define a mapping of element names to query selectors,\n * and it will return an object with getters for each element.\n * @template ElementMap A record mapping element names to their corresponding HTMLElement types\n * @param mapFn A function that takes a ref function and returns a mapping of element names to query selectors\n * @returns An object with getters for each referenced element\n * @throws Will throw an error if the element is not found\n * @example\n * const refs = this.useRefs((ref) => ({\n * button: ref('button'),\n * input: ref<HTMLInputElement>('input.my-input'),\n * }));\n *\n * // Usage:\n * refs.button.addEventListener('click', () => { ... });\n */\n protected useRefs<ElementMap extends Record<string, HTMLElement>>(\n mapFn: (\n ref: <Element extends HTMLElement = HTMLElement, Tag extends keyof HTMLElementTagNameMap | string = string>(\n query: Tag\n ) => SelectorToElementWithFallback<Tag, Element>\n ) => ElementMap\n ): Readonly<ElementMap> {\n // Call mapFn with a dummy ref that just returns the query string\n // This allows us to extract the structure of the queries\n const structure = mapFn(\n <Element extends HTMLElement, Tag extends keyof HTMLElementTagNameMap | string = string>(query: Tag) =>\n query as unknown as Element\n );\n\n return Object.freeze(\n Object.entries(structure).reduce((acc, [key, query]) => {\n Object.defineProperty(acc, key as keyof ElementMap, {\n configurable: false,\n enumerable: true,\n get: () => this.getElement(query as unknown as string),\n });\n return acc;\n }, {} as ElementMap)\n );\n }\n\n /**\n * Creates a change handler variable.\n * @param initialValue The initial value of the change handler variable\n * @param onChange A callback function that is called when the change handler variable changes\n * @param options Optional configuration for the change handler\n * @returns An object with `get` and `set` methods for the change handler variable\n */\n protected useChange<T>(\n initialValue: T,\n onChange: (newValue: T, oldValue: T) => void,\n { immediate = false }: ChangeOptions = {}\n ): Readonly<ChangeHandler<T>> {\n if (immediate) {\n if (this._isConnected) {\n onChange(initialValue, initialValue);\n } else {\n this.onConnectActions.push(() => {\n onChange(initialValue, initialValue);\n });\n }\n }\n return new ChangeHandler<T>(initialValue, onChange);\n }\n\n private buildTemplate(): DocumentFragment {\n const style = document.createElement('style');\n style.textContent = this.templateCss?.() ?? '';\n\n const fragment = document.createDocumentFragment();\n fragment.appendChild(style);\n\n const htmlContent = this.templateHtml?.();\n if (htmlContent) {\n fragment.appendChild(htmlContent);\n }\n\n return fragment;\n }\n\n private static get typeOfClass(): JadisConstructor {\n return this.prototype.constructor as JadisConstructor;\n }\n}\n","import type { Constructor, OptionalIfUndefined, Primitive } from './type.helper';\n\n/**\n * A bus for handling events in a type-safe manner.\n * It allows registering and emitting events with specific types.\n */\nexport class Bus<T> {\n private readonly _domElement = document.createElement('div');\n\n // biome-ignore lint/complexity/noUselessConstructor: Needed for typing\n constructor(_schema?: { [K in keyof T]: Constructor<T[K]> | undefined }) {} // NOSONAR\n\n /**\n * Registers a callback for a specific event.\n * @param event The event key to listen for\n * @param callback The callback to invoke when the event is emitted\n * @param signal The AbortSignal to cancel the listener\n */\n register<K extends keyof T>(event: K, callback: (detail: Primitive<T[K]>) => void, signal: AbortSignal): void {\n const listener = ({ detail }: CustomEvent<Primitive<T[K]>>) => callback(detail);\n this._domElement.addEventListener(event as string, listener as EventListener, { signal });\n }\n\n /**\n * Emits an event on the bus.\n * @param event The event key to emit\n * @param params The parameters to include with the event\n */\n emit<K extends keyof T>(event: K, ...params: OptionalIfUndefined<Primitive<T[K]>>): void {\n this._domElement.dispatchEvent(new CustomEvent(event as string, { detail: params[0] }));\n }\n}\n","import { assert } from './assert.helper';\n\nimport type { ComponentSelector } from './type.helper';\n\n/**\n * Checks if a string is a valid component selector.\n * @param key The string to check\n * @returns True if the string is a valid component selector, false otherwise\n */\nexport function isComponentSelector(key: string): key is ComponentSelector {\n return key.includes('-');\n}\n\n/**\n * Creates a component selector from a string.\n * @param name The name of the component. It must contain a hyphen.\n * @throws Will throw an error if the name does not contain a hyphen.\n * @returns The component selector\n */\nexport const createSelector = (name: string): ComponentSelector => {\n assert(isComponentSelector(name), `Custom element name must contain a hyphen: ${name}`);\n return name;\n};\n","import type {\n FlattenRouteGroup,\n FlattenRoutes,\n Path,\n RouteDefinition,\n RouteOptions,\n RouteTree,\n} from '../types/router.type';\n\nexport function isRouteDef(obj: any): obj is RouteDefinition {\n return obj && typeof obj.path === 'string' && typeof obj.page === 'function';\n}\n\n/**\n * Formats a URL path by normalizing slashes.\n * @param path The URL path to format.\n * @returns The formatted URL path.\n */\nexport function normalizePath(path: string): Path {\n return `/${path}`.replace(/\\/{2,}/g, '/').replace(/(?<=.)\\/$/, '') as Path;\n}\n\nfunction formatRouteKey<P extends string, K extends string>(prefix: P, key: K): string {\n return !prefix ? key : `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n}\n\nfunction flattenRoutes<const T extends Record<string, RouteDefinition | RouteTree>>(\n routes: T,\n prefix = ''\n): Record<string, RouteDefinition> {\n const result: Record<string, RouteDefinition> = {};\n\n for (const [key, value] of Object.entries(routes)) {\n const nextKey = formatRouteKey(prefix, key);\n\n if (isRouteDef(value)) {\n result[nextKey] = {\n ...value,\n path: normalizePath(value.path),\n };\n } else {\n Object.assign(result, flattenRoutes(value, nextKey));\n }\n }\n\n return result;\n}\n\n/**\n * Defines routes by normalizing their paths.\n * @param routes A record of route definitions or nested route trees.\n * @returns A flattened and normalized route map.\n */\nexport function defineRoutes<const Tree extends Record<string, RouteDefinition | RouteTree>>(\n routes: Tree\n): FlattenRoutes<Tree> {\n return flattenRoutes(routes) as FlattenRoutes<Tree>;\n}\n\n/**\n * Defines a route group with a common prefix.\n * @param prefix The common prefix for all routes in the group.\n * @param routes A record of route definitions or nested route trees.\n * @param options Optional route options to apply to all routes in the group.\n * @returns A new route tree with the prefix applied to all paths.\n */\nexport function defineRouteGroup<const Prefix extends Path, const Tree extends RouteTree>(\n prefix: Prefix,\n routes: Tree,\n options?: RouteOptions\n): FlattenRouteGroup<Prefix, Tree> {\n const normalizedPrefix = normalizePath(prefix);\n\n return Object.fromEntries(\n Object.entries(routes).map(([key, value]) => {\n return isRouteDef(value)\n ? [\n key,\n {\n options: { ...options, ...value.options },\n page: value.page,\n path: `${normalizedPrefix}${value.path}` as const,\n },\n ]\n : [key, defineRouteGroup(normalizedPrefix, value, options)];\n })\n );\n}\n","import { createElement } from './element.helper';\n\nimport type { HtmlMarkupValue } from './type.helper';\n\ntype HtmlMarkupResult = {\n markup: string;\n markers: Record<string, Node>;\n};\n\n/**\n * A helper for creating HTML templates using tagged template literals.\n * It allows for easy creation of HTML structures with interpolation.\n * @example\n * const template = html`\n * <div class=\"my-class\">\n * <p>${content}</p>\n * </div>\n * `;\n * @returns A DocumentFragment containing the HTML structure\n * @throws Will throw an error if the template contains invalid HTML.\n */\nexport function html(strings: TemplateStringsArray | string, ...values: Array<HtmlMarkupValue>): DocumentFragment {\n const { markup, markers } = htmlMarkup(strings, ...values);\n const templateEl = createElement('template');\n templateEl.innerHTML = markup;\n\n const content = templateEl.content;\n const walker = document.createTreeWalker(content, NodeFilter.SHOW_COMMENT);\n const updates: Array<{ target: Node; replacement: Node }> = [];\n\n while (walker.nextNode()) {\n const node = walker.currentNode;\n const match = markers[node.nodeValue?.trim() ?? ''];\n if (match && node.parentNode) {\n updates.push({ replacement: match, target: node });\n }\n }\n\n updates.forEach(({ target, replacement }) => {\n target.parentNode?.replaceChild(replacement, target);\n });\n\n return content;\n}\n\n/**\n * A helper for creating CSS styles using tagged template literals.\n * It allows for easy creation of CSS styles with interpolation.\n * @example\n * const styles = css`\n * .my-class {\n * color: red;\n * }\n * `;\n * @returns The concatenated CSS string\n */\nexport const css = (strings: TemplateStringsArray, ...args: Array<string | number | boolean>): string => {\n return strings.reduce((acc, curr, index) => `${acc}${curr}${args[index] ?? ''}`, '');\n};\n\nfunction createMarker(node: Node | Array<Node>, k1: number): HtmlMarkupResult {\n const key = `marker-${k1}`;\n\n return Array.isArray(node)\n ? node.reduce(\n (acc, n, k2) => ({\n markers: { ...acc.markers, [`${key}-${k2}`]: n },\n markup: `${acc.markup}<!--${key}-${k2}-->`,\n }),\n { markers: {}, markup: '' }\n )\n : {\n markers: { [key]: node },\n markup: `<!--${key}-->`,\n };\n}\n\nfunction htmlMarkup(strings: TemplateStringsArray | string, ...values: Array<HtmlMarkupValue>): HtmlMarkupResult {\n if (typeof strings === 'string') {\n return { markers: {}, markup: strings };\n }\n\n return strings.reduce(\n (acc: HtmlMarkupResult, str, k1) => {\n const val = values[k1];\n\n if (val instanceof Node || Array.isArray(val)) {\n const { markers, markup } = createMarker(val, k1);\n return {\n markers: { ...acc.markers, ...markers },\n markup: `${acc.markup}${str}${markup}`,\n };\n }\n\n return {\n markers: acc.markers,\n markup: `${acc.markup}${str}${String(val ?? '')}`,\n };\n },\n { markers: {}, markup: '' }\n );\n}\n","export const COMPONENT_SELECTOR_SEPARATOR = ';';\nexport const ROUTER_PARAMETER_PREFIX = ':';\n","import { assert } from '../helpers/assert.helper';\nimport { createElement } from '../helpers/element.helper';\nimport { normalizePath } from '../helpers/router.helper';\nimport { COMPONENT_SELECTOR_SEPARATOR, ROUTER_PARAMETER_PREFIX } from './router-constants';\n\nimport type {\n ExtractParams,\n InternalRoute,\n MatchedRoute,\n Route,\n RouteDefinition,\n RouterMode,\n RouterOptions,\n} from '../types/router.type';\n\nconst defaultOptions: Required<RouterOptions> = {\n baseUrl: '/',\n mode: 'history',\n};\n\n/**\n * Router class for managing navigation and routing in a web application.\n * It supports both hash and history modes for navigation.\n * It allows defining routes, navigating to them, and mounting components based on the current URL.\n */\nexport class Router<T extends Record<string, RouteDefinition>> {\n private readonly _routes: Array<InternalRoute> = [];\n private readonly _mode: RouterMode;\n private readonly _baseUrl: string;\n private readonly _parametersRegexp = new RegExp(`${ROUTER_PARAMETER_PREFIX}\\\\w+`, 'g');\n private _mount?: HTMLElement;\n private _currentRoute?: Route;\n\n constructor(routes: T, options?: RouterOptions) {\n this._mode = options?.mode ?? defaultOptions.mode;\n this._baseUrl = options?.baseUrl ?? defaultOptions.baseUrl;\n this._routes = Object.entries(routes).map(([name, def]) => {\n const path = normalizePath(`/${def.path}`);\n const pathWithoutParameters = path.replace(this._parametersRegexp, '(.+)');\n return {\n componentSelector: [def.options?.rootComponentSelector, def.page.selector]\n .filter(Boolean)\n .join(COMPONENT_SELECTOR_SEPARATOR),\n name,\n path,\n regexp: new RegExp(`^${pathWithoutParameters}$`),\n };\n });\n\n window.addEventListener(this.eventName, (evt) => {\n evt.preventDefault();\n this.onUrlChange();\n });\n }\n\n /**\n * Gets the router configuration.\n * @returns {Required<RouterOptions>} The router configuration including mode and baseUrl\n */\n get config(): Required<RouterOptions> {\n return {\n baseUrl: this._baseUrl,\n mode: this._mode,\n };\n }\n\n /**\n * Gets the current route.\n * @throws Will throw an error if no route is found\n * @returns {Route} The current route\n */\n get currentRoute(): Route {\n assert(this._currentRoute, 'No route found');\n return this._currentRoute;\n }\n\n /**\n * Mounts the router on a specific HTML element.\n * @param {HTMLElement} el The element to mount the router on\n */\n mountOn(el: HTMLElement) {\n this._mount = el;\n this.onUrlChange();\n }\n\n /**\n * Navigates to a route by its name.\n * @param {string} name The name of the route to navigate to\n * @param {Record<string, string>} [params] The parameters to include with the route\n */\n goto<K extends keyof T>(name: K & (keyof ExtractParams<T[K]['path']> extends never ? K : never)): void;\n goto<K extends keyof T>(\n name: K & (keyof ExtractParams<T[K]['path']> extends never ? never : K),\n params: ExtractParams<T[K]['path']>\n ): void;\n goto(name: keyof T, params?: Record<string, string>) {\n const route = this.getRouteByName(String(name));\n assert(route, `No route found for name: ${String(name)}`);\n\n this.gotoPath(this.buildPath(route.path, params));\n }\n\n private get baseUrl(): string {\n return normalizePath(this._baseUrl);\n }\n\n private get mountPoint(): HTMLElement {\n assert(this._mount, 'No mount point defined');\n return this._mount;\n }\n\n private get eventName() {\n return this._mode === 'hash' ? 'hashchange' : 'popstate';\n }\n\n private get currentUrlPath() {\n const formattedPath = window.location.pathname.startsWith(this.baseUrl)\n ? window.location.pathname.slice(this.baseUrl.length)\n : window.location.pathname;\n const path = this._mode === 'hash' ? window.location.hash.slice(1) : formattedPath;\n return normalizePath(path);\n }\n\n private gotoPath(path: string) {\n const urlPath = this._mode === 'hash' ? `#${path}` : path;\n window.history.pushState({}, '', normalizePath(`${this.baseUrl}/${urlPath}`));\n this.onUrlChange();\n }\n\n private onUrlChange() {\n const urlPath = this.currentUrlPath;\n\n const matchedRoute = this.getRouteByPath(urlPath);\n assert(matchedRoute, `No route found for path: ${urlPath}`);\n this._currentRoute = matchedRoute;\n\n const component = this.getComponentToLoad({ ...matchedRoute, urlPath });\n this.mountPoint.replaceChildren(component);\n }\n\n private buildPath(routePath: string, params: Record<string, string> = {}): string {\n const path = this.extractPathParams(routePath).reduce((acc, param) => {\n assert(Object.hasOwn(params, param), `Missing parameter \"${param}\" for path: ${routePath}`);\n return acc.replace(`${ROUTER_PARAMETER_PREFIX}${param}`, params[param]);\n }, routePath);\n return normalizePath(path);\n }\n\n private getComponentToLoad(matchedRoute: MatchedRoute): Node {\n const { componentSelector } = matchedRoute;\n const params = this.getRouteParameters(matchedRoute);\n\n const [rootComponent, ...childComponents] = componentSelector.split(COMPONENT_SELECTOR_SEPARATOR);\n const rootElement = createElement(rootComponent, { attrs: params });\n childComponents.reduce((parent, selector) => createElement(selector, { attrs: params }, parent), rootElement);\n return rootElement;\n }\n\n private getRouteParameters(matchedRoute: MatchedRoute): Record<string, string> {\n const { urlPath, regexp, path } = matchedRoute;\n\n const match = regexp.exec(urlPath);\n assert(match, `No match found for path: ${urlPath}`);\n\n return this.extractPathParams(path).reduce<Record<string, string>>((acc, param, index) => {\n acc[param] = match[index + 1];\n return acc;\n }, {});\n }\n\n private getRouteByName(name: string): InternalRoute | null {\n return this._routes.find(({ name: routeName }) => routeName === name) ?? null;\n }\n\n private getRouteByPath(path: string): InternalRoute | null {\n return this._routes.find(({ regexp }) => regexp.test(path)) ?? null;\n }\n\n private extractPathParams(path: string): Array<string> {\n return path.split('/').reduce<Array<string>>((acc, part) => {\n if (part.startsWith(ROUTER_PARAMETER_PREFIX)) {\n acc.push(part.slice(ROUTER_PARAMETER_PREFIX.length));\n }\n return acc;\n }, []);\n }\n}\n"],"names":[],"mappings":"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"}