@seahax/elemental
Advanced tools
@@ -55,6 +55,6 @@ import { useRef as e } from "../hooks/useRef.js"; | ||
| if (f?.component === e.component && f.pattern === e.pattern) { | ||
| i(f.element, e.config); | ||
| i(f.element, e.config, e.children); | ||
| return; | ||
| } | ||
| let n = i(e.component, e.config); | ||
| let n = i(e.component, e.config, e.children); | ||
| i(t, [n]), f = { | ||
@@ -61,0 +61,0 @@ component: e.component, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"defineRouterComponent.js","names":[],"sources":["../../src/router/defineRouterComponent.ts"],"sourcesContent":["import { type ComponentConstructor, defineComponent } from '../defineComponent.ts';\nimport { useEffect } from '../hooks/useEffect.ts';\nimport { useLocationHref } from '../hooks/useLocationHref.ts';\nimport { useRef } from '../hooks/useRef.ts';\nimport { type ChildValue, html, type HtmlConfig } from '../html.ts';\nimport { compareRouteMatches } from './compareRouteMatches.ts';\nimport type { RouterOptions } from './defineRouter.ts';\nimport { parsePath } from './parsePath.ts';\n\ninterface Route {\n readonly component: CustomElementConstructor;\n readonly config: (pathParams: Record<string, string>, searchParams?: URLSearchParams) => HtmlConfig<HTMLElement>;\n readonly matcher: (segments: readonly string[]) => Record<string, string> | null;\n}\n\nexport interface RouteMatch {\n readonly component: CustomElementConstructor;\n readonly config: HtmlConfig<HTMLElement>;\n readonly children: readonly ChildValue[];\n readonly pattern: string;\n}\n\nexport function defineRouterComponent(\n routeEntries: ReadonlyMap<`/${string}`, Route>,\n { fallback, invalid, ...options }: RouterOptions = {},\n): ComponentConstructor<{}> {\n return defineComponent(\n (shadow) => {\n const href = useLocationHref();\n const routeMatch = useRef<RouteMatch | null>(null, { compare: compareRouteMatches });\n\n let prev:\n | { readonly component: CustomElementConstructor; readonly pattern: string; readonly element: HTMLElement }\n | undefined;\n\n useEffect([href], (href) => {\n const url = new URL(href);\n const segments = parsePath(url.pathname);\n\n for (const [pattern, { component, config, matcher }] of routeEntries.entries()) {\n const pathParams = matcher(segments);\n\n if (pathParams) {\n const searchParams = config.length >= 2 ? new URLSearchParams(url.search) : undefined;\n try {\n const resolvedConfig = config(pathParams, searchParams);\n routeMatch.value = { pattern, component, config: resolvedConfig, children: [] };\n return;\n } catch (error) {\n if (invalid) {\n routeMatch.value = {\n component: invalid,\n pattern: 'invalid',\n config: {\n 'data-error-name': error instanceof Error ? error.name : null,\n 'data-error-code': typeof (error as any)?.code === 'string' ? (error as any).code : null,\n },\n children: [error instanceof Error ? error.message : String(error)],\n };\n\n return;\n }\n\n console.warn(error);\n }\n }\n }\n\n routeMatch.value = fallback ? { component: fallback, pattern: 'fallback', config: {}, children: [] } : null;\n });\n\n useEffect([routeMatch], (routeMatch) => {\n if (!routeMatch) {\n html(shadow, []);\n return;\n }\n\n if (prev?.component === routeMatch.component && prev.pattern === routeMatch.pattern) {\n html(prev.element, routeMatch.config);\n return;\n }\n\n const element = html(routeMatch.component, routeMatch.config);\n html(shadow, [element]);\n prev = { component: routeMatch.component, pattern: routeMatch.pattern, element };\n });\n },\n { ...options, styles: [':host{display:contents;}'] },\n );\n}\n"],"mappings":";;;;;;;;AAsBA,SAAgB,EACd,GACA,EAAE,aAAU,YAAS,GAAG,MAA2B,EAAE,EAC3B;AAC1B,QAAO,GACJ,MAAW;EACV,IAAM,IAAO,GAAiB,EACxB,IAAa,EAA0B,MAAM,EAAE,SAAS,GAAqB,CAAC,EAEhF;AAwCJ,EApCA,EAAU,CAAC,EAAK,GAAG,MAAS;GAC1B,IAAM,IAAM,IAAI,IAAI,EAAK,EACnB,IAAW,EAAU,EAAI,SAAS;AAExC,QAAK,IAAM,CAAC,GAAS,EAAE,cAAW,WAAQ,iBAAc,EAAa,SAAS,EAAE;IAC9E,IAAM,IAAa,EAAQ,EAAS;AAEpC,QAAI,GAAY;KACd,IAAM,IAAe,EAAO,UAAU,IAAI,IAAI,gBAAgB,EAAI,OAAO,GAAG,KAAA;AAC5E,SAAI;AAEF,QAAW,QAAQ;OAAE;OAAS;OAAW,QADlB,EAAO,GAAY,EACO;OAAgB,UAAU,EAAE;OAAE;AAC/E;cACO,GAAO;AACd,UAAI,GAAS;AACX,SAAW,QAAQ;QACjB,WAAW;QACX,SAAS;QACT,QAAQ;SACN,mBAAmB,aAAiB,QAAQ,EAAM,OAAO;SACzD,mBAAmB,OAAQ,GAAe,QAAS,WAAY,EAAc,OAAO;SACrF;QACD,UAAU,CAAC,aAAiB,QAAQ,EAAM,UAAU,OAAO,EAAM,CAAC;QACnE;AAED;;AAGF,cAAQ,KAAK,EAAM;;;;AAKzB,KAAW,QAAQ,IAAW;IAAE,WAAW;IAAU,SAAS;IAAY,QAAQ,EAAE;IAAE,UAAU,EAAE;IAAE,GAAG;IACvG,EAEF,EAAU,CAAC,EAAW,GAAG,MAAe;AACtC,OAAI,CAAC,GAAY;AACf,MAAK,GAAQ,EAAE,CAAC;AAChB;;AAGF,OAAI,GAAM,cAAc,EAAW,aAAa,EAAK,YAAY,EAAW,SAAS;AACnF,MAAK,EAAK,SAAS,EAAW,OAAO;AACrC;;GAGF,IAAM,IAAU,EAAK,EAAW,WAAW,EAAW,OAAO;AAE7D,GADA,EAAK,GAAQ,CAAC,EAAQ,CAAC,EACvB,IAAO;IAAE,WAAW,EAAW;IAAW,SAAS,EAAW;IAAS;IAAS;IAChF;IAEJ;EAAE,GAAG;EAAS,QAAQ,CAAC,2BAA2B;EAAE,CACrD"} | ||
| {"version":3,"file":"defineRouterComponent.js","names":[],"sources":["../../src/router/defineRouterComponent.ts"],"sourcesContent":["import { type ComponentConstructor, defineComponent } from '../defineComponent.ts';\nimport { useEffect } from '../hooks/useEffect.ts';\nimport { useLocationHref } from '../hooks/useLocationHref.ts';\nimport { useRef } from '../hooks/useRef.ts';\nimport { type ChildValue, html, type HtmlConfig } from '../html.ts';\nimport { compareRouteMatches } from './compareRouteMatches.ts';\nimport type { RouterOptions } from './defineRouter.ts';\nimport { parsePath } from './parsePath.ts';\n\ninterface Route {\n readonly component: CustomElementConstructor;\n readonly config: (pathParams: Record<string, string>, searchParams?: URLSearchParams) => HtmlConfig<HTMLElement>;\n readonly matcher: (segments: readonly string[]) => Record<string, string> | null;\n}\n\nexport interface RouteMatch {\n readonly component: CustomElementConstructor;\n readonly config: HtmlConfig<HTMLElement>;\n readonly children: readonly ChildValue[];\n readonly pattern: string;\n}\n\nexport function defineRouterComponent(\n routeEntries: ReadonlyMap<`/${string}`, Route>,\n { fallback, invalid, ...options }: RouterOptions = {},\n): ComponentConstructor<{}> {\n return defineComponent(\n (shadow) => {\n const href = useLocationHref();\n const routeMatch = useRef<RouteMatch | null>(null, { compare: compareRouteMatches });\n\n let prev:\n | { readonly component: CustomElementConstructor; readonly pattern: string; readonly element: HTMLElement }\n | undefined;\n\n useEffect([href], (href) => {\n const url = new URL(href);\n const segments = parsePath(url.pathname);\n\n for (const [pattern, { component, config, matcher }] of routeEntries.entries()) {\n const pathParams = matcher(segments);\n\n if (pathParams) {\n const searchParams = config.length >= 2 ? new URLSearchParams(url.search) : undefined;\n try {\n const resolvedConfig = config(pathParams, searchParams);\n routeMatch.value = { pattern, component, config: resolvedConfig, children: [] };\n return;\n } catch (error) {\n if (invalid) {\n routeMatch.value = {\n component: invalid,\n pattern: 'invalid',\n config: {\n 'data-error-name': error instanceof Error ? error.name : null,\n 'data-error-code': typeof (error as any)?.code === 'string' ? (error as any).code : null,\n },\n children: [error instanceof Error ? error.message : String(error)],\n };\n\n return;\n }\n\n console.warn(error);\n }\n }\n }\n\n routeMatch.value = fallback ? { component: fallback, pattern: 'fallback', config: {}, children: [] } : null;\n });\n\n useEffect([routeMatch], (routeMatch) => {\n if (!routeMatch) {\n html(shadow, []);\n return;\n }\n\n if (prev?.component === routeMatch.component && prev.pattern === routeMatch.pattern) {\n html(prev.element, routeMatch.config, routeMatch.children);\n return;\n }\n\n const element = html(routeMatch.component, routeMatch.config, routeMatch.children);\n html(shadow, [element]);\n prev = { component: routeMatch.component, pattern: routeMatch.pattern, element };\n });\n },\n { ...options, styles: [':host{display:contents;}'] },\n );\n}\n"],"mappings":";;;;;;;;AAsBA,SAAgB,EACd,GACA,EAAE,aAAU,YAAS,GAAG,MAA2B,EAAE,EAC3B;AAC1B,QAAO,GACJ,MAAW;EACV,IAAM,IAAO,GAAiB,EACxB,IAAa,EAA0B,MAAM,EAAE,SAAS,GAAqB,CAAC,EAEhF;AAwCJ,EApCA,EAAU,CAAC,EAAK,GAAG,MAAS;GAC1B,IAAM,IAAM,IAAI,IAAI,EAAK,EACnB,IAAW,EAAU,EAAI,SAAS;AAExC,QAAK,IAAM,CAAC,GAAS,EAAE,cAAW,WAAQ,iBAAc,EAAa,SAAS,EAAE;IAC9E,IAAM,IAAa,EAAQ,EAAS;AAEpC,QAAI,GAAY;KACd,IAAM,IAAe,EAAO,UAAU,IAAI,IAAI,gBAAgB,EAAI,OAAO,GAAG,KAAA;AAC5E,SAAI;AAEF,QAAW,QAAQ;OAAE;OAAS;OAAW,QADlB,EAAO,GAAY,EACO;OAAgB,UAAU,EAAE;OAAE;AAC/E;cACO,GAAO;AACd,UAAI,GAAS;AACX,SAAW,QAAQ;QACjB,WAAW;QACX,SAAS;QACT,QAAQ;SACN,mBAAmB,aAAiB,QAAQ,EAAM,OAAO;SACzD,mBAAmB,OAAQ,GAAe,QAAS,WAAY,EAAc,OAAO;SACrF;QACD,UAAU,CAAC,aAAiB,QAAQ,EAAM,UAAU,OAAO,EAAM,CAAC;QACnE;AAED;;AAGF,cAAQ,KAAK,EAAM;;;;AAKzB,KAAW,QAAQ,IAAW;IAAE,WAAW;IAAU,SAAS;IAAY,QAAQ,EAAE;IAAE,UAAU,EAAE;IAAE,GAAG;IACvG,EAEF,EAAU,CAAC,EAAW,GAAG,MAAe;AACtC,OAAI,CAAC,GAAY;AACf,MAAK,GAAQ,EAAE,CAAC;AAChB;;AAGF,OAAI,GAAM,cAAc,EAAW,aAAa,EAAK,YAAY,EAAW,SAAS;AACnF,MAAK,EAAK,SAAS,EAAW,QAAQ,EAAW,SAAS;AAC1D;;GAGF,IAAM,IAAU,EAAK,EAAW,WAAW,EAAW,QAAQ,EAAW,SAAS;AAElF,GADA,EAAK,GAAQ,CAAC,EAAQ,CAAC,EACvB,IAAO;IAAE,WAAW,EAAW;IAAW,SAAS,EAAW;IAAS;IAAS;IAChF;IAEJ;EAAE,GAAG;EAAS,QAAQ,CAAC,2BAA2B;EAAE,CACrD"} |
+1
-1
@@ -28,3 +28,3 @@ { | ||
| }, | ||
| "version": "0.8.2" | ||
| "version": "0.8.3" | ||
| } |
112277
0.08%