@wcstack/router 1.22.6 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +17 -0
- package/dist/index.esm.js +51 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.min.js","sources":["../../src/config.ts","../../src/getUUID.ts","../../src/raiseError.ts","../../src/GuardCancel.ts","../../src/builtinParamTypes.ts","../../src/core/RouteCore.ts","../../src/components/Route.ts","../../src/components/Layout.ts","../../src/components/Outlet.ts","../../src/assignParams.ts","../../src/getCustomTagName.ts","../../src/components/LayoutOutlet.ts","../../src/loadGuardHandler.ts","../../src/parse.ts","../../src/matchRoutes.ts","../../src/testPath.ts","../../src/hideRoute.ts","../../src/showRoute.ts","../../src/applyRoute.ts","../../src/showRouteContent.ts","../../src/Navigation.ts","../../src/normalizePathname.ts","../../src/components/Router.ts","../../src/components/Link.ts","../../src/components/Head.ts","../../src/registerComponents.ts","../../src/bootstrapRouter.ts","../../src/version.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types\";\n\ninterface IInternalConfig {\n tagNames: {\n route: string;\n router: string;\n outlet: string;\n layout: string;\n layoutOutlet: string;\n link: string;\n head: string;\n guardHandler: string;\n };\n enableShadowRoot: boolean;\n basenameFileExtensions: string[];\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n route: \"wcs-route\",\n router: \"wcs-router\",\n outlet: \"wcs-outlet\",\n layout: \"wcs-layout\",\n layoutOutlet: \"wcs-layout-outlet\",\n link: \"wcs-link\",\n head: \"wcs-head\",\n guardHandler: \"wcs-guard-handler\"\n },\n enableShadowRoot: false,\n basenameFileExtensions: [\".html\"]\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// 後方互換のため config もエクスポート(読み取り専用として使用)\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n if (typeof partialConfig.enableShadowRoot === \"boolean\") {\n _config.enableShadowRoot = partialConfig.enableShadowRoot;\n }\n if (Array.isArray(partialConfig.basenameFileExtensions)) {\n _config.basenameFileExtensions = partialConfig.basenameFileExtensions;\n }\n frozenConfig = null;\n}\n","\nexport function getUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Simple UUID generator\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}","\nexport function raiseError(message: string, options?: { cause?: unknown }): never {\n if (options && 'cause' in options) {\n throw new Error(`[@wcstack/router] ${message}`, { cause: options.cause });\n }\n throw new Error(`[@wcstack/router] ${message}`);\n}","import { IGuardCancel } from \"./types\";\n\nexport class GuardCancel extends Error implements IGuardCancel {\n fallbackPath: string;\n\n constructor(message: string, fallbackPath: string) {\n super(message);\n this.fallbackPath = fallbackPath;\n }\n}","import { BuiltinParamTypes, IParamTypeInfo } from \"./types\";\n\nexport const builtinParamTypes = {\n \"int\": {\n typeName: \"int\",\n pattern: /^-?\\d+$/,\n parse(value: string): number | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return parseInt(value, 10);\n }\n },\n\n \"float\": {\n typeName: \"float\",\n pattern: /^-?\\d+(?:\\.\\d+)?$/,\n parse(value: string): number | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return parseFloat(value);\n }\n },\n\n \"bool\": {\n typeName: \"bool\",\n pattern: /^(true|false|0|1)$/,\n parse(value: string): boolean | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value === \"true\" || value === \"1\";\n }\n },\n\n \"uuid\": {\n typeName: \"uuid\",\n pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n parse(value: string): string | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value;\n }\n },\n\n \"slug\": {\n typeName: \"slug\",\n pattern: /^[a-z0-9]+(?:-[a-z0-9]+)*$/,\n parse(value: string): string | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value;\n }\n },\n\n \"isoDate\": {\n typeName: \"isoDate\",\n pattern: /^\\d{4}-\\d{2}-\\d{2}$/,\n parse(value: string): Date | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n const [year, month, day] = value.split(\"-\").map(Number);\n const date = new Date(year, month - 1, day);\n // 元の値と一致するか確認(補正されていないか)\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return undefined;\n }\n return date;\n }\n },\n\n \"any\": {\n typeName: \"any\",\n pattern: /^.+$/,\n parse(value: string): string | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value;\n }\n },\n} satisfies Record<BuiltinParamTypes, IParamTypeInfo<unknown>>;\n","import { GuardCancel } from \"../GuardCancel.js\";\nimport { builtinParamTypes } from \"../builtinParamTypes.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { config } from \"../config.js\";\nimport { ISegmentInfo, SegmentType, IRouteMatchResult, GuardHandler } from \"../components/types.js\";\nimport { BuiltinParamTypes, IWcBindable } from \"../types.js\";\n\nconst weights: Record<SegmentType, number> = {\n 'static': 2,\n 'param': 1,\n 'catch-all': 0\n};\n\nexport interface RouteParseOptions {\n isIndex?: boolean;\n isFallback?: boolean;\n hasGuard?: boolean;\n guardFallback?: string | null;\n name?: string;\n}\n\nexport class RouteCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"params\", event: \"wcs-route:params-changed\" },\n { name: \"typedParams\", event: \"wcs-route:params-changed\", getter: (e: Event) => (e as CustomEvent).detail.typedParams },\n { name: \"active\", event: \"wcs-route:active-changed\" },\n ],\n };\n\n private _target: EventTarget;\n private _parentCore: RouteCore | null = null;\n private _path: string = '';\n private _name: string = '';\n private _isFallbackRoute: boolean = false;\n private _segmentInfos: ISegmentInfo[] = [];\n private _absoluteSegmentInfos: ISegmentInfo[] | undefined;\n private _paramNames: string[] | undefined;\n private _absoluteParamNames: string[] | undefined;\n private _weight: number | undefined;\n private _absoluteWeight: number | undefined;\n private _segmentCount: number | undefined;\n private _params: Record<string, string> = {};\n private _typedParams: Record<string, any> = {};\n private _active: boolean = false;\n\n // Guard\n private _hasGuard: boolean = false;\n private _guardHandler: GuardHandler | null = null;\n private _guardFallbackPath: string = '';\n private _waitForSetGuardHandler: Promise<void> | null = null;\n private _resolveSetGuardHandler: (() => void) | null = null;\n private _guardHandlerLoadFailed: boolean = false;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get parentCore(): RouteCore | null {\n return this._parentCore;\n }\n\n set parentCore(value: RouteCore | null) {\n this._parentCore = value;\n }\n\n get path(): string {\n return this._path;\n }\n\n get name(): string {\n return this._name;\n }\n\n get isFallbackRoute(): boolean {\n return this._isFallbackRoute;\n }\n\n get isRelative(): boolean {\n return !this._path.startsWith('/');\n }\n\n get segmentInfos(): ISegmentInfo[] {\n return this._segmentInfos;\n }\n\n private _checkParentCore<T>(\n hasParentCallback: (parentCore: RouteCore) => T,\n noParentCallback: () => T\n ): T {\n if (!this._isFallbackRoute) {\n if (this.isRelative && !this._parentCore) {\n raiseError(`${config.tagNames.route} is relative but has no parent route.`);\n }\n if (!this.isRelative && this._parentCore) {\n raiseError(`${config.tagNames.route} is absolute but has a parent route.`);\n }\n }\n if (this.isRelative && this._parentCore) {\n return hasParentCallback(this._parentCore);\n } else {\n return noParentCallback();\n }\n }\n\n get absolutePath(): string {\n return this._checkParentCore<string>((parentCore) => {\n const parentPath = parentCore.absolutePath;\n return parentPath.endsWith('/')\n ? parentPath + this._path\n : parentPath + '/' + this._path;\n }, () => {\n return this._path;\n });\n }\n\n get absoluteSegmentInfos(): ISegmentInfo[] {\n if (typeof this._absoluteSegmentInfos === 'undefined') {\n this._absoluteSegmentInfos = this._checkParentCore<ISegmentInfo[]>((parentCore) => {\n return [\n ...parentCore.absoluteSegmentInfos,\n ...this._segmentInfos\n ];\n }, () => {\n return [...this._segmentInfos];\n });\n }\n return this._absoluteSegmentInfos;\n }\n\n get params(): Record<string, string> {\n return this._params;\n }\n\n get typedParams(): Record<string, any> {\n return this._typedParams;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get paramNames(): string[] {\n if (typeof this._paramNames === 'undefined') {\n const names: string[] = [];\n for (const info of this._segmentInfos) {\n if (info.paramName) {\n names.push(info.paramName);\n }\n }\n this._paramNames = names;\n }\n return this._paramNames;\n }\n\n get absoluteParamNames(): string[] {\n if (typeof this._absoluteParamNames === 'undefined') {\n this._absoluteParamNames = this._checkParentCore<string[]>((parentCore) => {\n return [\n ...parentCore.absoluteParamNames,\n ...this.paramNames\n ];\n }, () => {\n return [...this.paramNames];\n });\n }\n return this._absoluteParamNames;\n }\n\n get weight(): number {\n if (typeof this._weight === 'undefined') {\n let weight = 0;\n for (const info of this._segmentInfos) {\n weight += weights[info.type];\n }\n this._weight = weight;\n }\n return this._weight;\n }\n\n get absoluteWeight(): number {\n if (typeof this._absoluteWeight === 'undefined') {\n this._absoluteWeight = this._checkParentCore<number>((parentCore) => {\n return parentCore.absoluteWeight + this.weight;\n }, () => {\n return this.weight;\n });\n }\n return this._absoluteWeight;\n }\n\n get segmentCount(): number {\n if (typeof this._segmentCount === 'undefined') {\n let count = 0;\n for (const info of this._segmentInfos) {\n if (info.type !== 'catch-all') {\n count++;\n }\n }\n this._segmentCount = this._path === \"\" ? 0 : count;\n }\n return this._segmentCount;\n }\n\n get absoluteSegmentCount(): number {\n return this._checkParentCore<number>((parentCore) => {\n return parentCore.absoluteSegmentCount + this.segmentCount;\n }, () => {\n return this.segmentCount;\n });\n }\n\n parsePath(path: string, options: RouteParseOptions = {}): void {\n // 連続呼び出し時のセグメント累積を防ぐためリセット\n this._segmentInfos = [];\n this._absoluteSegmentInfos = undefined;\n this._paramNames = undefined;\n this._absoluteParamNames = undefined;\n this._weight = undefined;\n this._absoluteWeight = undefined;\n this._segmentCount = undefined;\n this._path = path;\n this._name = options.name || '';\n this._isFallbackRoute = options.isFallback || false;\n\n if (options.isIndex) {\n this._segmentInfos.push({\n type: 'static',\n segmentText: '',\n paramName: null,\n pattern: /^$/,\n isIndex: true\n });\n }\n\n const segments = path.split('/');\n for (let idx = 0; idx < segments.length; idx++) {\n const segment = segments[idx];\n // 末尾の空セグメントはスキップ(/parent/ のような場合)\n if (segment === '' && idx === segments.length - 1 && idx > 0) {\n continue;\n }\n if (segment === '*') {\n this._segmentInfos.push({\n type: 'catch-all',\n segmentText: segment,\n paramName: '*',\n pattern: new RegExp('^(.*)$')\n });\n // Catch-all: matches remaining path segments\n break; // Ignore subsequent segments\n } else if (segment.startsWith(':')) {\n const matchType = segment.match(/^:([^()]+)(\\(([^)]+)\\))?$/);\n let paramName: string;\n let typeName: BuiltinParamTypes = 'any';\n if (matchType) {\n paramName = matchType[1];\n if (matchType[3] && Object.keys(builtinParamTypes).includes(matchType[3])) {\n typeName = matchType[3] as BuiltinParamTypes;\n }\n } else {\n paramName = segment.substring(1);\n }\n\n this._segmentInfos.push({\n type: 'param',\n segmentText: segment,\n paramName: paramName,\n pattern: new RegExp('^([^\\\\/]+)$'),\n paramType: typeName\n });\n } else if (segment !== '' || !options.isIndex) {\n // 空セグメントはindex以外の場合のみ追加(絶対パスの先頭 '' など)\n this._segmentInfos.push({\n type: 'static',\n segmentText: segment,\n paramName: null,\n pattern: new RegExp(`^${segment}$`)\n });\n }\n }\n\n this._hasGuard = options.hasGuard || false;\n if (this._hasGuard) {\n this._guardFallbackPath = options.guardFallback || '/';\n this._waitForSetGuardHandler = new Promise((resolve) => {\n this._resolveSetGuardHandler = resolve;\n });\n }\n }\n\n setParams(params: Record<string, string>, typedParams: Record<string, any>): void {\n const wasActive = this._active;\n this._params = params;\n this._typedParams = typedParams;\n this._active = true;\n this._target.dispatchEvent(new CustomEvent(\"wcs-route:params-changed\", {\n detail: { params, typedParams },\n bubbles: true,\n }));\n if (!wasActive) {\n this._target.dispatchEvent(new CustomEvent(\"wcs-route:active-changed\", {\n detail: true,\n bubbles: true,\n }));\n }\n }\n\n clearParams(): void {\n const wasActive = this._active;\n this._params = {};\n this._typedParams = {};\n this._active = false;\n if (wasActive) {\n this._target.dispatchEvent(new CustomEvent(\"wcs-route:active-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n shouldChange(newParams: Record<string, string>): boolean {\n for (const key of this.paramNames) {\n if (this._params[key] !== newParams[key]) {\n return true;\n }\n }\n return false;\n }\n\n get guardHandler(): GuardHandler {\n if (!this._guardHandler) {\n raiseError(`${config.tagNames.route} has no guardHandler.`);\n }\n return this._guardHandler!;\n }\n\n set guardHandler(value: GuardHandler) {\n this._guardHandler = value;\n this._resolveSetGuardHandler?.();\n }\n\n /**\n * Guardハンドラのロードに失敗したことを通知し、guardCheck の待ちを解除する。\n * 解除後の guardCheck は guardHandler が未設定のため fallback パスへリダイレクトする。\n */\n notifyGuardHandlerLoadFailed(): void {\n this._guardHandlerLoadFailed = true;\n this._resolveSetGuardHandler?.();\n }\n\n async guardCheck(matchResult: IRouteMatchResult): Promise<void> {\n if (this._hasGuard && this._waitForSetGuardHandler) {\n await this._waitForSetGuardHandler;\n }\n if (this._guardHandler) {\n const toPath = matchResult.path;\n const fromPath = matchResult.lastPath;\n const allowed = await this._guardHandler(toPath, fromPath);\n if (!allowed) {\n throw new GuardCancel('Navigation cancelled by guard.', this._guardFallbackPath);\n }\n } else if (this._hasGuard && this._guardHandlerLoadFailed) {\n // guardHandler のロードに失敗した場合は fallback パスへ\n throw new GuardCancel('Navigation cancelled: guard handler failed to load.', this._guardFallbackPath);\n }\n }\n}\n","import { getUUID } from \"../getUUID.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IRouteMatchResult, IRoute, IRouter, GuardHandler, ISegmentInfo } from \"./types.js\";\nimport { RouteCore } from \"../core/RouteCore.js\";\nimport { IWcBindable } from \"../types.js\";\n\nexport class Route extends HTMLElement implements IRoute {\n static wcBindable: IWcBindable = RouteCore.wcBindable;\n\n private _core: RouteCore;\n private _routeParentNode: IRoute | null = null;\n private _routeChildNodes: IRoute[] = [];\n private _routerNode: IRouter | null = null;\n private _uuid: string = getUUID();\n private _placeHolder: Comment = document.createComment(`@@route:${this._uuid}`);\n private _childNodeArray: Node[] | undefined;\n private _childIndex: number = 0;\n private _initialized: boolean = false;\n private _routes: IRoute[] | undefined;\n\n constructor() {\n super();\n this._core = new RouteCore(this);\n }\n\n // Shell-only properties\n\n get routeParentNode(): IRoute | null {\n return this._routeParentNode;\n }\n\n get routeChildNodes(): IRoute[] {\n return this._routeChildNodes;\n }\n\n get routerNode(): IRouter {\n if (!this._routerNode) {\n raiseError(`${config.tagNames.route} has no routerNode.`);\n }\n return this._routerNode;\n }\n\n get uuid(): string {\n return this._uuid;\n }\n\n get placeHolder(): Comment {\n return this._placeHolder;\n }\n\n get childNodeArray(): Node[] {\n if (typeof this._childNodeArray === 'undefined') {\n this._childNodeArray = Array.from(this.childNodes);\n }\n return this._childNodeArray;\n }\n\n get routes(): IRoute[] {\n // matchRoutes / testPath のホットパスで再帰的に呼ばれるため遅延キャッシュする。\n // initialize 後は routeParentNode が固定されるためキャッシュしても安全。\n if (typeof this._routes === 'undefined') {\n this._routes = this.routeParentNode\n ? this.routeParentNode.routes.concat(this)\n : [this];\n }\n return this._routes;\n }\n\n get childIndex(): number {\n return this._childIndex;\n }\n\n // Core delegates\n\n get path(): string {\n return this._core.path;\n }\n\n get name(): string {\n return this._core.name;\n }\n\n get isRelative(): boolean {\n return this._core.isRelative;\n }\n\n get absolutePath(): string {\n return this._core.absolutePath;\n }\n\n get segmentInfos(): ISegmentInfo[] {\n return this._core.segmentInfos;\n }\n\n get absoluteSegmentInfos(): ISegmentInfo[] {\n return this._core.absoluteSegmentInfos;\n }\n\n get params(): Record<string, string> {\n return this._core.params;\n }\n\n get typedParams(): Record<string, any> {\n return this._core.typedParams;\n }\n\n get paramNames(): string[] {\n return this._core.paramNames;\n }\n\n get absoluteParamNames(): string[] {\n return this._core.absoluteParamNames;\n }\n\n get weight(): number {\n return this._core.weight;\n }\n\n get absoluteWeight(): number {\n return this._core.absoluteWeight;\n }\n\n get segmentCount(): number {\n return this._core.segmentCount;\n }\n\n get absoluteSegmentCount(): number {\n return this._core.absoluteSegmentCount;\n }\n\n get fullpath(): string {\n return this.absolutePath;\n }\n\n get guardHandler(): GuardHandler {\n return this._core.guardHandler;\n }\n\n set guardHandler(value: GuardHandler) {\n this._core.guardHandler = value;\n }\n\n setParams(params: Record<string, string>, typedParams: Record<string, any>): void {\n this._core.setParams(params, typedParams);\n }\n\n clearParams(): void {\n this._core.clearParams();\n }\n\n shouldChange(newParams: Record<string, string>): boolean {\n return this._core.shouldChange(newParams);\n }\n\n async guardCheck(matchResult: IRouteMatchResult): Promise<void> {\n return this._core.guardCheck(matchResult);\n }\n\n notifyGuardHandlerLoadFailed(): void {\n this._core.notifyGuardHandlerLoadFailed();\n }\n\n /**\n * Shell(Route)の routeParentNode を辿って祖先関係を判定する。\n *\n * 責務の分担:\n * - Route(このクラス)は DOM ツリー上の親子関係(routeParentNode)を管理する。\n * - RouteCore はパスやパラメータといった論理的な親子関係(parentCore)を管理する。\n * DOM ツリーは Shell 層、論理ツリーは Core 層という分離のため、両者を独立に保持する。\n */\n testAncestorNode(ancestorNode: IRoute): boolean {\n let currentNode: IRoute | null = this._routeParentNode;\n while (currentNode) {\n if (currentNode === ancestorNode) {\n return true;\n }\n currentNode = currentNode.routeParentNode;\n }\n return false;\n }\n\n initialize(routerNode: IRouter, routeParentNode: IRoute | null): void {\n if (this._initialized) {\n return;\n }\n this._initialized = true;\n\n // 属性からパス情報を読み取り\n let path: string;\n let isIndex = false;\n let isFallback = false;\n\n if (this.hasAttribute('path')) {\n path = this.getAttribute('path') || '';\n } else if (this.hasAttribute('index')) {\n path = '';\n isIndex = true;\n } else if (this.hasAttribute('fallback')) {\n path = '';\n isFallback = true;\n } else {\n raiseError(`${config.tagNames.route} should have a \"path\" or \"index\" attribute.`);\n }\n\n // ルートツリーの構築\n this._routerNode = routerNode;\n this._routeParentNode = routeParentNode;\n const routeChildContainer = routeParentNode || routerNode;\n routeChildContainer.routeChildNodes.push(this);\n this._childIndex = routeChildContainer.routeChildNodes.length - 1;\n\n // Fallback検証\n if (isFallback) {\n if (routeParentNode) {\n raiseError(`${config.tagNames.route} with fallback attribute must be a direct child of ${config.tagNames.router}.`);\n }\n if (routerNode.fallbackRoute) {\n raiseError(`${config.tagNames.router} can have only one fallback route.`);\n }\n routerNode.fallbackRoute = this;\n }\n\n // 親CoreをCoreに設定\n if (routeParentNode) {\n this._core.parentCore = (routeParentNode as Route)._core;\n }\n\n // Coreでパス解析\n this._core.parsePath(path!, {\n isIndex,\n isFallback,\n hasGuard: this.hasAttribute('guard'),\n guardFallback: this.getAttribute('guard'),\n name: this.getAttribute('name') || '',\n });\n\n this.setAttribute('fullpath', this.absolutePath);\n }\n}\n","import { getUUID } from \"../getUUID.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { ILayout } from \"./types.js\";\n\nconst cache = new Map<string, string>();\n\n/**\n * Layout テンプレートキャッシュをクリアする。\n * テストや長時間 SPA でメモリリークを避けるため、リセットしたい場合に利用する。\n */\nexport function _clearLayoutCache(): void {\n cache.clear();\n}\n\nexport class Layout extends HTMLElement implements ILayout {\n private _uuid: string = getUUID();\n constructor() {\n super();\n }\n\n private async _loadTemplateFromSource(source: string): Promise<string> {\n try {\n const response = await fetch(source);\n if (!response.ok) {\n raiseError(`${config.tagNames.layout} failed to fetch layout from source: ${source}, status: ${response.status}`);\n }\n const templateContent = await response.text();\n cache.set(source, templateContent);\n return templateContent;\n } catch (error) {\n // 元の例外を cause として伝播し、スタックトレースを保持する\n raiseError(\n `${config.tagNames.layout} failed to load layout from source: ${source}, error: ${error}`,\n { cause: error }\n );\n }\n }\n\n private _loadTemplateFromDocument(id: string): string | null {\n const element = document.getElementById(`${id}`) as HTMLElement | null;\n if (element) {\n if (element instanceof HTMLTemplateElement) {\n return element.innerHTML;\n }\n }\n return null;\n }\n\n async loadTemplate(): Promise<HTMLTemplateElement> {\n const source = this.getAttribute('src');\n const layoutId = this.getAttribute('layout');\n if (source && layoutId) {\n console.warn(`${config.tagNames.layout} have both \"src\" and \"layout\" attributes.`);\n }\n const template = document.createElement('template');\n if (source) {\n if (cache.has(source)) {\n template.innerHTML = cache.get(source) || '';\n } else {\n // _loadTemplateFromSource は内部で cache.set を実行する\n template.innerHTML = await this._loadTemplateFromSource(source) || '';\n }\n } else if (layoutId) {\n const templateContent = this._loadTemplateFromDocument(layoutId);\n if (templateContent) {\n template.innerHTML = templateContent;\n } else {\n console.warn(`${config.tagNames.layout} could not find template with id \"${layoutId}\".`);\n }\n }\n return template;\n }\n\n get uuid(): string {\n return this._uuid;\n }\n\n get enableShadowRoot(): boolean {\n if (this.hasAttribute('enable-shadow-root')) {\n return true;\n } else if (this.hasAttribute('disable-shadow-root')) {\n return false;\n }\n return config.enableShadowRoot;\n }\n\n get name(): string {\n // Layout 要素が DOM に挿入されないケース(parseで置換)でも name を取れるようにする\n return this.getAttribute('name') || '';\n }\n}\n","import { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IOutlet, IRoute, IRouter } from \"./types.js\";\n\nexport class Outlet extends HTMLElement implements IOutlet {\n private _routesNode: IRouter | null = null;\n private _lastRoutes: IRoute[] = [];\n private _initialized: boolean = false;\n constructor() {\n super();\n }\n\n get routesNode(): IRouter {\n if (!this._routesNode) {\n raiseError(`${config.tagNames.outlet} has no routesNode.`);\n }\n return this._routesNode;\n }\n set routesNode(value: IRouter) {\n this._routesNode = value;\n }\n\n get rootNode(): HTMLElement | ShadowRoot {\n if (this.shadowRoot) {\n return this.shadowRoot;\n }\n return this;\n }\n\n get lastRoutes(): IRoute[] {\n return this._lastRoutes;\n }\n set lastRoutes(value: IRoute[]) {\n this._lastRoutes = [ ...value ];\n }\n\n /**\n * shadowRoot 有効化判定。Layout と挙動を揃え、属性で個別オーバーライド可能にする。\n * - `enable-shadow-root` 属性あり → true\n * - `disable-shadow-root` 属性あり → false\n * - いずれもなし → config.enableShadowRoot を尊重\n */\n private _resolveEnableShadowRoot(): boolean {\n if (this.hasAttribute('enable-shadow-root')) {\n return true;\n }\n if (this.hasAttribute('disable-shadow-root')) {\n return false;\n }\n return config.enableShadowRoot;\n }\n\n private _initialize() {\n if (this._resolveEnableShadowRoot()) {\n this.attachShadow({ mode: 'open' });\n }\n this._initialized = true;\n }\n\n connectedCallback() {\n if (!this._initialized) {\n this._initialize();\n }\n }\n\n /**\n * Outlet が disconnect された際の状態クリーンアップ。\n *\n * `_lastRoutes` をクリアすることで、再接続後の applyRoute における diff\n * (既に show 済みのルートは show を skip する判定)が、切断中に外部から\n * 操作された DOM と整合しなくなる事故を防ぐ。\n *\n * 仕様前提として Outlet は Router と一体運用される(Router が `_getOutlet()` で\n * 自身の兄弟に Outlet を配置・参照する)。それでも単独で再接続される\n * エッジケースに備える防衛的措置として `_lastRoutes` のみクリアする。\n * `_initialized` と shadowRoot は維持し、再 attachShadow による\n * InvalidStateError を回避する。\n */\n disconnectedCallback() {\n this._lastRoutes = [];\n }\n}\n\nexport function createOutlet(): Outlet {\n return document.createElement(config.tagNames.outlet) as Outlet;\n}\n","import { BindType } from \"./components/types\";\nimport { getCustomTagName } from \"./getCustomTagName\";\nimport { raiseError } from \"./raiseError\";\n\nconst bindTypeSet: Set<BindType> = new Set([ \"props\", \"states\", \"attr\", \"\" ]);\n\nfunction _assignParams(element: Element, params: Record<string, any>, bindType: BindType) {\n for(const [key, value] of Object.entries(params)) {\n switch(bindType) {\n case \"props\":\n (element as any).props = {\n ...(element as any).props,\n [key]: value\n };\n break;\n case \"states\":\n (element as any).states = {\n ...(element as any).states,\n [key]: value\n };\n break;\n case \"attr\":\n // null/undefined は属性削除として扱う(文字列 \"null\"/\"undefined\" になる事故を防ぐ)。\n // boolean/number は setAttribute の標準挙動に従って文字列化される。\n if (value === null || value === undefined) {\n element.removeAttribute(key);\n } else {\n element.setAttribute(key, String(value));\n }\n break;\n case \"\":\n (element as any)[key] = value;\n break;\n }\n }\n}\n\nexport function assignParams(element: Element, params: Record<string, any>) {\n if (!element.hasAttribute('data-bind')) {\n raiseError(`${element.tagName} has no 'data-bind' attribute.`);\n }\n const bindTypeText = element.getAttribute('data-bind') || '';\n if (!bindTypeSet.has(bindTypeText as BindType)) {\n raiseError(`${element.tagName} has invalid 'data-bind' attribute: ${bindTypeText}`);\n }\n const bindType = bindTypeText as BindType;\n const customTagName = getCustomTagName(element);\n if (customTagName && customElements.get(customTagName) === undefined) {\n // 注意: customElements.whenDefined(tag) は当該タグが define されるまで pending のままになる。\n // element が削除されてもこの Promise は GC されず、closure に保持される element/params は\n // 解放されない(弱い参照を持つ手段がないため)。define されないまま要素のみが大量に作られる\n // ようなケースではリークになりうるが、通常の Web Components 利用では autoloader が\n // 一括 define するため実用上問題にならない。明示的にキャンセルしたい場合は将来 AbortSignal を\n // サポートすることを検討する。\n customElements.whenDefined(customTagName).then(() => {\n if (element.isConnected) {\n // 要素が削除されていない場合のみ割り当てを行う\n _assignParams(element, params, bindType);\n }\n }).catch(() => {\n raiseError(`Failed to define custom element: ${customTagName}`);\n });\n } else {\n _assignParams(element, params, bindType);\n }\n}","\nexport function getCustomTagName(element: Element): string | null {\n const tagName = element.tagName.toLowerCase();\n if (tagName.includes(\"-\")) {\n return tagName;\n }\n const isAttr = element.getAttribute(\"is\");\n if (isAttr && isAttr.includes(\"-\")) {\n return isAttr;\n }\n return null;\n}","import { assignParams } from \"../assignParams.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { ILayout, ILayoutOutlet } from \"./types.js\";\n\nexport class LayoutOutlet extends HTMLElement implements ILayoutOutlet {\n private _layout: (ILayout & Pick<Element,'childNodes'>) | null = null;\n private _initialized: boolean = false;\n private _initializing: boolean = false;\n private _disconnectedDuringInit: boolean = false;\n private _layoutChildNodes: Node[] = [];\n constructor() {\n super();\n }\n\n get layout(): ILayout {\n if (!this._layout) {\n raiseError(`${config.tagNames.layoutOutlet} has no layout.`);\n }\n return this._layout;\n }\n set layout(value: ILayout) {\n this._layout = value;\n this.setAttribute('name', value.name);\n }\n \n get name(): string {\n return this.layout.name;\n }\n\n private async _initialize(): Promise<void> {\n this._initializing = true;\n try {\n this._initialized = true;\n // attachShadow は冪等にする: 一度 await loadTemplate() 中に切断されると\n // _initialized = false で戻され、再 connect 時に _initialize() が再度走るが、\n // その時点で shadowRoot は既に存在しているため、再度 attachShadow すると\n // InvalidStateError になる。\n if (this.layout.enableShadowRoot && !this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n const template = await this.layout.loadTemplate();\n // await 中に切断された場合は DOM 副作用を残さず、次回再接続時に再初期化させる\n if (!this.isConnected) {\n this._initialized = false;\n return;\n }\n if (this.shadowRoot) {\n this.shadowRoot.appendChild(template.content.cloneNode(true));\n for(const childNode of Array.from(this.layout.childNodes)) {\n this._layoutChildNodes.push(childNode);\n this.appendChild(childNode);\n }\n } else {\n const fragmentForTemplate = template.content.cloneNode(true) as DocumentFragment;\n const slotElementBySlotName: Map<string, Element> = new Map();\n fragmentForTemplate.querySelectorAll('slot').forEach((slotElement) => {\n const slotName = slotElement.getAttribute('name') || '';\n if (!slotElementBySlotName.has(slotName)) {\n slotElementBySlotName.set(slotName, slotElement);\n } else {\n console.warn(`${config.tagNames.layoutOutlet} duplicate slot name \"${slotName}\" in layout template.`);\n }\n });\n\n const fragmentBySlotName: Map<string, DocumentFragment> = new Map();\n const fragmentForChildNodes = document.createDocumentFragment();\n for(const childNode of Array.from(this.layout.childNodes)) {\n this._layoutChildNodes.push(childNode);\n if (childNode instanceof Element) {\n const slotName = childNode.getAttribute('slot') || '';\n if (slotName.length > 0 && slotElementBySlotName.has(slotName)) {\n if (!fragmentBySlotName.has(slotName)) {\n fragmentBySlotName.set(slotName, document.createDocumentFragment());\n }\n fragmentBySlotName.get(slotName)?.appendChild(childNode);\n continue;\n }\n }\n fragmentForChildNodes.appendChild(childNode);\n }\n for(const [slotName, slotElement] of slotElementBySlotName) {\n const fragment = fragmentBySlotName.get(slotName);\n if (fragment) {\n slotElement.replaceWith(fragment);\n }\n }\n const defaultSlot = slotElementBySlotName.get('');\n if (defaultSlot) {\n defaultSlot.replaceWith(fragmentForChildNodes);\n }\n\n this.appendChild(fragmentForTemplate);\n }\n } finally {\n this._initializing = false;\n }\n }\n\n async connectedCallback() {\n if (!this._initialized) {\n this._disconnectedDuringInit = false;\n await this._initialize();\n // 初期化中(await 中)に切断された場合は副作用を残さない\n if (this._disconnectedDuringInit || !this.isConnected) {\n return;\n }\n }\n }\n\n disconnectedCallback() {\n // _initialize 中(await 中)に呼ばれた場合はフラグを立てて再 connect 時に init を許可する\n if (this._initializing) {\n this._disconnectedDuringInit = true;\n }\n }\n\n assignParams(params: Record<string, any>): void {\n for(const childNode of this._layoutChildNodes) {\n if (childNode instanceof Element) {\n childNode.querySelectorAll('[data-bind]').forEach((e) => {\n // 子要素にパラメータを割り当て\n assignParams(e, params);\n });\n if (childNode.hasAttribute('data-bind')) {\n // 子要素にパラメータを割り当て\n assignParams(childNode, params);\n }\n }\n }\n }\n}\n\nexport function createLayoutOutlet(): LayoutOutlet {\n return document.createElement(config.tagNames.layoutOutlet) as LayoutOutlet;\n}","import { GuardHandler } from \"./components/types.js\";\nimport { IRoute } from \"./components/types.js\";\n\ntype ScriptModule = { default?: unknown };\n\nasync function importModule(script: HTMLScriptElement, route: IRoute): Promise<GuardHandler | null> {\n let scriptModule: ScriptModule | null = null;\n let firstError: unknown = null;\n // devtools での識別用 sourceURL suffix。\n // uuid を使う: Route インスタンスでは constructor で getUUID() により必ず設定される。\n // partial mock 等で undefined の可能性に備えて空文字列フォールバックを置く。\n const routeTag = route.uuid || \"\";\n const sourceURL = routeTag ? `wcs-guard-handler:${routeTag}` : `wcs-guard-handler`;\n const sourceComment = `\\n//# sourceURL=${sourceURL}\\n`;\n const scriptText = script.text + sourceComment;\n if (typeof URL.createObjectURL === 'function') {\n const blob = new Blob([scriptText], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n try {\n scriptModule = await import(url) as ScriptModule;\n } catch (e) {\n // Blob URL import failed (e.g. happy-dom), fall through to data: URL\n firstError = e;\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n if (!scriptModule) {\n // Fallback: Base64 data: URL (for test environments)\n const b64 = btoa(String.fromCodePoint(...new TextEncoder().encode(scriptText)));\n try {\n scriptModule = await import(`data:application/javascript;base64,${b64}`) as ScriptModule;\n } catch (e) {\n // 両 import が失敗した場合、Blob URL 側の元エラーを cause として失わないように包む\n // (Blob URL も失敗していなければ firstError は null)\n throw new Error(\n `loadGuardHandler: failed to import guard script. ` +\n `data: URL error: ${(e as Error)?.message ?? String(e)}` +\n (firstError ? `. Blob URL error: ${(firstError as Error)?.message ?? String(firstError)}` : ''),\n { cause: firstError ?? e }\n );\n }\n }\n if (scriptModule && typeof scriptModule.default === 'function') {\n return scriptModule.default as GuardHandler;\n }\n return null;\n}\n\nexport function loadGuardHandler(script: HTMLScriptElement, route: IRoute): void {\n importModule(script, route).then(handler => {\n if (handler) {\n route.guardHandler = handler;\n } else {\n // ハンドラが取得できなかった場合は guardCheck の待ちを解除する\n route.notifyGuardHandlerLoadFailed();\n }\n }).catch(err => {\n console.error('loadGuardHandler failed:', err);\n // import 失敗時も guardCheck の待ちを解除する\n route.notifyGuardHandlerLoadFailed();\n });\n}\n","import { IRoute, IRouter } from \"./components/types.js\";\nimport { Layout } from \"./components/Layout.js\";\nimport { createLayoutOutlet } from \"./components/LayoutOutlet.js\";\nimport { Route } from \"./components/Route.js\";\nimport { config } from \"./config.js\";\nimport { loadGuardHandler } from \"./loadGuardHandler.js\";\n\n\n/**\n * 同一の絶対パスを持つ Route が複数定義された場合に警告を出力する。\n *\n * 仕様: 同一 absolutePath ごとに 1 回だけ警告する(複数重複でも警告は 1 件)。\n * これは過剰なログを避けるための意図的な設計。\n * テストでは Vitest の console.warn spy で 1 回出力を確認する。\n */\nfunction _duplicateCheck(routesByPath: Map<string, IRoute[]>, route: IRoute): void {\n let routes = routesByPath.get(route.absolutePath);\n if (!routes) {\n routes = [];\n }\n for(const existingRoute of routes) {\n if (!route.testAncestorNode(existingRoute)) {\n console.warn(`Duplicate route path detected: '${route.absolutePath}' (defined as '${route.path}')`);\n break;\n }\n }\n routes.push(route);\n if (routes.length === 1) {\n routesByPath.set(route.absolutePath, routes);\n }\n}\n\nasync function _parseNode(\n routerNode: IRouter,\n node: Node,\n routes: IRoute[],\n routesByPath: Map<string, IRoute[]>\n): Promise<DocumentFragment> {\n const routeParentNode: IRoute | null = routes.length > 0 ? routes[routes.length - 1] : null;\n const fragment = document.createDocumentFragment();\n const childNodes = Array.from(node.childNodes);\n for(const childNode of childNodes) {\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n let appendNode = childNode\n let element = childNode as HTMLElement;\n const tagName = element.tagName.toLowerCase();\n if (tagName === config.tagNames.route) {\n const childFragment = document.createDocumentFragment();\n // Move child nodes to fragment to avoid duplication of\n for(const childNode of Array.from(element.childNodes)) {\n childFragment.appendChild(childNode);\n }\n const cloneElement = document.importNode<Route>(element as Route, true);\n customElements.upgrade(cloneElement);\n cloneElement.appendChild(childFragment);\n const route = cloneElement;\n route.initialize(routerNode, routeParentNode);\n _duplicateCheck(routesByPath, route);\n routes.push(route);\n appendNode = route.placeHolder;\n element = route;\n } else if (tagName === config.tagNames.guardHandler) {\n if (routes.length > 0) {\n const route = routes[routes.length - 1];\n const script = element.querySelector('script[type=\"module\"]');\n if (script) {\n loadGuardHandler(script as HTMLScriptElement, route);\n }\n }\n continue;\n } else if (tagName === config.tagNames.layout) {\n // <wcs-layout> は他の case と異なり element と appendNode が別物になる。\n // - element: cloneElement (Layout 本体)。後続の `element.innerHTML = \"\"; element.appendChild(children)`\n // で再帰結果が Layout 内に流し込まれる。Layout はそれを slot 投影に使う。\n // - appendNode: layoutOutlet。最終的に fragment へ挿入されるのは layoutOutlet で、\n // layoutOutlet が element (Layout) を参照して投影を行う。\n const childFragment = document.createDocumentFragment();\n // Move child nodes to fragment to avoid duplication of\n for(const childNode of Array.from(element.childNodes)) {\n childFragment.appendChild(childNode);\n }\n const cloneElement = document.importNode(element, true);\n customElements.upgrade(cloneElement);\n cloneElement.appendChild(childFragment);\n const layout = cloneElement;\n const layoutOutlet = createLayoutOutlet();\n layoutOutlet.layout = layout as Layout;\n appendNode = layoutOutlet;\n element = cloneElement;\n }\n const children = await _parseNode(routerNode, element, routes, routesByPath);\n element.innerHTML = \"\";\n element.appendChild(children);\n fragment.appendChild(appendNode);\n } else {\n fragment.appendChild(childNode);\n }\n }\n return fragment;\n}\n\nexport async function parse(routerNode: IRouter): Promise<DocumentFragment> {\n const routesByPath: Map<string, IRoute[]> = new Map();\n const fr = await _parseNode(routerNode, routerNode.template.content, [], routesByPath);\n return fr;\n}","import { IRoute, IRouteMatchResult, IRouter } from \"./components/types.js\";\nimport { testPath } from \"./testPath.js\";\n\nfunction _matchRoutes(\n routeNode: IRoute,\n normalizedPath: string,\n segments: string[],\n results: IRouteMatchResult[]\n): void {\n const matchResult = testPath(routeNode, normalizedPath, segments);\n if (matchResult) {\n results.push(matchResult);\n }\n for(const childRoute of routeNode.routeChildNodes) {\n _matchRoutes(childRoute, normalizedPath, segments, results);\n }\n}\n\nexport function matchRoutes(routerNode: IRouter, normalizedPath: string): IRouteMatchResult | null {\n const topLevelRoutes = routerNode.routeChildNodes;\n const results: IRouteMatchResult[] = [];\n // セグメント配列を作成(先頭の/は除去せずにそのまま分割)\n // '/' => ['', ''] → filter → ['']\n // '/home' => ['', 'home'] → filter → ['home']\n // '/home/about' => ['', 'home', 'about'] → filter → ['home', 'about']\n // '' => ['']\n const rawSegments = normalizedPath.split('/');\n // 先頭の空セグメント(絶対パスの/)と末尾の空セグメント(/で終わるパス)を除去\n const segments = rawSegments.filter((s, i) => {\n if (i === 0 && s === '') return false; // 先頭の空セグメントをスキップ\n if (i === rawSegments.length - 1 && s === '' && rawSegments.length > 1) return false; // 末尾の空セグメントをスキップ\n return true;\n });\n for (const route of topLevelRoutes) {\n _matchRoutes(route, normalizedPath, segments, results);\n }\n results.sort((a, b) => {\n const lastRouteA = a.routes.at(-1)!;\n const lastRouteB = b.routes.at(-1)!;\n const diffSegmentCount = lastRouteA.absoluteSegmentCount - lastRouteB.absoluteSegmentCount;\n if (diffSegmentCount !== 0) {\n return -diffSegmentCount;\n }\n const diffWeight = lastRouteA.absoluteWeight - lastRouteB.absoluteWeight;\n if (diffWeight !== 0) {\n return -diffWeight;\n }\n const diffIndex = lastRouteA.childIndex - lastRouteB.childIndex;\n return diffIndex;\n });\n if (results.length > 0) {\n return results[0];\n }\n return null;\n}","import { builtinParamTypes } from \"./builtinParamTypes\";\nimport { IRoute, IRouteMatchResult } from \"./components/types\";\n\nexport function testPath(route: IRoute, path: string, segments: string[]): IRouteMatchResult | null {\n const params: Record<string, string> = {};\n const typedParams: Record<string, any> = {};\n let testResult = true;\n let catchAllFound = false;\n let i = 0, segIndex = 0;\n while (i < route.absoluteSegmentInfos.length) {\n const segmentInfo = route.absoluteSegmentInfos[i];\n // index属性のルートはセグメントを消費しないのでスキップ\n if (segmentInfo.isIndex) {\n i++;\n continue;\n }\n // 先頭の空セグメント(絶対パスの /)はsegmentsから除外されているのでスキップ\n if (i === 0 && segmentInfo.segmentText === '' && segmentInfo.type === 'static') {\n i++;\n continue;\n }\n const segment = segments[segIndex];\n if (segment === undefined) {\n // セグメントが足りない\n testResult = false;\n break;\n }\n let match: boolean = false;\n if (segmentInfo.type === \"param\") {\n const paramType = segmentInfo.paramType || 'any';\n const builtinParamType = builtinParamTypes[paramType];\n const value = builtinParamType.parse(segment);\n if (typeof value !== 'undefined') {\n if (segmentInfo.paramName) {\n params[segmentInfo.paramName] = segment;\n typedParams[segmentInfo.paramName] = value;\n }\n match = true;\n }\n } else {\n match = segmentInfo.pattern.exec(segment) !== null;\n }\n if (match) {\n if (segmentInfo.type === 'catch-all') {\n // Catch-all: match remaining segments\n const remainingSegments = segments.slice(segIndex).join('/');\n params['*'] = remainingSegments;\n typedParams['*'] = remainingSegments;\n catchAllFound = true;\n break; // No more segments to process\n }\n } else {\n testResult = false;\n break; \n }\n i++;\n segIndex++;\n }\n let finalResult = false;\n if (testResult) {\n if (catchAllFound) {\n // catch-all は残り全部マッチ済み\n finalResult = true;\n } else if (i === route.absoluteSegmentInfos.length && segIndex === segments.length) {\n // 全セグメントが消費された。\n // 末尾スラッシュ(例: /users/)は matchRoutes 側で処理済み: normalizePathname が\n // ルート以外の末尾スラッシュを除去し、matchRoutes の filter が末尾の空セグメントを\n // 落とすため、testPath に渡る segments に末尾 '' は含まれない。よってここで\n // 末尾スラッシュ用の分岐は不要(trailing-slash の結合テストは matchRoutes.test.ts 参照)。\n finalResult = true;\n }\n }\n \n if (finalResult) {\n return {\n path: path,\n routes: route.routes,\n params: params,\n typedParams: typedParams,\n lastPath: \"\"\n };\n }\n return null;\n}","import { IRoute } from \"./components/types\";\n\nexport function hideRoute(route: IRoute) {\n route.clearParams();\n for(const node of route.childNodeArray) {\n node.parentNode?.removeChild(node);\n }\n}\n","import { assignParams } from \"./assignParams\";\nimport { LayoutOutlet } from \"./components/LayoutOutlet\";\nimport { IRoute, IRouteMatchResult } from \"./components/types\";\nimport { config } from \"./config\";\n\nexport function showRoute(route: IRoute, matchResult: IRouteMatchResult): boolean {\n const params: Record<string, string> = {};\n const typedParams: Record<string, any> = {};\n for(const key of route.paramNames) {\n params[key] = matchResult.params[key];\n typedParams[key] = matchResult.typedParams[key];\n }\n route.setParams(params, typedParams);\n const parentNode = route.placeHolder.parentNode;\n const nextSibling = route.placeHolder.nextSibling;\n for (const node of route.childNodeArray) {\n // connectedCallbackが呼ばれる前に、プロパティにパラメータを割り当てる\n // connectedCallbackを実行するときにパラメータはすでに設定されている必要があるため\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n element.querySelectorAll('[data-bind]').forEach((e) => {\n assignParams(e, route.typedParams);\n });\n if (element.hasAttribute('data-bind')) {\n assignParams(element, route.typedParams);\n }\n element.querySelectorAll<LayoutOutlet>(config.tagNames.layoutOutlet).forEach((layoutOutlet) => {\n layoutOutlet.assignParams(route.typedParams);\n });\n if (element.tagName.toLowerCase() === config.tagNames.layoutOutlet) {\n (element as LayoutOutlet).assignParams(route.typedParams);\n }\n }\n if (nextSibling) {\n parentNode?.insertBefore(node, nextSibling);\n } else {\n parentNode?.appendChild(node);\n }\n }\n return true;\n}\n","import { IOutlet, IRouter } from \"./components/types\";\nimport { config } from \"./config\";\nimport { matchRoutes } from \"./matchRoutes\";\nimport { raiseError } from \"./raiseError\";\nimport { showRouteContent } from \"./showRouteContent\";\n\nexport async function applyRoute(\n routerNode: IRouter, \n outlet: IOutlet, \n fullPath: string,\n lastPath: string\n): Promise<void> {\n const basename = routerNode.basename;\n let sliced = fullPath;\n if (basename !== \"\") {\n if (fullPath === basename) {\n sliced = \"\";\n } else if (fullPath.startsWith(basename + \"/\")) {\n sliced = fullPath.slice(basename.length);\n }\n }\n // when fullPath === basename (e.g. \"/app\"), treat it as root \"/\"\n const path = sliced === \"\" ? \"/\" : sliced;\n\n let matchResult = matchRoutes(routerNode, path);\n if (!matchResult) {\n if (routerNode.fallbackRoute) {\n matchResult = {\n routes: [routerNode.fallbackRoute],\n params: {},\n typedParams: {},\n path: path,\n lastPath: lastPath\n };\n } else {\n raiseError(`${config.tagNames.router} No route matched for path: ${path}`);\n }\n }\n matchResult.lastPath = lastPath;\n const lastRoutes = outlet.lastRoutes;\n const committed = await showRouteContent(routerNode, matchResult, lastRoutes);\n // GuardCancel により中断された場合は state を更新しない\n // (拒否されたパスでの wcs-router:path-changed 発火を防ぐため)\n if (!committed) return;\n // if successful, update router and outlet state\n routerNode.path = path;\n outlet.lastRoutes = matchResult.routes;\n}\n","import { IRoute, IRouteMatchResult, IRouter } from \"./components/types\";\nimport { hideRoute } from \"./hideRoute\";\nimport { showRoute } from \"./showRoute\";\nimport { GuardCancel } from \"./GuardCancel\";\n\n/**\n * ルートコンテンツを表示する。\n *\n * @returns ガードチェックを通過してコンテンツ表示が成立した場合 true、\n * GuardCancel により中断(フォールバックへ再ナビゲート)した場合 false。\n * 呼び出し側(applyRoute)は false の場合、router.path / outlet.lastRoutes を\n * 更新しないことで「拒否されたパスでの path-changed 発火」を防ぐ。\n */\nexport async function showRouteContent(\n routerNode: IRouter,\n matchResult: IRouteMatchResult,\n lastRoutes: IRoute[],\n): Promise<boolean> {\n // Hide previous routes\n const routesSet = new Set<IRoute>(matchResult.routes);\n for (const route of lastRoutes) {\n if (!routesSet.has(route)) {\n hideRoute(route);\n }\n }\n try {\n for (const route of matchResult.routes) {\n await route.guardCheck(matchResult);\n }\n } catch (e) {\n if (e instanceof GuardCancel) {\n console.warn(`Navigation cancelled: ${e.message}. Redirecting to ${e.fallbackPath}`);\n queueMicrotask(() => {\n routerNode.navigate(e.fallbackPath).catch((err) => {\n console.error('Fallback navigation failed:', err);\n });\n });\n return false;\n } else {\n throw e;\n }\n }\n const lastRouteSet = new Set<IRoute>(lastRoutes);\n let force = false;\n for (const route of matchResult.routes) {\n if (!lastRouteSet.has(route) || route.shouldChange(matchResult.params) || force) {\n force = showRoute(route, matchResult);\n }\n }\n return true;\n}\n","/**\n * Navigation API の `navigate()` 戻り値(NavigationResult)。\n * - `committed`: URL がアドレスバーに反映された時点で resolve\n * - `finished`: 全 intercept handler 完了で resolve\n * Polyfill や mock 環境では戻り値が undefined のケースもあるため、\n * 戻り値全体を optional として扱う。\n */\nexport type NavigationResultLike = {\n committed?: Promise<unknown>;\n finished?: Promise<unknown>;\n};\n\nexport type NavigationLike = {\n navigate?: (url: string) => NavigationResultLike | void | undefined;\n addEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n removeEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n};\n\nexport function getNavigation(): NavigationLike | null {\n const nav = (window as any).navigation as NavigationLike | undefined;\n if (!nav) {\n return null;\n }\n if (typeof nav.addEventListener !== \"function\" || typeof nav.removeEventListener !== \"function\") {\n return null;\n }\n return nav;\n}\n","import { config } from \"./config.js\";\n\n// basenameFileExtensions ベースの正規表現をキャッシュ(config 変更時のみ再生成)。\nlet _cachedExtensions: ReadonlyArray<string> | null = null;\nlet _cachedExtPattern: RegExp | null = null;\n\n/**\n * config.basenameFileExtensions から拡張子削除用の正規表現を生成(キャッシュ付き)。\n * config 変更が検知された場合のみ再生成する。\n */\nexport function getExtPattern(): RegExp | null {\n const exts = config.basenameFileExtensions;\n if (exts.length === 0) return null;\n if (_cachedExtensions === exts && _cachedExtPattern) {\n return _cachedExtPattern;\n }\n _cachedExtensions = exts;\n _cachedExtPattern = new RegExp(\n `\\\\/[^/]+(?:${exts.map(e => e.replace(/\\./g, '\\\\.')).join('|')})$`,\n 'i'\n );\n return _cachedExtPattern;\n}\n\n/**\n * URL pathname を route path に正規化する。\n * - 先頭スラッシュを保証\n * - 連続スラッシュを単一化\n * - 末尾のファイル拡張子(例: .html)をディレクトリルートとして扱う\n * - ルート以外の末尾スラッシュを除去\n */\nexport function normalizePathname(path: string): string {\n let p = path || \"/\";\n if (!p.startsWith(\"/\")) p = \"/\" + p;\n p = p.replace(/\\/{2,}/g, \"/\");\n const extPattern = getExtPattern();\n if (extPattern) {\n p = p.replace(extPattern, \"\");\n }\n if (p === \"\") p = \"/\";\n if (p.length > 1 && p.endsWith(\"/\")) p = p.slice(0, -1);\n return p;\n}\n\n/**\n * basename を正規化する。\n * - \"\" or \"/\" -> \"\"\n * - \"/app/\" -> \"/app\"\n * - \"/app/index.html\" -> \"/app\"\n */\nexport function normalizeBasename(path: string): string {\n let p = path || \"\";\n if (!p) return \"\";\n if (!p.startsWith(\"/\")) p = \"/\" + p;\n p = p.replace(/\\/{2,}/g, \"/\");\n const extPattern = getExtPattern();\n if (extPattern) {\n p = p.replace(extPattern, \"\");\n }\n if (p.length > 1 && p.endsWith(\"/\")) p = p.slice(0, -1);\n if (p === \"/\") return \"\";\n return p;\n}\n","import { parse } from \"../parse.js\";\nimport { createOutlet } from \"./Outlet.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IOutlet, IRoute, IRouter } from \"./types.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { applyRoute } from \"../applyRoute.js\";\nimport { getNavigation } from \"../Navigation.js\";\nimport { normalizeBasename, normalizePathname } from \"../normalizePathname.js\";\n\ninterface NavigateEventLike {\n canIntercept: boolean;\n hashChange: boolean;\n downloadRequest: string | null;\n destination: { url: string };\n intercept: (options: { handler: () => Promise<void> }) => void;\n}\n\n/**\n * AppRoutes - Root component for @wcstack/router\n *\n * Container element that manages route definitions and navigation.\n */\nexport class Router extends HTMLElement implements IRouter {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"navigateUrl\", event: \"wcs-router:navigate-url-changed\" },\n { name: \"path\", event: \"wcs-router:path-changed\" },\n ],\n // `navigateUrl` は observable output であると同時に settable な書き込み面でもある\n // (setter が navigate() を起動し、完了後に自分で null へ戻す)。properties にだけ\n // 宣言すると binding core は output-only とみなし、state → element の書き込みを\n // 抑止するため、state 経由のプログラム遷移が成立しなくなる。`path` は setter が\n // navigate せず内部値の反映だけなので、意図的に output のままにしている。\n inputs: [\n { name: \"basename\", attribute: \"basename\" },\n { name: \"navigateUrl\" },\n ],\n commands: [\n { name: \"navigate\", async: true },\n ],\n };\n\n private _outlet: IOutlet | null = null;\n private _template: HTMLTemplateElement | null = null;\n private _routeChildNodes: IRoute[] = [];\n private _basename: string = '';\n private _path: string = '';\n private _initialized: boolean = false;\n private _fallbackRoute: IRoute | null = null;\n private _listeningPopState: boolean = false;\n private _listeningNavigate: boolean = false;\n private _navigateUrl: string | null = null;\n private _disconnectedDuringInit: boolean = false;\n private _initializing: boolean = false;\n\n constructor() {\n super();\n }\n\n /**\n * Normalize a URL pathname to a route path.\n * 共通実装は normalizePathname.ts を参照(Link との挙動整合のため)。\n */\n private _normalizePathname(_path: string): string {\n return normalizePathname(_path);\n }\n\n /**\n * Normalize basename.\n * 共通実装は normalizePathname.ts を参照。\n */\n private _normalizeBasename(_path: string): string {\n return normalizeBasename(_path);\n }\n\n private _joinInternalPath(basename: string, to: string): string {\n const base = this._normalizeBasename(basename);\n // accept \"about\" as \"/about\"\n let path = to.startsWith(\"/\") ? to : \"/\" + to;\n path = this._normalizePathname(path);\n if (!base) return path;\n // keep \"/app/\" for root\n if (path === \"/\") return base + \"/\";\n return base + path;\n }\n\n private _notifyLocationChange(): void {\n // For environments without Navigation API (and for Link active-state updates)\n window.dispatchEvent(new CustomEvent(\"wcs:navigate\"));\n }\n\n private _getBasename(): string {\n const base = new URL(document.baseURI);\n let path = base.pathname || \"/\";\n if (path === \"/\") {\n return \"\";\n }\n return this._normalizeBasename(path);\n }\n\n get basename(): string {\n return this._basename;\n }\n\n private _getOutlet(): IOutlet {\n // 自身を起点に兄弟・子孫から Outlet を探す(マルチ Router 対応)\n const next = this.nextElementSibling;\n if (next && next.matches(config.tagNames.outlet)) {\n return next as unknown as IOutlet;\n }\n // なければ新規作成して自身の直後に挿入\n const outlet = createOutlet();\n if (this.parentNode) {\n this.parentNode.insertBefore(outlet, this.nextSibling);\n } else {\n document.body.appendChild(outlet);\n }\n return outlet;\n }\n\n private _getTemplate() {\n const template = this.querySelector(\"template\");\n return template;\n }\n \n get outlet(): IOutlet {\n if (!this._outlet) {\n raiseError(`${config.tagNames.router} has no outlet.`);\n }\n return this._outlet;\n }\n\n get template(): HTMLTemplateElement {\n if (!this._template) {\n raiseError(`${config.tagNames.router} has no template.`);\n }\n return this._template;\n }\n\n get routeChildNodes(): IRoute[] {\n return this._routeChildNodes;\n }\n\n get path(): string {\n return this._path;\n }\n /**\n * applyRoute 内で設定される値です。\n */\n set path(value: string) {\n const changed = this._path !== value;\n this._path = value;\n if (changed) {\n this.dispatchEvent(new CustomEvent(\"wcs-router:path-changed\", {\n detail: value,\n bubbles: true,\n }));\n }\n }\n\n get fallbackRoute(): IRoute | null {\n return this._fallbackRoute;\n }\n /**\n * Routeのfallback属性がある場合にそのルートを設定します。\n */\n set fallbackRoute(value: IRoute | null) {\n this._fallbackRoute = value;\n }\n\n get navigateUrl(): string | null {\n return this._navigateUrl;\n }\n\n set navigateUrl(value: string | null) {\n if (value === null || value === undefined || value === \"\") return;\n // 既に同一 URL の navigate 中なら再起動しない\n if (this._navigateUrl === value) return;\n this._navigateUrl = value;\n this.navigate(value).catch((err) => {\n console.error(`${config.tagNames.router} navigate failed:`, err);\n }).finally(() => {\n this._navigateUrl = null;\n this.dispatchEvent(new CustomEvent(\"wcs-router:navigate-url-changed\", {\n detail: null,\n bubbles: true,\n }));\n });\n }\n\n async navigate(path: string): Promise<void> {\n const fullPath = this._joinInternalPath(this._basename, path);\n const navigation = getNavigation();\n if (navigation?.navigate) {\n // Navigation API は { committed, finished } を返す。\n // finished を await することで、navigate() の Promise が\n // 実際のナビゲーション完了まで pending となり、_navigateUrl の\n // 二重 navigate ガード (setter 内 `if (this._navigateUrl === value)`) が\n // 適切な時間ウィンドウで機能するようになる。\n // Polyfill や mock 環境で undefined / 戻り値なしのケースもあるため optional chaining。\n await navigation.navigate(fullPath)?.finished;\n } else {\n history.pushState(null, '', fullPath);\n await applyRoute(this, this.outlet, fullPath, this._path);\n this._notifyLocationChange();\n }\n }\n\n /**\n * basename 配下の URL かどうかを判定する。\n * basename が空の場合はすべての URL にマッチする。\n */\n private _isOwnPath(fullPath: string): boolean {\n if (this._basename === \"\") return true;\n return fullPath === this._basename || fullPath.startsWith(this._basename + \"/\");\n }\n\n private _onNavigateFunc(navEvent: NavigateEventLike) {\n if (\n !navEvent.canIntercept ||\n navEvent.hashChange ||\n navEvent.downloadRequest !== null\n ) {\n return;\n }\n const url = new URL(navEvent.destination.url);\n const fullPath = this._normalizePathname(url.pathname);\n // basename 配下でない URL は無視(マルチ Router 対応)\n if (!this._isOwnPath(fullPath)) return;\n const routesNode = this;\n navEvent.intercept({\n handler: async () => {\n try {\n await applyRoute(routesNode, routesNode.outlet, fullPath, routesNode.path);\n } catch (err) {\n console.error(`${config.tagNames.router} applyRoute failed:`, err);\n throw err;\n }\n },\n });\n }\n\n private _onNavigate = this._onNavigateFunc.bind(this) as unknown as EventListener;\n\n private _onPopState = async () => {\n // back/forward for environments without Navigation API\n const fullPath = this._normalizePathname(window.location.pathname);\n // basename 配下でない URL は無視(マルチ Router 対応)\n if (!this._isOwnPath(fullPath)) return;\n await applyRoute(this, this.outlet, fullPath, this._path);\n this._notifyLocationChange();\n };\n\n private async _initialize(): Promise<void> {\n this._initializing = true;\n try {\n this._basename = this._normalizeBasename(\n this.getAttribute(\"basename\") || this._getBasename() || \"\"\n );\n const hasBaseTag = document.querySelector('base[href]') !== null;\n const url = new URL(window.location.href);\n if (this._basename === \"\" && !hasBaseTag && url.pathname !== \"/\") {\n raiseError(`${config.tagNames.router} basename is empty, but current path is not \"/\".`);\n }\n\n this._outlet = this._getOutlet();\n this._outlet.routesNode = this;\n this._template = this._getTemplate();\n if (!this._template) {\n raiseError(`${config.tagNames.router} should have a <template> child element.`);\n }\n const fragment = await parse(this);\n this._outlet.rootNode.appendChild(fragment);\n if (this.routeChildNodes.length === 0) {\n raiseError(`${config.tagNames.router} has no route definitions.`);\n }\n\n const fullPath = this._normalizePathname(window.location.pathname);\n await applyRoute(this, this.outlet, fullPath, this._path);\n this._notifyLocationChange();\n this._initialized = true;\n } finally {\n this._initializing = false;\n }\n }\n\n async connectedCallback() {\n if (!this._initialized) {\n this._disconnectedDuringInit = false;\n await this._initialize();\n // 初期化中に disconnectedCallback が呼ばれた場合はイベントリスナを登録しない\n if (this._disconnectedDuringInit) {\n return;\n }\n }\n const navigation = getNavigation();\n if (navigation && !this._listeningNavigate) {\n navigation.addEventListener(\"navigate\", this._onNavigate);\n this._listeningNavigate = true;\n }\n // Fallback for browsers without Navigation API\n if (!navigation && !this._listeningPopState) {\n window.addEventListener(\"popstate\", this._onPopState);\n this._listeningPopState = true;\n }\n }\n\n disconnectedCallback() {\n // _initialize 中(await 中)に呼ばれた場合はフラグを立ててリスナ登録をスキップさせる\n if (this._initializing) {\n this._disconnectedDuringInit = true;\n }\n if (this._listeningNavigate) {\n getNavigation()?.removeEventListener(\"navigate\", this._onNavigate);\n this._listeningNavigate = false;\n }\n if (this._listeningPopState) {\n window.removeEventListener(\"popstate\", this._onPopState);\n this._listeningPopState = false;\n }\n }\n}\n","import { config } from \"../config\";\nimport { getUUID } from \"../getUUID\";\nimport { raiseError } from \"../raiseError\";\nimport { getNavigation } from \"../Navigation\";\nimport { normalizeBasename, normalizePathname } from \"../normalizePathname\";\nimport { ILink } from \"./types\";\nimport type { Router } from \"./Router\";\n\nexport class Link extends HTMLElement implements ILink {\n static get observedAttributes(): string[] {\n return ['to'];\n }\n\n private _childNodeArray: Node[] = [];\n private _uuid: string = getUUID();\n private _path: string = \"\";\n private _router: Router | null = null;\n private _anchorElement: HTMLAnchorElement | null = null;\n private _initialized: boolean = false;\n private _onClick?: (e: MouseEvent) => void;\n\n constructor() {\n super();\n }\n\n get uuid(): string {\n return this._uuid;\n }\n \n /**\n * 最寄りの Router を返す。\n *\n * 注意: この getter は DOM 走査で Router を探すため、\n * Router がまだ upgrade されていない場合は HTMLElement として返る可能性がある。\n * 通常は registerComponents() で Router を Link より先に upgrade することを推奨する。\n */\n get router(): Router {\n if (this._router) {\n return this._router;\n }\n // DOM 祖先走査で最寄りの Router を探す(マルチ Router 対応)\n const ancestor = this.closest<Router>(config.tagNames.router);\n if (ancestor) {\n return (this._router = ancestor);\n }\n // 祖先にない場合は ownerDocument 内の Router を探す\n const root = this.getRootNode() as Document | ShadowRoot;\n const found = root.querySelector?.<Router>(config.tagNames.router);\n if (found) {\n return (this._router = found);\n }\n raiseError(`${config.tagNames.link} is not connected to a router.`);\n }\n\n private _initialize() {\n this.style.display = \"none\";\n this._childNodeArray = Array.from(this.childNodes);\n this._path = this.getAttribute('to') || '';\n this._initialized = true;\n }\n\n /**\n * URL pathname を正規化する。Router と共通実装を使うことで\n * basenameFileExtensions の取り扱いを揃え、active 判定の取りこぼしを防ぐ。\n */\n private _normalizePathname(path: string): string {\n return normalizePathname(path);\n }\n\n private _joinInternalPath(basename: string, to: string): string {\n // Router._joinInternalPath と挙動を揃える\n const base = normalizeBasename(basename);\n const internal = to.startsWith(\"/\") ? to : \"/\" + to;\n const path = this._normalizePathname(internal);\n if (!base) return path;\n if (path === \"/\") return base + \"/\";\n return base + path;\n }\n\n private _setAnchorHref(anchor: HTMLAnchorElement,path: string) {\n if (path.startsWith('/')) {\n anchor.href = this._joinInternalPath(this.router.basename, path);\n } else {\n try {\n anchor.href = new URL(path).toString();\n } catch {\n raiseError(`[${config.tagNames.link}] Invalid URL in 'to' attribute: ${path}`);\n }\n }\n }\n\n connectedCallback() {\n if (!this._initialized) {\n this._initialize();\n }\n const parentNode = this.parentNode;\n if (!parentNode) {\n // should not happen if connected\n return; \n }\n const nextSibling = this.nextSibling;\n const link = document.createElement('a');\n this._setAnchorHref(link, this._path);\n for(const childNode of this._childNodeArray) {\n link.appendChild(childNode);\n }\n if (nextSibling) {\n parentNode.insertBefore(link, nextSibling);\n } else {\n parentNode.appendChild(link);\n }\n this._anchorElement = link;\n\n // ロケーション変更を監視\n getNavigation()?.addEventListener('currententrychange', this._updateActiveState);\n window.addEventListener('wcs:navigate', this._updateActiveState as EventListener);\n window.addEventListener('popstate', this._updateActiveState as EventListener);\n\n // Navigation API が無い場合は、クリックで router.navigate にフォールバック\n if (this._path.startsWith('/') && !getNavigation()?.navigate) {\n this._onClick = async (e: MouseEvent) => {\n // only left-click without modifiers\n if (e.defaultPrevented) return;\n if (e.button !== 0) return;\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n // 動的に外部URLに変わった場合はブラウザのデフォルト挙動に委ねる\n if (!this._path.startsWith('/')) return;\n e.preventDefault();\n await this.router.navigate(this._path);\n this._updateActiveState();\n };\n link.addEventListener('click', this._onClick);\n }\n this._updateActiveState(); \n }\n\n disconnectedCallback() {\n getNavigation()?.removeEventListener('currententrychange', this._updateActiveState);\n window.removeEventListener('wcs:navigate', this._updateActiveState as EventListener);\n window.removeEventListener('popstate', this._updateActiveState as EventListener);\n const anchor = this._anchorElement;\n if (anchor) {\n if (this._onClick) {\n anchor.removeEventListener('click', this._onClick);\n this._onClick = undefined;\n }\n anchor.remove();\n this._anchorElement = null;\n }\n // anchor 配下のままだった子要素のみ取り除く(別の親に移動されていた場合に誤って strip しないため)\n for(const childNode of this._childNodeArray) {\n if (anchor && childNode.parentNode === anchor) {\n anchor.removeChild(childNode);\n }\n }\n // Router キャッシュをクリア。別の Router 配下に動的に移動された場合や\n // Router 自体が入れ替わった場合に古い参照を返さないようにする。\n this._router = null;\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (name === 'to' && oldValue !== newValue) {\n this._path = newValue || '';\n if (this._anchorElement) {\n this._setAnchorHref(this._anchorElement, this._path);\n this._updateActiveState();\n }\n }\n }\n\n private _updateActiveState = () => {\n const currentPath = this._normalizePathname(new URL(window.location.href).pathname);\n const linkPath = this._normalizePathname(\n this._path.startsWith('/') ? this._joinInternalPath(this.router.basename, this._path) : this._path\n );\n \n if (this._anchorElement) {\n if (currentPath === linkPath) {\n this._anchorElement.classList.add('active');\n } else {\n this._anchorElement.classList.remove('active');\n }\n }\n };\n\n get anchorElement(): HTMLAnchorElement | null {\n return this._anchorElement;\n }\n}","import { raiseError } from \"../raiseError\";\n\n/**\n * グローバルHeadスタック\n * 最後に接続されたHeadが優先される\n */\nconst headStack: Head[] = [];\n\n/**\n * 初期の<head>内容を記憶(最初のHead接続時に保存)\n *\n * 設計仕様: `initialHeadCaptured` は最初の Head 接続時に一度だけ true になる。\n * SPA ライフタイム中の初期 head 状態は、最初の Head が接続された瞬間がベースラインで、\n * それ以降に追加された <head> 要素は「初期値」ではなく「現在の値」として扱う。\n * テストや SPA リセットで初期値を再キャプチャしたい場合は `_resetHeadStack()` を呼ぶ。\n */\nconst initialHeadValues: Map<string, Element | null> = new Map();\nlet initialHeadCaptured = false;\n\n/**\n * 要素ごとの `_getKey` 結果のキャッシュ。\n * 初期化時/キャプチャ時に算出し、以降の `_reapplyHead` ループで再計算しないようにする。\n * 要素の属性変更には追随しない(Head 内要素は初期化時に固定される前提)。\n */\nconst keyCache: WeakMap<Element, string> = new WeakMap();\n\nexport class Head extends HTMLElement {\n private _initialized: boolean = false;\n private _childElementArray: Element[] = [];\n\n constructor() {\n super();\n this.style.display = 'none';\n }\n\n private _initialize(): void {\n if (this._initialized) {\n return;\n }\n this._initialized = true;\n this._childElementArray = Array.from(this.children);\n for (const child of this._childElementArray) {\n this.removeChild(child);\n }\n }\n\n connectedCallback(): void {\n this._initialize();\n \n // 初回のみ初期状態を保存\n if (!initialHeadCaptured) {\n this._captureInitialHead();\n initialHeadCaptured = true;\n }\n \n // スタックに追加\n headStack.push(this);\n \n // headを再適用\n this._reapplyHead();\n }\n\n disconnectedCallback(): void {\n // スタックから削除\n const index = headStack.indexOf(this);\n if (index !== -1) {\n headStack.splice(index, 1);\n }\n \n // headを再適用(スタックが空なら初期状態に戻す)\n this._reapplyHead();\n }\n\n get childElementArray(): Element[] {\n if (!this._initialized) {\n raiseError('Head component is not initialized yet.');\n }\n return this._childElementArray;\n }\n\n /**\n * 要素の一意キーを生成(WeakMap でキャッシュ)\n */\n private _getKey(el: Element): string {\n const cached = keyCache.get(el);\n if (cached !== undefined) {\n return cached;\n }\n const key = this._computeKey(el);\n keyCache.set(el, key);\n return key;\n }\n\n /**\n * 要素の一意キーを計算(実体)\n */\n private _computeKey(el: Element): string {\n const tag = el.tagName.toLowerCase();\n\n if (tag === 'title') {\n return 'title';\n }\n\n if (tag === 'meta') {\n const name = el.getAttribute('name') || '';\n const property = el.getAttribute('property') || '';\n const httpEquiv = el.getAttribute('http-equiv') || '';\n const charset = el.hasAttribute('charset') ? 'charset' : '';\n const media = el.getAttribute('media') || '';\n return `meta:${name}:${property}:${httpEquiv}:${charset}:${media}`;\n }\n\n if (tag === 'link') {\n const rel = el.getAttribute('rel') || '';\n const href = el.getAttribute('href') || '';\n const media = el.getAttribute('media') || '';\n return `link:${rel}:${href}:${media}`;\n }\n\n if (tag === 'base') {\n return 'base';\n }\n\n if (tag === 'script') {\n const src = el.getAttribute('src') || '';\n const id = el.getAttribute('id') || '';\n const type = el.getAttribute('type') || '';\n if (src || id) {\n return `script:${src}:${id}:${type}`;\n }\n // インライン script はおおまかな先頭で識別(同等性は完全一致でなく簡易判定)\n return `script::${type}:${el.outerHTML.slice(0, 100)}`;\n }\n\n if (tag === 'style') {\n const id = el.getAttribute('id') || '';\n const media = el.getAttribute('media') || '';\n if (id) {\n return `style:${id}:${media}`;\n }\n // インライン style はおおまかな先頭で識別(同等性は完全一致でなく簡易判定)\n return `style::${media}:${el.outerHTML.slice(0, 100)}`;\n }\n\n // その他要素はおおまかに識別(同等性は完全一致でなく簡易判定)\n return `${tag}:${el.outerHTML.slice(0, 100)}`;\n }\n\n /**\n * head 内の要素を key で引ける Map を構築する。\n * `_reapplyHead` のループ前に一度だけ呼び出し、O(N) lookup に置き換えるためのヘルパ。\n *\n * 設計仕様: 同一 key の要素が複数 `document.head` 内に存在する場合は **first-wins**\n * (DOM 順で最初の要素のみ採用)。これは `_captureInitialHead` および\n * `initialHeadValues` の挙動とも整合する。\n * 重複は基本的にユーザーの記述ミスだが、_getKey の粒度(href/name 等の主要属性のみ)に\n * よる「論理的重複」もあり得るため、サイレントに first-wins とする。\n * 厳密な重複検出が必要な場合は呼び出し側で行う。\n */\n private _buildHeadElementMap(): Map<string, Element> {\n const map = new Map<string, Element>();\n for (const el of Array.from(document.head.children)) {\n const key = this._getKey(el);\n if (!map.has(key)) {\n map.set(key, el);\n }\n }\n return map;\n }\n\n /**\n * 初期の<head>状態をキャプチャ\n * document.head内の全ての要素をスキャンして保存する\n */\n private _captureInitialHead(): void {\n const head = document.head;\n for (const child of Array.from(head.children)) {\n const key = this._getKey(child);\n if (!initialHeadValues.has(key)) {\n initialHeadValues.set(key, child.cloneNode(true) as Element);\n }\n }\n }\n\n /**\n * スタック全体からheadを再構築\n * 後のHeadが優先される(上書き)\n */\n private _reapplyHead(): void {\n // 全スタックのHeadが扱うキーを収集\n const allKeys = new Set<string>();\n for (const head of headStack) {\n for (const child of head._childElementArray) {\n allKeys.add(this._getKey(child));\n }\n }\n // 初期値にあるキーも追加\n for (const key of initialHeadValues.keys()) {\n allKeys.add(key);\n }\n\n // 現在のheadにある要素のキーも追加(管理下から外れたものを削除するため)\n // 同時に key -> Element の lookup map も構築する(O(N²) を避けるため)\n const headElementMap = this._buildHeadElementMap();\n for (const key of headElementMap.keys()) {\n allKeys.add(key);\n }\n\n // 各キーについて、最も優先度の高い値を決定\n for (const key of allKeys) {\n // スタックを逆順に見て、最初に見つかった値を使用\n let targetElement: Element | null = null;\n for (let i = headStack.length - 1; i >= 0; i--) {\n const head = headStack[i];\n for (const child of head._childElementArray) {\n if (this._getKey(child) === key) {\n targetElement = child.cloneNode(true) as Element;\n break;\n }\n }\n if (targetElement) break;\n }\n\n // スタックに該当がなければ初期値を使用\n if (!targetElement && initialHeadValues.has(key)) {\n const initial = initialHeadValues.get(key);\n // initialHeadValuesにはnullを保存しないため、has(key)がtrueならinitialは必ず存在しElementである\n targetElement = (initial as Element).cloneNode(true) as Element;\n }\n\n // headを更新\n const current = headElementMap.get(key) ?? null;\n if (targetElement) {\n if (current) {\n current.replaceWith(targetElement);\n } else {\n document.head.appendChild(targetElement);\n }\n // map を新しい要素に更新(後続の同 key 処理に備える)\n headElementMap.set(key, targetElement);\n } else {\n // 初期値もスタックにもない場合は削除\n current?.remove();\n headElementMap.delete(key);\n }\n }\n }\n}\n\n// テスト用にスタックをリセットする関数\nexport function _resetHeadStack(): void {\n headStack.length = 0;\n initialHeadValues.clear();\n initialHeadCaptured = false;\n}\n","import { Route } from './components/Route';\nimport { Layout } from './components/Layout';\nimport { Outlet } from './components/Outlet';\nimport { Router } from './components/Router';\nimport { LayoutOutlet } from './components/LayoutOutlet';\nimport { Link } from './components/Link';\nimport { Head } from './components/Head';\nimport { config } from './config';\n\nexport function registerComponents() {\n // Register custom element\n if (!customElements.get(config.tagNames.layout)) {\n customElements.define(config.tagNames.layout, Layout);\n }\n if (!customElements.get(config.tagNames.layoutOutlet)) {\n customElements.define(config.tagNames.layoutOutlet, LayoutOutlet);\n }\n if (!customElements.get(config.tagNames.outlet)) {\n customElements.define(config.tagNames.outlet, Outlet);\n }\n if (!customElements.get(config.tagNames.route)) {\n customElements.define(config.tagNames.route, Route);\n }\n if (!customElements.get(config.tagNames.router)) {\n customElements.define(config.tagNames.router, Router);\n }\n if (!customElements.get(config.tagNames.link)) {\n customElements.define(config.tagNames.link, Link);\n }\n if (!customElements.get(config.tagNames.head)) {\n customElements.define(config.tagNames.head, Head);\n }\n}","import { IWritableConfig } from \"./types\";\nimport { setConfig } from \"./config\";\nimport { registerComponents } from \"./registerComponents\";\n\n/**\n * Initialize the router with optional configuration.\n * This is the main entry point for setting up the router.\n * @param config - Optional partial configuration to override defaults\n */\nexport function bootstrapRouter(config?: Partial<IWritableConfig>): void {\n if (config) {\n setConfig(config);\n }\n registerComponents();\n}\n","import pkg from \"../package.json\" with { type: \"json\" };\nexport const VERSION = pkg.version;\n"],"names":["_config","tagNames","route","router","outlet","layout","layoutOutlet","link","head","guardHandler","enableShadowRoot","basenameFileExtensions","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","getUUID","crypto","randomUUID","replace","c","r","Math","random","toString","raiseError","message","options","Error","cause","GuardCancel","fallbackPath","constructor","super","this","builtinParamTypes","int","typeName","pattern","parse","value","test","parseInt","float","parseFloat","bool","uuid","slug","isoDate","year","month","day","split","map","Number","date","Date","getFullYear","getMonth","getDate","any","weights","static","param","RouteCore","EventTarget","protocol","version","properties","name","event","getter","e","detail","typedParams","_target","_parentCore","_path","_name","_isFallbackRoute","_segmentInfos","_absoluteSegmentInfos","_paramNames","_absoluteParamNames","_weight","_absoluteWeight","_segmentCount","_params","_typedParams","_active","_hasGuard","_guardHandler","_guardFallbackPath","_waitForSetGuardHandler","_resolveSetGuardHandler","_guardHandlerLoadFailed","target","parentCore","path","isFallbackRoute","isRelative","startsWith","segmentInfos","_checkParentCore","hasParentCallback","noParentCallback","absolutePath","parentPath","endsWith","absoluteSegmentInfos","params","active","paramNames","names","info","paramName","push","absoluteParamNames","weight","type","absoluteWeight","segmentCount","count","absoluteSegmentCount","parsePath","undefined","isFallback","isIndex","segmentText","segments","idx","length","segment","RegExp","matchType","match","includes","substring","paramType","hasGuard","guardFallback","Promise","resolve","setParams","wasActive","dispatchEvent","CustomEvent","bubbles","clearParams","shouldChange","newParams","notifyGuardHandlerLoadFailed","guardCheck","matchResult","toPath","fromPath","lastPath","Route","HTMLElement","wcBindable","_core","_routeParentNode","_routeChildNodes","_routerNode","_uuid","_placeHolder","document","createComment","_childNodeArray","_childIndex","_initialized","_routes","routeParentNode","routeChildNodes","routerNode","placeHolder","childNodeArray","Array","from","childNodes","routes","concat","childIndex","fullpath","testAncestorNode","ancestorNode","currentNode","initialize","hasAttribute","getAttribute","routeChildContainer","fallbackRoute","setAttribute","cache","Map","Layout","_loadTemplateFromSource","source","response","fetch","ok","status","templateContent","text","set","error","_loadTemplateFromDocument","id","element","getElementById","HTMLTemplateElement","innerHTML","loadTemplate","layoutId","console","warn","template","createElement","has","get","Outlet","_routesNode","_lastRoutes","routesNode","rootNode","shadowRoot","lastRoutes","_resolveEnableShadowRoot","_initialize","attachShadow","mode","connectedCallback","disconnectedCallback","bindTypeSet","Set","_assignParams","bindType","entries","props","states","removeAttribute","String","assignParams","tagName","bindTypeText","customTagName","toLowerCase","isAttr","getCustomTagName","customElements","whenDefined","then","isConnected","catch","LayoutOutlet","_layout","_initializing","_disconnectedDuringInit","_layoutChildNodes","appendChild","content","cloneNode","childNode","fragmentForTemplate","slotElementBySlotName","querySelectorAll","forEach","slotElement","slotName","fragmentBySlotName","fragmentForChildNodes","createDocumentFragment","Element","fragment","replaceWith","defaultSlot","createLayoutOutlet","loadGuardHandler","script","async","scriptModule","firstError","routeTag","sourceComment","scriptText","URL","createObjectURL","blob","Blob","url","import","revokeObjectURL","b64","btoa","fromCodePoint","TextEncoder","encode","default","importModule","handler","err","_duplicateCheck","routesByPath","existingRoute","_parseNode","node","nodeType","Node","ELEMENT_NODE","appendNode","childFragment","cloneElement","importNode","upgrade","querySelector","children","_matchRoutes","routeNode","normalizedPath","results","testResult","catchAllFound","i","segIndex","segmentInfo","exec","remainingSegments","slice","join","finalResult","testPath","childRoute","hideRoute","parentNode","removeChild","showRoute","nextSibling","insertBefore","applyRoute","fullPath","basename","sliced","topLevelRoutes","rawSegments","filter","s","sort","a","b","lastRouteA","at","lastRouteB","diffSegmentCount","diffWeight","matchRoutes","committed","routesSet","queueMicrotask","navigate","lastRouteSet","force","showRouteContent","getNavigation","nav","window","navigation","addEventListener","removeEventListener","_cachedExtensions","_cachedExtPattern","getExtPattern","exts","normalizePathname","p","extPattern","normalizeBasename","Router","inputs","attribute","commands","_outlet","_template","_basename","_fallbackRoute","_listeningPopState","_listeningNavigate","_navigateUrl","_normalizePathname","_normalizeBasename","_joinInternalPath","to","base","_notifyLocationChange","_getBasename","baseURI","pathname","_getOutlet","next","nextElementSibling","matches","body","_getTemplate","changed","navigateUrl","finally","finished","history","pushState","_isOwnPath","_onNavigateFunc","navEvent","canIntercept","hashChange","downloadRequest","destination","intercept","_onNavigate","bind","_onPopState","location","hasBaseTag","href","Link","observedAttributes","_router","_anchorElement","_onClick","ancestor","closest","root","getRootNode","found","style","display","internal","_setAnchorHref","anchor","_updateActiveState","defaultPrevented","button","metaKey","ctrlKey","shiftKey","altKey","preventDefault","remove","attributeChangedCallback","oldValue","newValue","currentPath","linkPath","classList","add","anchorElement","headStack","initialHeadValues","initialHeadCaptured","keyCache","WeakMap","Head","_childElementArray","child","_captureInitialHead","_reapplyHead","index","indexOf","splice","childElementArray","_getKey","el","cached","_computeKey","tag","src","outerHTML","media","_buildHeadElementMap","allKeys","headElementMap","targetElement","current","delete","registerComponents","define","bootstrapRouter","partialConfig","assign","isArray","VERSION"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.min.js","sources":["../../src/config.ts","../../src/getUUID.ts","../../src/raiseError.ts","../../src/GuardCancel.ts","../../src/builtinParamTypes.ts","../../src/core/RouteCore.ts","../../src/components/Route.ts","../../src/components/Layout.ts","../../src/components/Outlet.ts","../../src/assignParams.ts","../../src/getCustomTagName.ts","../../src/components/LayoutOutlet.ts","../../src/loadGuardHandler.ts","../../src/parse.ts","../../src/matchRoutes.ts","../../src/testPath.ts","../../src/hideRoute.ts","../../src/showRoute.ts","../../src/applyRoute.ts","../../src/showRouteContent.ts","../../src/Navigation.ts","../../src/normalizePathname.ts","../../src/protocol/upgradeProperties.ts","../../src/components/Router.ts","../../src/components/Link.ts","../../src/components/Head.ts","../../src/registerComponents.ts","../../src/bootstrapRouter.ts","../../src/version.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types\";\n\ninterface IInternalConfig {\n tagNames: {\n route: string;\n router: string;\n outlet: string;\n layout: string;\n layoutOutlet: string;\n link: string;\n head: string;\n guardHandler: string;\n };\n enableShadowRoot: boolean;\n basenameFileExtensions: string[];\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n route: \"wcs-route\",\n router: \"wcs-router\",\n outlet: \"wcs-outlet\",\n layout: \"wcs-layout\",\n layoutOutlet: \"wcs-layout-outlet\",\n link: \"wcs-link\",\n head: \"wcs-head\",\n guardHandler: \"wcs-guard-handler\"\n },\n enableShadowRoot: false,\n basenameFileExtensions: [\".html\"]\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// 後方互換のため config もエクスポート(読み取り専用として使用)\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n if (typeof partialConfig.enableShadowRoot === \"boolean\") {\n _config.enableShadowRoot = partialConfig.enableShadowRoot;\n }\n if (Array.isArray(partialConfig.basenameFileExtensions)) {\n _config.basenameFileExtensions = partialConfig.basenameFileExtensions;\n }\n frozenConfig = null;\n}\n","\nexport function getUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Simple UUID generator\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}","\nexport function raiseError(message: string, options?: { cause?: unknown }): never {\n if (options && 'cause' in options) {\n throw new Error(`[@wcstack/router] ${message}`, { cause: options.cause });\n }\n throw new Error(`[@wcstack/router] ${message}`);\n}","import { IGuardCancel } from \"./types\";\n\nexport class GuardCancel extends Error implements IGuardCancel {\n fallbackPath: string;\n\n constructor(message: string, fallbackPath: string) {\n super(message);\n this.fallbackPath = fallbackPath;\n }\n}","import { BuiltinParamTypes, IParamTypeInfo } from \"./types\";\n\nexport const builtinParamTypes = {\n \"int\": {\n typeName: \"int\",\n pattern: /^-?\\d+$/,\n parse(value: string): number | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return parseInt(value, 10);\n }\n },\n\n \"float\": {\n typeName: \"float\",\n pattern: /^-?\\d+(?:\\.\\d+)?$/,\n parse(value: string): number | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return parseFloat(value);\n }\n },\n\n \"bool\": {\n typeName: \"bool\",\n pattern: /^(true|false|0|1)$/,\n parse(value: string): boolean | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value === \"true\" || value === \"1\";\n }\n },\n\n \"uuid\": {\n typeName: \"uuid\",\n pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n parse(value: string): string | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value;\n }\n },\n\n \"slug\": {\n typeName: \"slug\",\n pattern: /^[a-z0-9]+(?:-[a-z0-9]+)*$/,\n parse(value: string): string | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value;\n }\n },\n\n \"isoDate\": {\n typeName: \"isoDate\",\n pattern: /^\\d{4}-\\d{2}-\\d{2}$/,\n parse(value: string): Date | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n const [year, month, day] = value.split(\"-\").map(Number);\n const date = new Date(year, month - 1, day);\n // 元の値と一致するか確認(補正されていないか)\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return undefined;\n }\n return date;\n }\n },\n\n \"any\": {\n typeName: \"any\",\n pattern: /^.+$/,\n parse(value: string): string | undefined {\n if (!this.pattern.test(value)) {\n return undefined;\n }\n return value;\n }\n },\n} satisfies Record<BuiltinParamTypes, IParamTypeInfo<unknown>>;\n","import { GuardCancel } from \"../GuardCancel.js\";\nimport { builtinParamTypes } from \"../builtinParamTypes.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { config } from \"../config.js\";\nimport { ISegmentInfo, SegmentType, IRouteMatchResult, GuardHandler } from \"../components/types.js\";\nimport { BuiltinParamTypes, IWcBindable } from \"../types.js\";\n\nconst weights: Record<SegmentType, number> = {\n 'static': 2,\n 'param': 1,\n 'catch-all': 0\n};\n\nexport interface RouteParseOptions {\n isIndex?: boolean;\n isFallback?: boolean;\n hasGuard?: boolean;\n guardFallback?: string | null;\n name?: string;\n}\n\nexport class RouteCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"params\", event: \"wcs-route:params-changed\", semantics: \"state\" },\n { name: \"typedParams\", event: \"wcs-route:params-changed\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.typedParams },\n { name: \"active\", event: \"wcs-route:active-changed\", semantics: \"state\" },\n ],\n };\n\n private _target: EventTarget;\n private _parentCore: RouteCore | null = null;\n private _path: string = '';\n private _name: string = '';\n private _isFallbackRoute: boolean = false;\n private _segmentInfos: ISegmentInfo[] = [];\n private _absoluteSegmentInfos: ISegmentInfo[] | undefined;\n private _paramNames: string[] | undefined;\n private _absoluteParamNames: string[] | undefined;\n private _weight: number | undefined;\n private _absoluteWeight: number | undefined;\n private _segmentCount: number | undefined;\n private _params: Record<string, string> = {};\n private _typedParams: Record<string, any> = {};\n private _active: boolean = false;\n\n // Guard\n private _hasGuard: boolean = false;\n private _guardHandler: GuardHandler | null = null;\n private _guardFallbackPath: string = '';\n private _waitForSetGuardHandler: Promise<void> | null = null;\n private _resolveSetGuardHandler: (() => void) | null = null;\n private _guardHandlerLoadFailed: boolean = false;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get parentCore(): RouteCore | null {\n return this._parentCore;\n }\n\n set parentCore(value: RouteCore | null) {\n this._parentCore = value;\n }\n\n get path(): string {\n return this._path;\n }\n\n get name(): string {\n return this._name;\n }\n\n get isFallbackRoute(): boolean {\n return this._isFallbackRoute;\n }\n\n get isRelative(): boolean {\n return !this._path.startsWith('/');\n }\n\n get segmentInfos(): ISegmentInfo[] {\n return this._segmentInfos;\n }\n\n private _checkParentCore<T>(\n hasParentCallback: (parentCore: RouteCore) => T,\n noParentCallback: () => T\n ): T {\n if (!this._isFallbackRoute) {\n if (this.isRelative && !this._parentCore) {\n raiseError(`${config.tagNames.route} is relative but has no parent route.`);\n }\n if (!this.isRelative && this._parentCore) {\n raiseError(`${config.tagNames.route} is absolute but has a parent route.`);\n }\n }\n if (this.isRelative && this._parentCore) {\n return hasParentCallback(this._parentCore);\n } else {\n return noParentCallback();\n }\n }\n\n get absolutePath(): string {\n return this._checkParentCore<string>((parentCore) => {\n const parentPath = parentCore.absolutePath;\n return parentPath.endsWith('/')\n ? parentPath + this._path\n : parentPath + '/' + this._path;\n }, () => {\n return this._path;\n });\n }\n\n get absoluteSegmentInfos(): ISegmentInfo[] {\n if (typeof this._absoluteSegmentInfos === 'undefined') {\n this._absoluteSegmentInfos = this._checkParentCore<ISegmentInfo[]>((parentCore) => {\n return [\n ...parentCore.absoluteSegmentInfos,\n ...this._segmentInfos\n ];\n }, () => {\n return [...this._segmentInfos];\n });\n }\n return this._absoluteSegmentInfos;\n }\n\n get params(): Record<string, string> {\n return this._params;\n }\n\n get typedParams(): Record<string, any> {\n return this._typedParams;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get paramNames(): string[] {\n if (typeof this._paramNames === 'undefined') {\n const names: string[] = [];\n for (const info of this._segmentInfos) {\n if (info.paramName) {\n names.push(info.paramName);\n }\n }\n this._paramNames = names;\n }\n return this._paramNames;\n }\n\n get absoluteParamNames(): string[] {\n if (typeof this._absoluteParamNames === 'undefined') {\n this._absoluteParamNames = this._checkParentCore<string[]>((parentCore) => {\n return [\n ...parentCore.absoluteParamNames,\n ...this.paramNames\n ];\n }, () => {\n return [...this.paramNames];\n });\n }\n return this._absoluteParamNames;\n }\n\n get weight(): number {\n if (typeof this._weight === 'undefined') {\n let weight = 0;\n for (const info of this._segmentInfos) {\n weight += weights[info.type];\n }\n this._weight = weight;\n }\n return this._weight;\n }\n\n get absoluteWeight(): number {\n if (typeof this._absoluteWeight === 'undefined') {\n this._absoluteWeight = this._checkParentCore<number>((parentCore) => {\n return parentCore.absoluteWeight + this.weight;\n }, () => {\n return this.weight;\n });\n }\n return this._absoluteWeight;\n }\n\n get segmentCount(): number {\n if (typeof this._segmentCount === 'undefined') {\n let count = 0;\n for (const info of this._segmentInfos) {\n if (info.type !== 'catch-all') {\n count++;\n }\n }\n this._segmentCount = this._path === \"\" ? 0 : count;\n }\n return this._segmentCount;\n }\n\n get absoluteSegmentCount(): number {\n return this._checkParentCore<number>((parentCore) => {\n return parentCore.absoluteSegmentCount + this.segmentCount;\n }, () => {\n return this.segmentCount;\n });\n }\n\n parsePath(path: string, options: RouteParseOptions = {}): void {\n // 連続呼び出し時のセグメント累積を防ぐためリセット\n this._segmentInfos = [];\n this._absoluteSegmentInfos = undefined;\n this._paramNames = undefined;\n this._absoluteParamNames = undefined;\n this._weight = undefined;\n this._absoluteWeight = undefined;\n this._segmentCount = undefined;\n this._path = path;\n this._name = options.name || '';\n this._isFallbackRoute = options.isFallback || false;\n\n if (options.isIndex) {\n this._segmentInfos.push({\n type: 'static',\n segmentText: '',\n paramName: null,\n pattern: /^$/,\n isIndex: true\n });\n }\n\n const segments = path.split('/');\n for (let idx = 0; idx < segments.length; idx++) {\n const segment = segments[idx];\n // 末尾の空セグメントはスキップ(/parent/ のような場合)\n if (segment === '' && idx === segments.length - 1 && idx > 0) {\n continue;\n }\n if (segment === '*') {\n this._segmentInfos.push({\n type: 'catch-all',\n segmentText: segment,\n paramName: '*',\n pattern: new RegExp('^(.*)$')\n });\n // Catch-all: matches remaining path segments\n break; // Ignore subsequent segments\n } else if (segment.startsWith(':')) {\n const matchType = segment.match(/^:([^()]+)(\\(([^)]+)\\))?$/);\n let paramName: string;\n let typeName: BuiltinParamTypes = 'any';\n if (matchType) {\n paramName = matchType[1];\n if (matchType[3] && Object.keys(builtinParamTypes).includes(matchType[3])) {\n typeName = matchType[3] as BuiltinParamTypes;\n }\n } else {\n paramName = segment.substring(1);\n }\n\n this._segmentInfos.push({\n type: 'param',\n segmentText: segment,\n paramName: paramName,\n pattern: new RegExp('^([^\\\\/]+)$'),\n paramType: typeName\n });\n } else if (segment !== '' || !options.isIndex) {\n // 空セグメントはindex以外の場合のみ追加(絶対パスの先頭 '' など)\n this._segmentInfos.push({\n type: 'static',\n segmentText: segment,\n paramName: null,\n pattern: new RegExp(`^${segment}$`)\n });\n }\n }\n\n this._hasGuard = options.hasGuard || false;\n if (this._hasGuard) {\n this._guardFallbackPath = options.guardFallback || '/';\n this._waitForSetGuardHandler = new Promise((resolve) => {\n this._resolveSetGuardHandler = resolve;\n });\n }\n }\n\n setParams(params: Record<string, string>, typedParams: Record<string, any>): void {\n const wasActive = this._active;\n this._params = params;\n this._typedParams = typedParams;\n this._active = true;\n this._target.dispatchEvent(new CustomEvent(\"wcs-route:params-changed\", {\n detail: { params, typedParams },\n bubbles: true,\n }));\n if (!wasActive) {\n this._target.dispatchEvent(new CustomEvent(\"wcs-route:active-changed\", {\n detail: true,\n bubbles: true,\n }));\n }\n }\n\n clearParams(): void {\n const wasActive = this._active;\n this._params = {};\n this._typedParams = {};\n this._active = false;\n if (wasActive) {\n this._target.dispatchEvent(new CustomEvent(\"wcs-route:active-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n shouldChange(newParams: Record<string, string>): boolean {\n for (const key of this.paramNames) {\n if (this._params[key] !== newParams[key]) {\n return true;\n }\n }\n return false;\n }\n\n get guardHandler(): GuardHandler {\n if (!this._guardHandler) {\n raiseError(`${config.tagNames.route} has no guardHandler.`);\n }\n return this._guardHandler!;\n }\n\n set guardHandler(value: GuardHandler) {\n this._guardHandler = value;\n this._resolveSetGuardHandler?.();\n }\n\n /**\n * Guardハンドラのロードに失敗したことを通知し、guardCheck の待ちを解除する。\n * 解除後の guardCheck は guardHandler が未設定のため fallback パスへリダイレクトする。\n */\n notifyGuardHandlerLoadFailed(): void {\n this._guardHandlerLoadFailed = true;\n this._resolveSetGuardHandler?.();\n }\n\n async guardCheck(matchResult: IRouteMatchResult): Promise<void> {\n if (this._hasGuard && this._waitForSetGuardHandler) {\n await this._waitForSetGuardHandler;\n }\n if (this._guardHandler) {\n const toPath = matchResult.path;\n const fromPath = matchResult.lastPath;\n const allowed = await this._guardHandler(toPath, fromPath);\n if (!allowed) {\n throw new GuardCancel('Navigation cancelled by guard.', this._guardFallbackPath);\n }\n } else if (this._hasGuard && this._guardHandlerLoadFailed) {\n // guardHandler のロードに失敗した場合は fallback パスへ\n throw new GuardCancel('Navigation cancelled: guard handler failed to load.', this._guardFallbackPath);\n }\n }\n}\n","import { getUUID } from \"../getUUID.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IRouteMatchResult, IRoute, IRouter, GuardHandler, ISegmentInfo } from \"./types.js\";\nimport { RouteCore } from \"../core/RouteCore.js\";\nimport { IWcBindable } from \"../types.js\";\n\nexport class Route extends HTMLElement implements IRoute {\n static wcBindable: IWcBindable = RouteCore.wcBindable;\n\n private _core: RouteCore;\n private _routeParentNode: IRoute | null = null;\n private _routeChildNodes: IRoute[] = [];\n private _routerNode: IRouter | null = null;\n private _uuid: string = getUUID();\n private _placeHolder: Comment = document.createComment(`@@route:${this._uuid}`);\n private _childNodeArray: Node[] | undefined;\n private _childIndex: number = 0;\n private _initialized: boolean = false;\n private _routes: IRoute[] | undefined;\n\n constructor() {\n super();\n this._core = new RouteCore(this);\n }\n\n // Shell-only properties\n\n get routeParentNode(): IRoute | null {\n return this._routeParentNode;\n }\n\n get routeChildNodes(): IRoute[] {\n return this._routeChildNodes;\n }\n\n get routerNode(): IRouter {\n if (!this._routerNode) {\n raiseError(`${config.tagNames.route} has no routerNode.`);\n }\n return this._routerNode;\n }\n\n get uuid(): string {\n return this._uuid;\n }\n\n get placeHolder(): Comment {\n return this._placeHolder;\n }\n\n get childNodeArray(): Node[] {\n if (typeof this._childNodeArray === 'undefined') {\n this._childNodeArray = Array.from(this.childNodes);\n }\n return this._childNodeArray;\n }\n\n get routes(): IRoute[] {\n // matchRoutes / testPath のホットパスで再帰的に呼ばれるため遅延キャッシュする。\n // initialize 後は routeParentNode が固定されるためキャッシュしても安全。\n if (typeof this._routes === 'undefined') {\n this._routes = this.routeParentNode\n ? this.routeParentNode.routes.concat(this)\n : [this];\n }\n return this._routes;\n }\n\n get childIndex(): number {\n return this._childIndex;\n }\n\n // Core delegates\n\n get path(): string {\n return this._core.path;\n }\n\n get name(): string {\n return this._core.name;\n }\n\n get isRelative(): boolean {\n return this._core.isRelative;\n }\n\n get absolutePath(): string {\n return this._core.absolutePath;\n }\n\n get segmentInfos(): ISegmentInfo[] {\n return this._core.segmentInfos;\n }\n\n get absoluteSegmentInfos(): ISegmentInfo[] {\n return this._core.absoluteSegmentInfos;\n }\n\n get params(): Record<string, string> {\n return this._core.params;\n }\n\n get typedParams(): Record<string, any> {\n return this._core.typedParams;\n }\n\n get paramNames(): string[] {\n return this._core.paramNames;\n }\n\n get absoluteParamNames(): string[] {\n return this._core.absoluteParamNames;\n }\n\n get weight(): number {\n return this._core.weight;\n }\n\n get absoluteWeight(): number {\n return this._core.absoluteWeight;\n }\n\n get segmentCount(): number {\n return this._core.segmentCount;\n }\n\n get absoluteSegmentCount(): number {\n return this._core.absoluteSegmentCount;\n }\n\n get fullpath(): string {\n return this.absolutePath;\n }\n\n get guardHandler(): GuardHandler {\n return this._core.guardHandler;\n }\n\n set guardHandler(value: GuardHandler) {\n this._core.guardHandler = value;\n }\n\n setParams(params: Record<string, string>, typedParams: Record<string, any>): void {\n this._core.setParams(params, typedParams);\n }\n\n clearParams(): void {\n this._core.clearParams();\n }\n\n shouldChange(newParams: Record<string, string>): boolean {\n return this._core.shouldChange(newParams);\n }\n\n async guardCheck(matchResult: IRouteMatchResult): Promise<void> {\n return this._core.guardCheck(matchResult);\n }\n\n notifyGuardHandlerLoadFailed(): void {\n this._core.notifyGuardHandlerLoadFailed();\n }\n\n /**\n * Shell(Route)の routeParentNode を辿って祖先関係を判定する。\n *\n * 責務の分担:\n * - Route(このクラス)は DOM ツリー上の親子関係(routeParentNode)を管理する。\n * - RouteCore はパスやパラメータといった論理的な親子関係(parentCore)を管理する。\n * DOM ツリーは Shell 層、論理ツリーは Core 層という分離のため、両者を独立に保持する。\n */\n testAncestorNode(ancestorNode: IRoute): boolean {\n let currentNode: IRoute | null = this._routeParentNode;\n while (currentNode) {\n if (currentNode === ancestorNode) {\n return true;\n }\n currentNode = currentNode.routeParentNode;\n }\n return false;\n }\n\n initialize(routerNode: IRouter, routeParentNode: IRoute | null): void {\n if (this._initialized) {\n return;\n }\n this._initialized = true;\n\n // 属性からパス情報を読み取り\n let path: string;\n let isIndex = false;\n let isFallback = false;\n\n if (this.hasAttribute('path')) {\n path = this.getAttribute('path') || '';\n } else if (this.hasAttribute('index')) {\n path = '';\n isIndex = true;\n } else if (this.hasAttribute('fallback')) {\n path = '';\n isFallback = true;\n } else {\n raiseError(`${config.tagNames.route} should have a \"path\" or \"index\" attribute.`);\n }\n\n // ルートツリーの構築\n this._routerNode = routerNode;\n this._routeParentNode = routeParentNode;\n const routeChildContainer = routeParentNode || routerNode;\n routeChildContainer.routeChildNodes.push(this);\n this._childIndex = routeChildContainer.routeChildNodes.length - 1;\n\n // Fallback検証\n if (isFallback) {\n if (routeParentNode) {\n raiseError(`${config.tagNames.route} with fallback attribute must be a direct child of ${config.tagNames.router}.`);\n }\n if (routerNode.fallbackRoute) {\n raiseError(`${config.tagNames.router} can have only one fallback route.`);\n }\n routerNode.fallbackRoute = this;\n }\n\n // 親CoreをCoreに設定\n if (routeParentNode) {\n this._core.parentCore = (routeParentNode as Route)._core;\n }\n\n // Coreでパス解析\n this._core.parsePath(path!, {\n isIndex,\n isFallback,\n hasGuard: this.hasAttribute('guard'),\n guardFallback: this.getAttribute('guard'),\n name: this.getAttribute('name') || '',\n });\n\n this.setAttribute('fullpath', this.absolutePath);\n }\n}\n","import { getUUID } from \"../getUUID.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { ILayout } from \"./types.js\";\n\nconst cache = new Map<string, string>();\n\n/**\n * Layout テンプレートキャッシュをクリアする。\n * テストや長時間 SPA でメモリリークを避けるため、リセットしたい場合に利用する。\n */\nexport function _clearLayoutCache(): void {\n cache.clear();\n}\n\nexport class Layout extends HTMLElement implements ILayout {\n private _uuid: string = getUUID();\n constructor() {\n super();\n }\n\n private async _loadTemplateFromSource(source: string): Promise<string> {\n try {\n const response = await fetch(source);\n if (!response.ok) {\n raiseError(`${config.tagNames.layout} failed to fetch layout from source: ${source}, status: ${response.status}`);\n }\n const templateContent = await response.text();\n cache.set(source, templateContent);\n return templateContent;\n } catch (error) {\n // 元の例外を cause として伝播し、スタックトレースを保持する\n raiseError(\n `${config.tagNames.layout} failed to load layout from source: ${source}, error: ${error}`,\n { cause: error }\n );\n }\n }\n\n private _loadTemplateFromDocument(id: string): string | null {\n const element = document.getElementById(`${id}`) as HTMLElement | null;\n if (element) {\n if (element instanceof HTMLTemplateElement) {\n return element.innerHTML;\n }\n }\n return null;\n }\n\n async loadTemplate(): Promise<HTMLTemplateElement> {\n const source = this.getAttribute('src');\n const layoutId = this.getAttribute('layout');\n if (source && layoutId) {\n console.warn(`${config.tagNames.layout} have both \"src\" and \"layout\" attributes.`);\n }\n const template = document.createElement('template');\n if (source) {\n if (cache.has(source)) {\n template.innerHTML = cache.get(source) || '';\n } else {\n // _loadTemplateFromSource は内部で cache.set を実行する\n template.innerHTML = await this._loadTemplateFromSource(source) || '';\n }\n } else if (layoutId) {\n const templateContent = this._loadTemplateFromDocument(layoutId);\n if (templateContent) {\n template.innerHTML = templateContent;\n } else {\n console.warn(`${config.tagNames.layout} could not find template with id \"${layoutId}\".`);\n }\n }\n return template;\n }\n\n get uuid(): string {\n return this._uuid;\n }\n\n get enableShadowRoot(): boolean {\n if (this.hasAttribute('enable-shadow-root')) {\n return true;\n } else if (this.hasAttribute('disable-shadow-root')) {\n return false;\n }\n return config.enableShadowRoot;\n }\n\n get name(): string {\n // Layout 要素が DOM に挿入されないケース(parseで置換)でも name を取れるようにする\n return this.getAttribute('name') || '';\n }\n}\n","import { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IOutlet, IRoute, IRouter } from \"./types.js\";\n\nexport class Outlet extends HTMLElement implements IOutlet {\n private _routesNode: IRouter | null = null;\n private _lastRoutes: IRoute[] = [];\n private _initialized: boolean = false;\n constructor() {\n super();\n }\n\n get routesNode(): IRouter {\n if (!this._routesNode) {\n raiseError(`${config.tagNames.outlet} has no routesNode.`);\n }\n return this._routesNode;\n }\n set routesNode(value: IRouter) {\n this._routesNode = value;\n }\n\n get rootNode(): HTMLElement | ShadowRoot {\n if (this.shadowRoot) {\n return this.shadowRoot;\n }\n return this;\n }\n\n get lastRoutes(): IRoute[] {\n return this._lastRoutes;\n }\n set lastRoutes(value: IRoute[]) {\n this._lastRoutes = [ ...value ];\n }\n\n /**\n * shadowRoot 有効化判定。Layout と挙動を揃え、属性で個別オーバーライド可能にする。\n * - `enable-shadow-root` 属性あり → true\n * - `disable-shadow-root` 属性あり → false\n * - いずれもなし → config.enableShadowRoot を尊重\n */\n private _resolveEnableShadowRoot(): boolean {\n if (this.hasAttribute('enable-shadow-root')) {\n return true;\n }\n if (this.hasAttribute('disable-shadow-root')) {\n return false;\n }\n return config.enableShadowRoot;\n }\n\n private _initialize() {\n if (this._resolveEnableShadowRoot()) {\n this.attachShadow({ mode: 'open' });\n }\n this._initialized = true;\n }\n\n connectedCallback() {\n if (!this._initialized) {\n this._initialize();\n }\n }\n\n /**\n * Outlet が disconnect された際の状態クリーンアップ。\n *\n * `_lastRoutes` をクリアすることで、再接続後の applyRoute における diff\n * (既に show 済みのルートは show を skip する判定)が、切断中に外部から\n * 操作された DOM と整合しなくなる事故を防ぐ。\n *\n * 仕様前提として Outlet は Router と一体運用される(Router が `_getOutlet()` で\n * 自身の兄弟に Outlet を配置・参照する)。それでも単独で再接続される\n * エッジケースに備える防衛的措置として `_lastRoutes` のみクリアする。\n * `_initialized` と shadowRoot は維持し、再 attachShadow による\n * InvalidStateError を回避する。\n */\n disconnectedCallback() {\n this._lastRoutes = [];\n }\n}\n\nexport function createOutlet(): Outlet {\n return document.createElement(config.tagNames.outlet) as Outlet;\n}\n","import { BindType } from \"./components/types\";\nimport { getCustomTagName } from \"./getCustomTagName\";\nimport { raiseError } from \"./raiseError\";\n\nconst bindTypeSet: Set<BindType> = new Set([ \"props\", \"states\", \"attr\", \"\" ]);\n\nfunction _assignParams(element: Element, params: Record<string, any>, bindType: BindType) {\n for(const [key, value] of Object.entries(params)) {\n switch(bindType) {\n case \"props\":\n (element as any).props = {\n ...(element as any).props,\n [key]: value\n };\n break;\n case \"states\":\n (element as any).states = {\n ...(element as any).states,\n [key]: value\n };\n break;\n case \"attr\":\n // null/undefined は属性削除として扱う(文字列 \"null\"/\"undefined\" になる事故を防ぐ)。\n // boolean/number は setAttribute の標準挙動に従って文字列化される。\n if (value === null || value === undefined) {\n element.removeAttribute(key);\n } else {\n element.setAttribute(key, String(value));\n }\n break;\n case \"\":\n (element as any)[key] = value;\n break;\n }\n }\n}\n\nexport function assignParams(element: Element, params: Record<string, any>) {\n if (!element.hasAttribute('data-bind')) {\n raiseError(`${element.tagName} has no 'data-bind' attribute.`);\n }\n const bindTypeText = element.getAttribute('data-bind') || '';\n if (!bindTypeSet.has(bindTypeText as BindType)) {\n raiseError(`${element.tagName} has invalid 'data-bind' attribute: ${bindTypeText}`);\n }\n const bindType = bindTypeText as BindType;\n const customTagName = getCustomTagName(element);\n if (customTagName && customElements.get(customTagName) === undefined) {\n // 注意: customElements.whenDefined(tag) は当該タグが define されるまで pending のままになる。\n // element が削除されてもこの Promise は GC されず、closure に保持される element/params は\n // 解放されない(弱い参照を持つ手段がないため)。define されないまま要素のみが大量に作られる\n // ようなケースではリークになりうるが、通常の Web Components 利用では autoloader が\n // 一括 define するため実用上問題にならない。明示的にキャンセルしたい場合は将来 AbortSignal を\n // サポートすることを検討する。\n customElements.whenDefined(customTagName).then(() => {\n if (element.isConnected) {\n // 要素が削除されていない場合のみ割り当てを行う\n _assignParams(element, params, bindType);\n }\n }).catch(() => {\n raiseError(`Failed to define custom element: ${customTagName}`);\n });\n } else {\n _assignParams(element, params, bindType);\n }\n}","\nexport function getCustomTagName(element: Element): string | null {\n const tagName = element.tagName.toLowerCase();\n if (tagName.includes(\"-\")) {\n return tagName;\n }\n const isAttr = element.getAttribute(\"is\");\n if (isAttr && isAttr.includes(\"-\")) {\n return isAttr;\n }\n return null;\n}","import { assignParams } from \"../assignParams.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { ILayout, ILayoutOutlet } from \"./types.js\";\n\nexport class LayoutOutlet extends HTMLElement implements ILayoutOutlet {\n private _layout: (ILayout & Pick<Element,'childNodes'>) | null = null;\n private _initialized: boolean = false;\n private _initializing: boolean = false;\n private _disconnectedDuringInit: boolean = false;\n private _layoutChildNodes: Node[] = [];\n constructor() {\n super();\n }\n\n get layout(): ILayout {\n if (!this._layout) {\n raiseError(`${config.tagNames.layoutOutlet} has no layout.`);\n }\n return this._layout;\n }\n set layout(value: ILayout) {\n this._layout = value;\n this.setAttribute('name', value.name);\n }\n \n get name(): string {\n return this.layout.name;\n }\n\n private async _initialize(): Promise<void> {\n this._initializing = true;\n try {\n this._initialized = true;\n // attachShadow は冪等にする: 一度 await loadTemplate() 中に切断されると\n // _initialized = false で戻され、再 connect 時に _initialize() が再度走るが、\n // その時点で shadowRoot は既に存在しているため、再度 attachShadow すると\n // InvalidStateError になる。\n if (this.layout.enableShadowRoot && !this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n const template = await this.layout.loadTemplate();\n // await 中に切断された場合は DOM 副作用を残さず、次回再接続時に再初期化させる\n if (!this.isConnected) {\n this._initialized = false;\n return;\n }\n if (this.shadowRoot) {\n this.shadowRoot.appendChild(template.content.cloneNode(true));\n for(const childNode of Array.from(this.layout.childNodes)) {\n this._layoutChildNodes.push(childNode);\n this.appendChild(childNode);\n }\n } else {\n const fragmentForTemplate = template.content.cloneNode(true) as DocumentFragment;\n const slotElementBySlotName: Map<string, Element> = new Map();\n fragmentForTemplate.querySelectorAll('slot').forEach((slotElement) => {\n const slotName = slotElement.getAttribute('name') || '';\n if (!slotElementBySlotName.has(slotName)) {\n slotElementBySlotName.set(slotName, slotElement);\n } else {\n console.warn(`${config.tagNames.layoutOutlet} duplicate slot name \"${slotName}\" in layout template.`);\n }\n });\n\n const fragmentBySlotName: Map<string, DocumentFragment> = new Map();\n const fragmentForChildNodes = document.createDocumentFragment();\n for(const childNode of Array.from(this.layout.childNodes)) {\n this._layoutChildNodes.push(childNode);\n if (childNode instanceof Element) {\n const slotName = childNode.getAttribute('slot') || '';\n if (slotName.length > 0 && slotElementBySlotName.has(slotName)) {\n if (!fragmentBySlotName.has(slotName)) {\n fragmentBySlotName.set(slotName, document.createDocumentFragment());\n }\n fragmentBySlotName.get(slotName)?.appendChild(childNode);\n continue;\n }\n }\n fragmentForChildNodes.appendChild(childNode);\n }\n for(const [slotName, slotElement] of slotElementBySlotName) {\n const fragment = fragmentBySlotName.get(slotName);\n if (fragment) {\n slotElement.replaceWith(fragment);\n }\n }\n const defaultSlot = slotElementBySlotName.get('');\n if (defaultSlot) {\n defaultSlot.replaceWith(fragmentForChildNodes);\n }\n\n this.appendChild(fragmentForTemplate);\n }\n } finally {\n this._initializing = false;\n }\n }\n\n async connectedCallback() {\n if (!this._initialized) {\n this._disconnectedDuringInit = false;\n await this._initialize();\n // 初期化中(await 中)に切断された場合は副作用を残さない\n if (this._disconnectedDuringInit || !this.isConnected) {\n return;\n }\n }\n }\n\n disconnectedCallback() {\n // _initialize 中(await 中)に呼ばれた場合はフラグを立てて再 connect 時に init を許可する\n if (this._initializing) {\n this._disconnectedDuringInit = true;\n }\n }\n\n assignParams(params: Record<string, any>): void {\n for(const childNode of this._layoutChildNodes) {\n if (childNode instanceof Element) {\n childNode.querySelectorAll('[data-bind]').forEach((e) => {\n // 子要素にパラメータを割り当て\n assignParams(e, params);\n });\n if (childNode.hasAttribute('data-bind')) {\n // 子要素にパラメータを割り当て\n assignParams(childNode, params);\n }\n }\n }\n }\n}\n\nexport function createLayoutOutlet(): LayoutOutlet {\n return document.createElement(config.tagNames.layoutOutlet) as LayoutOutlet;\n}","import { GuardHandler } from \"./components/types.js\";\nimport { IRoute } from \"./components/types.js\";\n\ntype ScriptModule = { default?: unknown };\n\nasync function importModule(script: HTMLScriptElement, route: IRoute): Promise<GuardHandler | null> {\n let scriptModule: ScriptModule | null = null;\n let firstError: unknown = null;\n // devtools での識別用 sourceURL suffix。\n // uuid を使う: Route インスタンスでは constructor で getUUID() により必ず設定される。\n // partial mock 等で undefined の可能性に備えて空文字列フォールバックを置く。\n const routeTag = route.uuid || \"\";\n const sourceURL = routeTag ? `wcs-guard-handler:${routeTag}` : `wcs-guard-handler`;\n const sourceComment = `\\n//# sourceURL=${sourceURL}\\n`;\n const scriptText = script.text + sourceComment;\n if (typeof URL.createObjectURL === 'function') {\n const blob = new Blob([scriptText], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n try {\n scriptModule = await import(url) as ScriptModule;\n } catch (e) {\n // Blob URL import failed (e.g. happy-dom), fall through to data: URL\n firstError = e;\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n if (!scriptModule) {\n // Fallback: Base64 data: URL (for test environments)\n const b64 = btoa(String.fromCodePoint(...new TextEncoder().encode(scriptText)));\n try {\n scriptModule = await import(`data:application/javascript;base64,${b64}`) as ScriptModule;\n } catch (e) {\n // 両 import が失敗した場合、Blob URL 側の元エラーを cause として失わないように包む\n // (Blob URL も失敗していなければ firstError は null)\n throw new Error(\n `loadGuardHandler: failed to import guard script. ` +\n `data: URL error: ${(e as Error)?.message ?? String(e)}` +\n (firstError ? `. Blob URL error: ${(firstError as Error)?.message ?? String(firstError)}` : ''),\n { cause: firstError ?? e }\n );\n }\n }\n if (scriptModule && typeof scriptModule.default === 'function') {\n return scriptModule.default as GuardHandler;\n }\n return null;\n}\n\nexport function loadGuardHandler(script: HTMLScriptElement, route: IRoute): void {\n importModule(script, route).then(handler => {\n if (handler) {\n route.guardHandler = handler;\n } else {\n // ハンドラが取得できなかった場合は guardCheck の待ちを解除する\n route.notifyGuardHandlerLoadFailed();\n }\n }).catch(err => {\n console.error('loadGuardHandler failed:', err);\n // import 失敗時も guardCheck の待ちを解除する\n route.notifyGuardHandlerLoadFailed();\n });\n}\n","import { IRoute, IRouter } from \"./components/types.js\";\nimport { Layout } from \"./components/Layout.js\";\nimport { createLayoutOutlet } from \"./components/LayoutOutlet.js\";\nimport { Route } from \"./components/Route.js\";\nimport { config } from \"./config.js\";\nimport { loadGuardHandler } from \"./loadGuardHandler.js\";\n\n\n/**\n * 同一の絶対パスを持つ Route が複数定義された場合に警告を出力する。\n *\n * 仕様: 同一 absolutePath ごとに 1 回だけ警告する(複数重複でも警告は 1 件)。\n * これは過剰なログを避けるための意図的な設計。\n * テストでは Vitest の console.warn spy で 1 回出力を確認する。\n */\nfunction _duplicateCheck(routesByPath: Map<string, IRoute[]>, route: IRoute): void {\n let routes = routesByPath.get(route.absolutePath);\n if (!routes) {\n routes = [];\n }\n for(const existingRoute of routes) {\n if (!route.testAncestorNode(existingRoute)) {\n console.warn(`Duplicate route path detected: '${route.absolutePath}' (defined as '${route.path}')`);\n break;\n }\n }\n routes.push(route);\n if (routes.length === 1) {\n routesByPath.set(route.absolutePath, routes);\n }\n}\n\nasync function _parseNode(\n routerNode: IRouter,\n node: Node,\n routes: IRoute[],\n routesByPath: Map<string, IRoute[]>\n): Promise<DocumentFragment> {\n const routeParentNode: IRoute | null = routes.length > 0 ? routes[routes.length - 1] : null;\n const fragment = document.createDocumentFragment();\n const childNodes = Array.from(node.childNodes);\n for(const childNode of childNodes) {\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n let appendNode = childNode\n let element = childNode as HTMLElement;\n const tagName = element.tagName.toLowerCase();\n if (tagName === config.tagNames.route) {\n const childFragment = document.createDocumentFragment();\n // Move child nodes to fragment to avoid duplication of\n for(const childNode of Array.from(element.childNodes)) {\n childFragment.appendChild(childNode);\n }\n const cloneElement = document.importNode<Route>(element as Route, true);\n customElements.upgrade(cloneElement);\n cloneElement.appendChild(childFragment);\n const route = cloneElement;\n route.initialize(routerNode, routeParentNode);\n _duplicateCheck(routesByPath, route);\n routes.push(route);\n appendNode = route.placeHolder;\n element = route;\n } else if (tagName === config.tagNames.guardHandler) {\n if (routes.length > 0) {\n const route = routes[routes.length - 1];\n const script = element.querySelector('script[type=\"module\"]');\n if (script) {\n loadGuardHandler(script as HTMLScriptElement, route);\n }\n }\n continue;\n } else if (tagName === config.tagNames.layout) {\n // <wcs-layout> は他の case と異なり element と appendNode が別物になる。\n // - element: cloneElement (Layout 本体)。後続の `element.innerHTML = \"\"; element.appendChild(children)`\n // で再帰結果が Layout 内に流し込まれる。Layout はそれを slot 投影に使う。\n // - appendNode: layoutOutlet。最終的に fragment へ挿入されるのは layoutOutlet で、\n // layoutOutlet が element (Layout) を参照して投影を行う。\n const childFragment = document.createDocumentFragment();\n // Move child nodes to fragment to avoid duplication of\n for(const childNode of Array.from(element.childNodes)) {\n childFragment.appendChild(childNode);\n }\n const cloneElement = document.importNode(element, true);\n customElements.upgrade(cloneElement);\n cloneElement.appendChild(childFragment);\n const layout = cloneElement;\n const layoutOutlet = createLayoutOutlet();\n layoutOutlet.layout = layout as Layout;\n appendNode = layoutOutlet;\n element = cloneElement;\n }\n const children = await _parseNode(routerNode, element, routes, routesByPath);\n element.innerHTML = \"\";\n element.appendChild(children);\n fragment.appendChild(appendNode);\n } else {\n fragment.appendChild(childNode);\n }\n }\n return fragment;\n}\n\nexport async function parse(routerNode: IRouter): Promise<DocumentFragment> {\n const routesByPath: Map<string, IRoute[]> = new Map();\n const fr = await _parseNode(routerNode, routerNode.template.content, [], routesByPath);\n return fr;\n}","import { IRoute, IRouteMatchResult, IRouter } from \"./components/types.js\";\nimport { testPath } from \"./testPath.js\";\n\nfunction _matchRoutes(\n routeNode: IRoute,\n normalizedPath: string,\n segments: string[],\n results: IRouteMatchResult[]\n): void {\n const matchResult = testPath(routeNode, normalizedPath, segments);\n if (matchResult) {\n results.push(matchResult);\n }\n for(const childRoute of routeNode.routeChildNodes) {\n _matchRoutes(childRoute, normalizedPath, segments, results);\n }\n}\n\nexport function matchRoutes(routerNode: IRouter, normalizedPath: string): IRouteMatchResult | null {\n const topLevelRoutes = routerNode.routeChildNodes;\n const results: IRouteMatchResult[] = [];\n // セグメント配列を作成(先頭の/は除去せずにそのまま分割)\n // '/' => ['', ''] → filter → ['']\n // '/home' => ['', 'home'] → filter → ['home']\n // '/home/about' => ['', 'home', 'about'] → filter → ['home', 'about']\n // '' => ['']\n const rawSegments = normalizedPath.split('/');\n // 先頭の空セグメント(絶対パスの/)と末尾の空セグメント(/で終わるパス)を除去\n const segments = rawSegments.filter((s, i) => {\n if (i === 0 && s === '') return false; // 先頭の空セグメントをスキップ\n if (i === rawSegments.length - 1 && s === '' && rawSegments.length > 1) return false; // 末尾の空セグメントをスキップ\n return true;\n });\n for (const route of topLevelRoutes) {\n _matchRoutes(route, normalizedPath, segments, results);\n }\n results.sort((a, b) => {\n const lastRouteA = a.routes.at(-1)!;\n const lastRouteB = b.routes.at(-1)!;\n const diffSegmentCount = lastRouteA.absoluteSegmentCount - lastRouteB.absoluteSegmentCount;\n if (diffSegmentCount !== 0) {\n return -diffSegmentCount;\n }\n const diffWeight = lastRouteA.absoluteWeight - lastRouteB.absoluteWeight;\n if (diffWeight !== 0) {\n return -diffWeight;\n }\n const diffIndex = lastRouteA.childIndex - lastRouteB.childIndex;\n return diffIndex;\n });\n if (results.length > 0) {\n return results[0];\n }\n return null;\n}","import { builtinParamTypes } from \"./builtinParamTypes\";\nimport { IRoute, IRouteMatchResult } from \"./components/types\";\n\nexport function testPath(route: IRoute, path: string, segments: string[]): IRouteMatchResult | null {\n const params: Record<string, string> = {};\n const typedParams: Record<string, any> = {};\n let testResult = true;\n let catchAllFound = false;\n let i = 0, segIndex = 0;\n while (i < route.absoluteSegmentInfos.length) {\n const segmentInfo = route.absoluteSegmentInfos[i];\n // index属性のルートはセグメントを消費しないのでスキップ\n if (segmentInfo.isIndex) {\n i++;\n continue;\n }\n // 先頭の空セグメント(絶対パスの /)はsegmentsから除外されているのでスキップ\n if (i === 0 && segmentInfo.segmentText === '' && segmentInfo.type === 'static') {\n i++;\n continue;\n }\n const segment = segments[segIndex];\n if (segment === undefined) {\n // セグメントが足りない\n testResult = false;\n break;\n }\n let match: boolean = false;\n if (segmentInfo.type === \"param\") {\n const paramType = segmentInfo.paramType || 'any';\n const builtinParamType = builtinParamTypes[paramType];\n const value = builtinParamType.parse(segment);\n if (typeof value !== 'undefined') {\n if (segmentInfo.paramName) {\n params[segmentInfo.paramName] = segment;\n typedParams[segmentInfo.paramName] = value;\n }\n match = true;\n }\n } else {\n match = segmentInfo.pattern.exec(segment) !== null;\n }\n if (match) {\n if (segmentInfo.type === 'catch-all') {\n // Catch-all: match remaining segments\n const remainingSegments = segments.slice(segIndex).join('/');\n params['*'] = remainingSegments;\n typedParams['*'] = remainingSegments;\n catchAllFound = true;\n break; // No more segments to process\n }\n } else {\n testResult = false;\n break; \n }\n i++;\n segIndex++;\n }\n let finalResult = false;\n if (testResult) {\n if (catchAllFound) {\n // catch-all は残り全部マッチ済み\n finalResult = true;\n } else if (i === route.absoluteSegmentInfos.length && segIndex === segments.length) {\n // 全セグメントが消費された。\n // 末尾スラッシュ(例: /users/)は matchRoutes 側で処理済み: normalizePathname が\n // ルート以外の末尾スラッシュを除去し、matchRoutes の filter が末尾の空セグメントを\n // 落とすため、testPath に渡る segments に末尾 '' は含まれない。よってここで\n // 末尾スラッシュ用の分岐は不要(trailing-slash の結合テストは matchRoutes.test.ts 参照)。\n finalResult = true;\n }\n }\n \n if (finalResult) {\n return {\n path: path,\n routes: route.routes,\n params: params,\n typedParams: typedParams,\n lastPath: \"\"\n };\n }\n return null;\n}","import { IRoute } from \"./components/types\";\n\nexport function hideRoute(route: IRoute) {\n route.clearParams();\n for(const node of route.childNodeArray) {\n node.parentNode?.removeChild(node);\n }\n}\n","import { assignParams } from \"./assignParams\";\nimport { LayoutOutlet } from \"./components/LayoutOutlet\";\nimport { IRoute, IRouteMatchResult } from \"./components/types\";\nimport { config } from \"./config\";\n\nexport function showRoute(route: IRoute, matchResult: IRouteMatchResult): boolean {\n const params: Record<string, string> = {};\n const typedParams: Record<string, any> = {};\n for(const key of route.paramNames) {\n params[key] = matchResult.params[key];\n typedParams[key] = matchResult.typedParams[key];\n }\n route.setParams(params, typedParams);\n const parentNode = route.placeHolder.parentNode;\n const nextSibling = route.placeHolder.nextSibling;\n for (const node of route.childNodeArray) {\n // connectedCallbackが呼ばれる前に、プロパティにパラメータを割り当てる\n // connectedCallbackを実行するときにパラメータはすでに設定されている必要があるため\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n element.querySelectorAll('[data-bind]').forEach((e) => {\n assignParams(e, route.typedParams);\n });\n if (element.hasAttribute('data-bind')) {\n assignParams(element, route.typedParams);\n }\n element.querySelectorAll<LayoutOutlet>(config.tagNames.layoutOutlet).forEach((layoutOutlet) => {\n layoutOutlet.assignParams(route.typedParams);\n });\n if (element.tagName.toLowerCase() === config.tagNames.layoutOutlet) {\n (element as LayoutOutlet).assignParams(route.typedParams);\n }\n }\n if (nextSibling) {\n parentNode?.insertBefore(node, nextSibling);\n } else {\n parentNode?.appendChild(node);\n }\n }\n return true;\n}\n","import { IOutlet, IRouter } from \"./components/types\";\nimport { config } from \"./config\";\nimport { matchRoutes } from \"./matchRoutes\";\nimport { raiseError } from \"./raiseError\";\nimport { showRouteContent } from \"./showRouteContent\";\n\nexport async function applyRoute(\n routerNode: IRouter, \n outlet: IOutlet, \n fullPath: string,\n lastPath: string\n): Promise<void> {\n const basename = routerNode.basename;\n let sliced = fullPath;\n if (basename !== \"\") {\n if (fullPath === basename) {\n sliced = \"\";\n } else if (fullPath.startsWith(basename + \"/\")) {\n sliced = fullPath.slice(basename.length);\n }\n }\n // when fullPath === basename (e.g. \"/app\"), treat it as root \"/\"\n const path = sliced === \"\" ? \"/\" : sliced;\n\n let matchResult = matchRoutes(routerNode, path);\n if (!matchResult) {\n if (routerNode.fallbackRoute) {\n matchResult = {\n routes: [routerNode.fallbackRoute],\n params: {},\n typedParams: {},\n path: path,\n lastPath: lastPath\n };\n } else {\n raiseError(`${config.tagNames.router} No route matched for path: ${path}`);\n }\n }\n matchResult.lastPath = lastPath;\n const lastRoutes = outlet.lastRoutes;\n const committed = await showRouteContent(routerNode, matchResult, lastRoutes);\n // GuardCancel により中断された場合は state を更新しない\n // (拒否されたパスでの wcs-router:path-changed 発火を防ぐため)\n if (!committed) return;\n // if successful, update router and outlet state\n routerNode.path = path;\n outlet.lastRoutes = matchResult.routes;\n}\n","import { IRoute, IRouteMatchResult, IRouter } from \"./components/types\";\nimport { hideRoute } from \"./hideRoute\";\nimport { showRoute } from \"./showRoute\";\nimport { GuardCancel } from \"./GuardCancel\";\n\n/**\n * ルートコンテンツを表示する。\n *\n * @returns ガードチェックを通過してコンテンツ表示が成立した場合 true、\n * GuardCancel により中断(フォールバックへ再ナビゲート)した場合 false。\n * 呼び出し側(applyRoute)は false の場合、router.path / outlet.lastRoutes を\n * 更新しないことで「拒否されたパスでの path-changed 発火」を防ぐ。\n */\nexport async function showRouteContent(\n routerNode: IRouter,\n matchResult: IRouteMatchResult,\n lastRoutes: IRoute[],\n): Promise<boolean> {\n // Hide previous routes\n const routesSet = new Set<IRoute>(matchResult.routes);\n for (const route of lastRoutes) {\n if (!routesSet.has(route)) {\n hideRoute(route);\n }\n }\n try {\n for (const route of matchResult.routes) {\n await route.guardCheck(matchResult);\n }\n } catch (e) {\n if (e instanceof GuardCancel) {\n console.warn(`Navigation cancelled: ${e.message}. Redirecting to ${e.fallbackPath}`);\n queueMicrotask(() => {\n routerNode.navigate(e.fallbackPath).catch((err) => {\n console.error('Fallback navigation failed:', err);\n });\n });\n return false;\n } else {\n throw e;\n }\n }\n const lastRouteSet = new Set<IRoute>(lastRoutes);\n let force = false;\n for (const route of matchResult.routes) {\n if (!lastRouteSet.has(route) || route.shouldChange(matchResult.params) || force) {\n force = showRoute(route, matchResult);\n }\n }\n return true;\n}\n","/**\n * Navigation API の `navigate()` 戻り値(NavigationResult)。\n * - `committed`: URL がアドレスバーに反映された時点で resolve\n * - `finished`: 全 intercept handler 完了で resolve\n * Polyfill や mock 環境では戻り値が undefined のケースもあるため、\n * 戻り値全体を optional として扱う。\n */\nexport type NavigationResultLike = {\n committed?: Promise<unknown>;\n finished?: Promise<unknown>;\n};\n\nexport type NavigationLike = {\n navigate?: (url: string) => NavigationResultLike | void | undefined;\n addEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n removeEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n};\n\nexport function getNavigation(): NavigationLike | null {\n const nav = (window as any).navigation as NavigationLike | undefined;\n if (!nav) {\n return null;\n }\n if (typeof nav.addEventListener !== \"function\" || typeof nav.removeEventListener !== \"function\") {\n return null;\n }\n return nav;\n}\n","import { config } from \"./config.js\";\n\n// basenameFileExtensions ベースの正規表現をキャッシュ(config 変更時のみ再生成)。\nlet _cachedExtensions: ReadonlyArray<string> | null = null;\nlet _cachedExtPattern: RegExp | null = null;\n\n/**\n * config.basenameFileExtensions から拡張子削除用の正規表現を生成(キャッシュ付き)。\n * config 変更が検知された場合のみ再生成する。\n */\nexport function getExtPattern(): RegExp | null {\n const exts = config.basenameFileExtensions;\n if (exts.length === 0) return null;\n if (_cachedExtensions === exts && _cachedExtPattern) {\n return _cachedExtPattern;\n }\n _cachedExtensions = exts;\n _cachedExtPattern = new RegExp(\n `\\\\/[^/]+(?:${exts.map(e => e.replace(/\\./g, '\\\\.')).join('|')})$`,\n 'i'\n );\n return _cachedExtPattern;\n}\n\n/**\n * URL pathname を route path に正規化する。\n * - 先頭スラッシュを保証\n * - 連続スラッシュを単一化\n * - 末尾のファイル拡張子(例: .html)をディレクトリルートとして扱う\n * - ルート以外の末尾スラッシュを除去\n */\nexport function normalizePathname(path: string): string {\n let p = path || \"/\";\n if (!p.startsWith(\"/\")) p = \"/\" + p;\n p = p.replace(/\\/{2,}/g, \"/\");\n const extPattern = getExtPattern();\n if (extPattern) {\n p = p.replace(extPattern, \"\");\n }\n if (p === \"\") p = \"/\";\n if (p.length > 1 && p.endsWith(\"/\")) p = p.slice(0, -1);\n return p;\n}\n\n/**\n * basename を正規化する。\n * - \"\" or \"/\" -> \"\"\n * - \"/app/\" -> \"/app\"\n * - \"/app/index.html\" -> \"/app\"\n */\nexport function normalizeBasename(path: string): string {\n let p = path || \"\";\n if (!p) return \"\";\n if (!p.startsWith(\"/\")) p = \"/\" + p;\n p = p.replace(/\\/{2,}/g, \"/\");\n const extPattern = getExtPattern();\n if (extPattern) {\n p = p.replace(extPattern, \"\");\n }\n if (p.length > 1 && p.endsWith(\"/\")) p = p.slice(0, -1);\n if (p === \"/\") return \"\";\n return p;\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { parse } from \"../parse.js\";\nimport { createOutlet } from \"./Outlet.js\";\nimport { config } from \"../config.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IOutlet, IRoute, IRouter } from \"./types.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { applyRoute } from \"../applyRoute.js\";\nimport { getNavigation } from \"../Navigation.js\";\nimport { normalizeBasename, normalizePathname } from \"../normalizePathname.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\n\ninterface NavigateEventLike {\n canIntercept: boolean;\n hashChange: boolean;\n downloadRequest: string | null;\n destination: { url: string };\n intercept: (options: { handler: () => Promise<void> }) => void;\n}\n\n/**\n * AppRoutes - Root component for @wcstack/router\n *\n * Container element that manages route definitions and navigation.\n */\nexport class Router extends HTMLElement implements IRouter {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"navigateUrl\", event: \"wcs-router:navigate-url-changed\", semantics: \"state\" },\n { name: \"path\", event: \"wcs-router:path-changed\", semantics: \"state\" },\n ],\n // `navigateUrl` は observable output であると同時に settable な書き込み面でもある\n // (setter が navigate() を起動し、完了後に自分で null へ戻す)。properties にだけ\n // 宣言すると binding core は output-only とみなし、state → element の書き込みを\n // 抑止するため、state 経由のプログラム遷移が成立しなくなる。`path` は setter が\n // navigate せず内部値の反映だけなので、意図的に output のままにしている。\n inputs: [\n { name: \"basename\", attribute: \"basename\" },\n { name: \"navigateUrl\" },\n ],\n commands: [\n { name: \"navigate\", async: true },\n ],\n };\n\n private _outlet: IOutlet | null = null;\n private _template: HTMLTemplateElement | null = null;\n private _routeChildNodes: IRoute[] = [];\n private _basename: string = '';\n private _path: string = '';\n private _initialized: boolean = false;\n private _fallbackRoute: IRoute | null = null;\n private _listeningPopState: boolean = false;\n private _listeningNavigate: boolean = false;\n private _navigateUrl: string | null = null;\n private _disconnectedDuringInit: boolean = false;\n private _initializing: boolean = false;\n\n constructor() {\n super();\n }\n\n /**\n * Normalize a URL pathname to a route path.\n * 共通実装は normalizePathname.ts を参照(Link との挙動整合のため)。\n */\n private _normalizePathname(_path: string): string {\n return normalizePathname(_path);\n }\n\n /**\n * Normalize basename.\n * 共通実装は normalizePathname.ts を参照。\n */\n private _normalizeBasename(_path: string): string {\n return normalizeBasename(_path);\n }\n\n private _joinInternalPath(basename: string, to: string): string {\n const base = this._normalizeBasename(basename);\n // accept \"about\" as \"/about\"\n let path = to.startsWith(\"/\") ? to : \"/\" + to;\n path = this._normalizePathname(path);\n if (!base) return path;\n // keep \"/app/\" for root\n if (path === \"/\") return base + \"/\";\n return base + path;\n }\n\n private _notifyLocationChange(): void {\n // For environments without Navigation API (and for Link active-state updates)\n window.dispatchEvent(new CustomEvent(\"wcs:navigate\"));\n }\n\n private _getBasename(): string {\n const base = new URL(document.baseURI);\n let path = base.pathname || \"/\";\n if (path === \"/\") {\n return \"\";\n }\n return this._normalizeBasename(path);\n }\n\n get basename(): string {\n return this._basename;\n }\n\n private _getOutlet(): IOutlet {\n // 自身を起点に兄弟・子孫から Outlet を探す(マルチ Router 対応)\n const next = this.nextElementSibling;\n if (next && next.matches(config.tagNames.outlet)) {\n return next as unknown as IOutlet;\n }\n // なければ新規作成して自身の直後に挿入\n const outlet = createOutlet();\n if (this.parentNode) {\n this.parentNode.insertBefore(outlet, this.nextSibling);\n } else {\n document.body.appendChild(outlet);\n }\n return outlet;\n }\n\n private _getTemplate() {\n const template = this.querySelector(\"template\");\n return template;\n }\n \n get outlet(): IOutlet {\n if (!this._outlet) {\n raiseError(`${config.tagNames.router} has no outlet.`);\n }\n return this._outlet;\n }\n\n get template(): HTMLTemplateElement {\n if (!this._template) {\n raiseError(`${config.tagNames.router} has no template.`);\n }\n return this._template;\n }\n\n get routeChildNodes(): IRoute[] {\n return this._routeChildNodes;\n }\n\n get path(): string {\n return this._path;\n }\n /**\n * applyRoute 内で設定される値です。\n */\n set path(value: string) {\n const changed = this._path !== value;\n this._path = value;\n if (changed) {\n this.dispatchEvent(new CustomEvent(\"wcs-router:path-changed\", {\n detail: value,\n bubbles: true,\n }));\n }\n }\n\n get fallbackRoute(): IRoute | null {\n return this._fallbackRoute;\n }\n /**\n * Routeのfallback属性がある場合にそのルートを設定します。\n */\n set fallbackRoute(value: IRoute | null) {\n this._fallbackRoute = value;\n }\n\n get navigateUrl(): string | null {\n return this._navigateUrl;\n }\n\n set navigateUrl(value: string | null) {\n if (value === null || value === undefined || value === \"\") return;\n // 既に同一 URL の navigate 中なら再起動しない\n if (this._navigateUrl === value) return;\n this._navigateUrl = value;\n this.navigate(value).catch((err) => {\n console.error(`${config.tagNames.router} navigate failed:`, err);\n }).finally(() => {\n this._navigateUrl = null;\n this.dispatchEvent(new CustomEvent(\"wcs-router:navigate-url-changed\", {\n detail: null,\n bubbles: true,\n }));\n });\n }\n\n async navigate(path: string): Promise<void> {\n const fullPath = this._joinInternalPath(this._basename, path);\n const navigation = getNavigation();\n if (navigation?.navigate) {\n // Navigation API は { committed, finished } を返す。\n // finished を await することで、navigate() の Promise が\n // 実際のナビゲーション完了まで pending となり、_navigateUrl の\n // 二重 navigate ガード (setter 内 `if (this._navigateUrl === value)`) が\n // 適切な時間ウィンドウで機能するようになる。\n // Polyfill や mock 環境で undefined / 戻り値なしのケースもあるため optional chaining。\n await navigation.navigate(fullPath)?.finished;\n } else {\n history.pushState(null, '', fullPath);\n await applyRoute(this, this.outlet, fullPath, this._path);\n this._notifyLocationChange();\n }\n }\n\n /**\n * basename 配下の URL かどうかを判定する。\n * basename が空の場合はすべての URL にマッチする。\n */\n private _isOwnPath(fullPath: string): boolean {\n if (this._basename === \"\") return true;\n return fullPath === this._basename || fullPath.startsWith(this._basename + \"/\");\n }\n\n private _onNavigateFunc(navEvent: NavigateEventLike) {\n if (\n !navEvent.canIntercept ||\n navEvent.hashChange ||\n navEvent.downloadRequest !== null\n ) {\n return;\n }\n const url = new URL(navEvent.destination.url);\n const fullPath = this._normalizePathname(url.pathname);\n // basename 配下でない URL は無視(マルチ Router 対応)\n if (!this._isOwnPath(fullPath)) return;\n const routesNode = this;\n navEvent.intercept({\n handler: async () => {\n try {\n await applyRoute(routesNode, routesNode.outlet, fullPath, routesNode.path);\n } catch (err) {\n console.error(`${config.tagNames.router} applyRoute failed:`, err);\n throw err;\n }\n },\n });\n }\n\n private _onNavigate = this._onNavigateFunc.bind(this) as unknown as EventListener;\n\n private _onPopState = async () => {\n // back/forward for environments without Navigation API\n const fullPath = this._normalizePathname(window.location.pathname);\n // basename 配下でない URL は無視(マルチ Router 対応)\n if (!this._isOwnPath(fullPath)) return;\n await applyRoute(this, this.outlet, fullPath, this._path);\n this._notifyLocationChange();\n };\n\n private async _initialize(): Promise<void> {\n this._initializing = true;\n try {\n this._basename = this._normalizeBasename(\n this.getAttribute(\"basename\") || this._getBasename() || \"\"\n );\n const hasBaseTag = document.querySelector('base[href]') !== null;\n const url = new URL(window.location.href);\n if (this._basename === \"\" && !hasBaseTag && url.pathname !== \"/\") {\n raiseError(`${config.tagNames.router} basename is empty, but current path is not \"/\".`);\n }\n\n this._outlet = this._getOutlet();\n this._outlet.routesNode = this;\n this._template = this._getTemplate();\n if (!this._template) {\n raiseError(`${config.tagNames.router} should have a <template> child element.`);\n }\n const fragment = await parse(this);\n this._outlet.rootNode.appendChild(fragment);\n if (this.routeChildNodes.length === 0) {\n raiseError(`${config.tagNames.router} has no route definitions.`);\n }\n\n const fullPath = this._normalizePathname(window.location.pathname);\n await applyRoute(this, this.outlet, fullPath, this._path);\n this._notifyLocationChange();\n this._initialized = true;\n } finally {\n this._initializing = false;\n }\n }\n\n async connectedCallback() {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)。\n // await より前に同期で行い、初期化が古い値を読まないようにする。\n upgradeProperties(this);\n if (!this._initialized) {\n this._disconnectedDuringInit = false;\n await this._initialize();\n // 初期化中に disconnectedCallback が呼ばれた場合はイベントリスナを登録しない\n if (this._disconnectedDuringInit) {\n return;\n }\n }\n const navigation = getNavigation();\n if (navigation && !this._listeningNavigate) {\n navigation.addEventListener(\"navigate\", this._onNavigate);\n this._listeningNavigate = true;\n }\n // Fallback for browsers without Navigation API\n if (!navigation && !this._listeningPopState) {\n window.addEventListener(\"popstate\", this._onPopState);\n this._listeningPopState = true;\n }\n }\n\n disconnectedCallback() {\n // _initialize 中(await 中)に呼ばれた場合はフラグを立ててリスナ登録をスキップさせる\n if (this._initializing) {\n this._disconnectedDuringInit = true;\n }\n if (this._listeningNavigate) {\n getNavigation()?.removeEventListener(\"navigate\", this._onNavigate);\n this._listeningNavigate = false;\n }\n if (this._listeningPopState) {\n window.removeEventListener(\"popstate\", this._onPopState);\n this._listeningPopState = false;\n }\n }\n}\n","import { config } from \"../config\";\nimport { getUUID } from \"../getUUID\";\nimport { raiseError } from \"../raiseError\";\nimport { getNavigation } from \"../Navigation\";\nimport { normalizeBasename, normalizePathname } from \"../normalizePathname\";\nimport { ILink } from \"./types\";\nimport type { Router } from \"./Router\";\n\nexport class Link extends HTMLElement implements ILink {\n static get observedAttributes(): string[] {\n return ['to'];\n }\n\n private _childNodeArray: Node[] = [];\n private _uuid: string = getUUID();\n private _path: string = \"\";\n private _router: Router | null = null;\n private _anchorElement: HTMLAnchorElement | null = null;\n private _initialized: boolean = false;\n private _onClick?: (e: MouseEvent) => void;\n\n constructor() {\n super();\n }\n\n get uuid(): string {\n return this._uuid;\n }\n \n /**\n * 最寄りの Router を返す。\n *\n * 注意: この getter は DOM 走査で Router を探すため、\n * Router がまだ upgrade されていない場合は HTMLElement として返る可能性がある。\n * 通常は registerComponents() で Router を Link より先に upgrade することを推奨する。\n */\n get router(): Router {\n if (this._router) {\n return this._router;\n }\n // DOM 祖先走査で最寄りの Router を探す(マルチ Router 対応)\n const ancestor = this.closest<Router>(config.tagNames.router);\n if (ancestor) {\n return (this._router = ancestor);\n }\n // 祖先にない場合は ownerDocument 内の Router を探す\n const root = this.getRootNode() as Document | ShadowRoot;\n const found = root.querySelector?.<Router>(config.tagNames.router);\n if (found) {\n return (this._router = found);\n }\n raiseError(`${config.tagNames.link} is not connected to a router.`);\n }\n\n private _initialize() {\n this.style.display = \"none\";\n this._childNodeArray = Array.from(this.childNodes);\n this._path = this.getAttribute('to') || '';\n this._initialized = true;\n }\n\n /**\n * URL pathname を正規化する。Router と共通実装を使うことで\n * basenameFileExtensions の取り扱いを揃え、active 判定の取りこぼしを防ぐ。\n */\n private _normalizePathname(path: string): string {\n return normalizePathname(path);\n }\n\n private _joinInternalPath(basename: string, to: string): string {\n // Router._joinInternalPath と挙動を揃える\n const base = normalizeBasename(basename);\n const internal = to.startsWith(\"/\") ? to : \"/\" + to;\n const path = this._normalizePathname(internal);\n if (!base) return path;\n if (path === \"/\") return base + \"/\";\n return base + path;\n }\n\n private _setAnchorHref(anchor: HTMLAnchorElement,path: string) {\n if (path.startsWith('/')) {\n anchor.href = this._joinInternalPath(this.router.basename, path);\n } else {\n try {\n anchor.href = new URL(path).toString();\n } catch {\n raiseError(`[${config.tagNames.link}] Invalid URL in 'to' attribute: ${path}`);\n }\n }\n }\n\n connectedCallback() {\n if (!this._initialized) {\n this._initialize();\n }\n const parentNode = this.parentNode;\n if (!parentNode) {\n // should not happen if connected\n return; \n }\n const nextSibling = this.nextSibling;\n const link = document.createElement('a');\n this._setAnchorHref(link, this._path);\n for(const childNode of this._childNodeArray) {\n link.appendChild(childNode);\n }\n if (nextSibling) {\n parentNode.insertBefore(link, nextSibling);\n } else {\n parentNode.appendChild(link);\n }\n this._anchorElement = link;\n\n // ロケーション変更を監視\n getNavigation()?.addEventListener('currententrychange', this._updateActiveState);\n window.addEventListener('wcs:navigate', this._updateActiveState as EventListener);\n window.addEventListener('popstate', this._updateActiveState as EventListener);\n\n // Navigation API が無い場合は、クリックで router.navigate にフォールバック\n if (this._path.startsWith('/') && !getNavigation()?.navigate) {\n this._onClick = async (e: MouseEvent) => {\n // only left-click without modifiers\n if (e.defaultPrevented) return;\n if (e.button !== 0) return;\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n // 動的に外部URLに変わった場合はブラウザのデフォルト挙動に委ねる\n if (!this._path.startsWith('/')) return;\n e.preventDefault();\n await this.router.navigate(this._path);\n this._updateActiveState();\n };\n link.addEventListener('click', this._onClick);\n }\n this._updateActiveState(); \n }\n\n disconnectedCallback() {\n getNavigation()?.removeEventListener('currententrychange', this._updateActiveState);\n window.removeEventListener('wcs:navigate', this._updateActiveState as EventListener);\n window.removeEventListener('popstate', this._updateActiveState as EventListener);\n const anchor = this._anchorElement;\n if (anchor) {\n if (this._onClick) {\n anchor.removeEventListener('click', this._onClick);\n this._onClick = undefined;\n }\n anchor.remove();\n this._anchorElement = null;\n }\n // anchor 配下のままだった子要素のみ取り除く(別の親に移動されていた場合に誤って strip しないため)\n for(const childNode of this._childNodeArray) {\n if (anchor && childNode.parentNode === anchor) {\n anchor.removeChild(childNode);\n }\n }\n // Router キャッシュをクリア。別の Router 配下に動的に移動された場合や\n // Router 自体が入れ替わった場合に古い参照を返さないようにする。\n this._router = null;\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (name === 'to' && oldValue !== newValue) {\n this._path = newValue || '';\n if (this._anchorElement) {\n this._setAnchorHref(this._anchorElement, this._path);\n this._updateActiveState();\n }\n }\n }\n\n private _updateActiveState = () => {\n const currentPath = this._normalizePathname(new URL(window.location.href).pathname);\n const linkPath = this._normalizePathname(\n this._path.startsWith('/') ? this._joinInternalPath(this.router.basename, this._path) : this._path\n );\n \n if (this._anchorElement) {\n if (currentPath === linkPath) {\n this._anchorElement.classList.add('active');\n } else {\n this._anchorElement.classList.remove('active');\n }\n }\n };\n\n get anchorElement(): HTMLAnchorElement | null {\n return this._anchorElement;\n }\n}","import { raiseError } from \"../raiseError\";\n\n/**\n * グローバルHeadスタック\n * 最後に接続されたHeadが優先される\n */\nconst headStack: Head[] = [];\n\n/**\n * 初期の<head>内容を記憶(最初のHead接続時に保存)\n *\n * 設計仕様: `initialHeadCaptured` は最初の Head 接続時に一度だけ true になる。\n * SPA ライフタイム中の初期 head 状態は、最初の Head が接続された瞬間がベースラインで、\n * それ以降に追加された <head> 要素は「初期値」ではなく「現在の値」として扱う。\n * テストや SPA リセットで初期値を再キャプチャしたい場合は `_resetHeadStack()` を呼ぶ。\n */\nconst initialHeadValues: Map<string, Element | null> = new Map();\nlet initialHeadCaptured = false;\n\n/**\n * 要素ごとの `_getKey` 結果のキャッシュ。\n * 初期化時/キャプチャ時に算出し、以降の `_reapplyHead` ループで再計算しないようにする。\n * 要素の属性変更には追随しない(Head 内要素は初期化時に固定される前提)。\n */\nconst keyCache: WeakMap<Element, string> = new WeakMap();\n\nexport class Head extends HTMLElement {\n private _initialized: boolean = false;\n private _childElementArray: Element[] = [];\n\n constructor() {\n super();\n this.style.display = 'none';\n }\n\n private _initialize(): void {\n if (this._initialized) {\n return;\n }\n this._initialized = true;\n this._childElementArray = Array.from(this.children);\n for (const child of this._childElementArray) {\n this.removeChild(child);\n }\n }\n\n connectedCallback(): void {\n this._initialize();\n \n // 初回のみ初期状態を保存\n if (!initialHeadCaptured) {\n this._captureInitialHead();\n initialHeadCaptured = true;\n }\n \n // スタックに追加\n headStack.push(this);\n \n // headを再適用\n this._reapplyHead();\n }\n\n disconnectedCallback(): void {\n // スタックから削除\n const index = headStack.indexOf(this);\n if (index !== -1) {\n headStack.splice(index, 1);\n }\n \n // headを再適用(スタックが空なら初期状態に戻す)\n this._reapplyHead();\n }\n\n get childElementArray(): Element[] {\n if (!this._initialized) {\n raiseError('Head component is not initialized yet.');\n }\n return this._childElementArray;\n }\n\n /**\n * 要素の一意キーを生成(WeakMap でキャッシュ)\n */\n private _getKey(el: Element): string {\n const cached = keyCache.get(el);\n if (cached !== undefined) {\n return cached;\n }\n const key = this._computeKey(el);\n keyCache.set(el, key);\n return key;\n }\n\n /**\n * 要素の一意キーを計算(実体)\n */\n private _computeKey(el: Element): string {\n const tag = el.tagName.toLowerCase();\n\n if (tag === 'title') {\n return 'title';\n }\n\n if (tag === 'meta') {\n const name = el.getAttribute('name') || '';\n const property = el.getAttribute('property') || '';\n const httpEquiv = el.getAttribute('http-equiv') || '';\n const charset = el.hasAttribute('charset') ? 'charset' : '';\n const media = el.getAttribute('media') || '';\n return `meta:${name}:${property}:${httpEquiv}:${charset}:${media}`;\n }\n\n if (tag === 'link') {\n const rel = el.getAttribute('rel') || '';\n const href = el.getAttribute('href') || '';\n const media = el.getAttribute('media') || '';\n return `link:${rel}:${href}:${media}`;\n }\n\n if (tag === 'base') {\n return 'base';\n }\n\n if (tag === 'script') {\n const src = el.getAttribute('src') || '';\n const id = el.getAttribute('id') || '';\n const type = el.getAttribute('type') || '';\n if (src || id) {\n return `script:${src}:${id}:${type}`;\n }\n // インライン script はおおまかな先頭で識別(同等性は完全一致でなく簡易判定)\n return `script::${type}:${el.outerHTML.slice(0, 100)}`;\n }\n\n if (tag === 'style') {\n const id = el.getAttribute('id') || '';\n const media = el.getAttribute('media') || '';\n if (id) {\n return `style:${id}:${media}`;\n }\n // インライン style はおおまかな先頭で識別(同等性は完全一致でなく簡易判定)\n return `style::${media}:${el.outerHTML.slice(0, 100)}`;\n }\n\n // その他要素はおおまかに識別(同等性は完全一致でなく簡易判定)\n return `${tag}:${el.outerHTML.slice(0, 100)}`;\n }\n\n /**\n * head 内の要素を key で引ける Map を構築する。\n * `_reapplyHead` のループ前に一度だけ呼び出し、O(N) lookup に置き換えるためのヘルパ。\n *\n * 設計仕様: 同一 key の要素が複数 `document.head` 内に存在する場合は **first-wins**\n * (DOM 順で最初の要素のみ採用)。これは `_captureInitialHead` および\n * `initialHeadValues` の挙動とも整合する。\n * 重複は基本的にユーザーの記述ミスだが、_getKey の粒度(href/name 等の主要属性のみ)に\n * よる「論理的重複」もあり得るため、サイレントに first-wins とする。\n * 厳密な重複検出が必要な場合は呼び出し側で行う。\n */\n private _buildHeadElementMap(): Map<string, Element> {\n const map = new Map<string, Element>();\n for (const el of Array.from(document.head.children)) {\n const key = this._getKey(el);\n if (!map.has(key)) {\n map.set(key, el);\n }\n }\n return map;\n }\n\n /**\n * 初期の<head>状態をキャプチャ\n * document.head内の全ての要素をスキャンして保存する\n */\n private _captureInitialHead(): void {\n const head = document.head;\n for (const child of Array.from(head.children)) {\n const key = this._getKey(child);\n if (!initialHeadValues.has(key)) {\n initialHeadValues.set(key, child.cloneNode(true) as Element);\n }\n }\n }\n\n /**\n * スタック全体からheadを再構築\n * 後のHeadが優先される(上書き)\n */\n private _reapplyHead(): void {\n // 全スタックのHeadが扱うキーを収集\n const allKeys = new Set<string>();\n for (const head of headStack) {\n for (const child of head._childElementArray) {\n allKeys.add(this._getKey(child));\n }\n }\n // 初期値にあるキーも追加\n for (const key of initialHeadValues.keys()) {\n allKeys.add(key);\n }\n\n // 現在のheadにある要素のキーも追加(管理下から外れたものを削除するため)\n // 同時に key -> Element の lookup map も構築する(O(N²) を避けるため)\n const headElementMap = this._buildHeadElementMap();\n for (const key of headElementMap.keys()) {\n allKeys.add(key);\n }\n\n // 各キーについて、最も優先度の高い値を決定\n for (const key of allKeys) {\n // スタックを逆順に見て、最初に見つかった値を使用\n let targetElement: Element | null = null;\n for (let i = headStack.length - 1; i >= 0; i--) {\n const head = headStack[i];\n for (const child of head._childElementArray) {\n if (this._getKey(child) === key) {\n targetElement = child.cloneNode(true) as Element;\n break;\n }\n }\n if (targetElement) break;\n }\n\n // スタックに該当がなければ初期値を使用\n if (!targetElement && initialHeadValues.has(key)) {\n const initial = initialHeadValues.get(key);\n // initialHeadValuesにはnullを保存しないため、has(key)がtrueならinitialは必ず存在しElementである\n targetElement = (initial as Element).cloneNode(true) as Element;\n }\n\n // headを更新\n const current = headElementMap.get(key) ?? null;\n if (targetElement) {\n if (current) {\n current.replaceWith(targetElement);\n } else {\n document.head.appendChild(targetElement);\n }\n // map を新しい要素に更新(後続の同 key 処理に備える)\n headElementMap.set(key, targetElement);\n } else {\n // 初期値もスタックにもない場合は削除\n current?.remove();\n headElementMap.delete(key);\n }\n }\n }\n}\n\n// テスト用にスタックをリセットする関数\nexport function _resetHeadStack(): void {\n headStack.length = 0;\n initialHeadValues.clear();\n initialHeadCaptured = false;\n}\n","import { Route } from './components/Route';\nimport { Layout } from './components/Layout';\nimport { Outlet } from './components/Outlet';\nimport { Router } from './components/Router';\nimport { LayoutOutlet } from './components/LayoutOutlet';\nimport { Link } from './components/Link';\nimport { Head } from './components/Head';\nimport { config } from './config';\n\nexport function registerComponents() {\n // Register custom element\n if (!customElements.get(config.tagNames.layout)) {\n customElements.define(config.tagNames.layout, Layout);\n }\n if (!customElements.get(config.tagNames.layoutOutlet)) {\n customElements.define(config.tagNames.layoutOutlet, LayoutOutlet);\n }\n if (!customElements.get(config.tagNames.outlet)) {\n customElements.define(config.tagNames.outlet, Outlet);\n }\n if (!customElements.get(config.tagNames.route)) {\n customElements.define(config.tagNames.route, Route);\n }\n if (!customElements.get(config.tagNames.router)) {\n customElements.define(config.tagNames.router, Router);\n }\n if (!customElements.get(config.tagNames.link)) {\n customElements.define(config.tagNames.link, Link);\n }\n if (!customElements.get(config.tagNames.head)) {\n customElements.define(config.tagNames.head, Head);\n }\n}","import { IWritableConfig } from \"./types\";\nimport { setConfig } from \"./config\";\nimport { registerComponents } from \"./registerComponents\";\n\n/**\n * Initialize the router with optional configuration.\n * This is the main entry point for setting up the router.\n * @param config - Optional partial configuration to override defaults\n */\nexport function bootstrapRouter(config?: Partial<IWritableConfig>): void {\n if (config) {\n setConfig(config);\n }\n registerComponents();\n}\n","import pkg from \"../package.json\" with { type: \"json\" };\nexport const VERSION = pkg.version;\n"],"names":["_config","tagNames","route","router","outlet","layout","layoutOutlet","link","head","guardHandler","enableShadowRoot","basenameFileExtensions","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","getUUID","crypto","randomUUID","replace","c","r","Math","random","toString","raiseError","message","options","Error","cause","GuardCancel","fallbackPath","constructor","super","this","builtinParamTypes","int","typeName","pattern","parse","value","test","parseInt","float","parseFloat","bool","uuid","slug","isoDate","year","month","day","split","map","Number","date","Date","getFullYear","getMonth","getDate","any","weights","static","param","RouteCore","EventTarget","protocol","version","properties","name","event","semantics","getter","e","detail","typedParams","_target","_parentCore","_path","_name","_isFallbackRoute","_segmentInfos","_absoluteSegmentInfos","_paramNames","_absoluteParamNames","_weight","_absoluteWeight","_segmentCount","_params","_typedParams","_active","_hasGuard","_guardHandler","_guardFallbackPath","_waitForSetGuardHandler","_resolveSetGuardHandler","_guardHandlerLoadFailed","target","parentCore","path","isFallbackRoute","isRelative","startsWith","segmentInfos","_checkParentCore","hasParentCallback","noParentCallback","absolutePath","parentPath","endsWith","absoluteSegmentInfos","params","active","paramNames","names","info","paramName","push","absoluteParamNames","weight","type","absoluteWeight","segmentCount","count","absoluteSegmentCount","parsePath","undefined","isFallback","isIndex","segmentText","segments","idx","length","segment","RegExp","matchType","match","includes","substring","paramType","hasGuard","guardFallback","Promise","resolve","setParams","wasActive","dispatchEvent","CustomEvent","bubbles","clearParams","shouldChange","newParams","notifyGuardHandlerLoadFailed","guardCheck","matchResult","toPath","fromPath","lastPath","Route","HTMLElement","wcBindable","_core","_routeParentNode","_routeChildNodes","_routerNode","_uuid","_placeHolder","document","createComment","_childNodeArray","_childIndex","_initialized","_routes","routeParentNode","routeChildNodes","routerNode","placeHolder","childNodeArray","Array","from","childNodes","routes","concat","childIndex","fullpath","testAncestorNode","ancestorNode","currentNode","initialize","hasAttribute","getAttribute","routeChildContainer","fallbackRoute","setAttribute","cache","Map","Layout","_loadTemplateFromSource","source","response","fetch","ok","status","templateContent","text","set","error","_loadTemplateFromDocument","id","element","getElementById","HTMLTemplateElement","innerHTML","loadTemplate","layoutId","console","warn","template","createElement","has","get","Outlet","_routesNode","_lastRoutes","routesNode","rootNode","shadowRoot","lastRoutes","_resolveEnableShadowRoot","_initialize","attachShadow","mode","connectedCallback","disconnectedCallback","bindTypeSet","Set","_assignParams","bindType","entries","props","states","removeAttribute","String","assignParams","tagName","bindTypeText","customTagName","toLowerCase","isAttr","getCustomTagName","customElements","whenDefined","then","isConnected","catch","LayoutOutlet","_layout","_initializing","_disconnectedDuringInit","_layoutChildNodes","appendChild","content","cloneNode","childNode","fragmentForTemplate","slotElementBySlotName","querySelectorAll","forEach","slotElement","slotName","fragmentBySlotName","fragmentForChildNodes","createDocumentFragment","Element","fragment","replaceWith","defaultSlot","createLayoutOutlet","loadGuardHandler","script","async","scriptModule","firstError","routeTag","sourceComment","scriptText","URL","createObjectURL","blob","Blob","url","import","revokeObjectURL","b64","btoa","fromCodePoint","TextEncoder","encode","default","importModule","handler","err","_duplicateCheck","routesByPath","existingRoute","_parseNode","node","nodeType","Node","ELEMENT_NODE","appendNode","childFragment","cloneElement","importNode","upgrade","querySelector","children","_matchRoutes","routeNode","normalizedPath","results","testResult","catchAllFound","i","segIndex","segmentInfo","exec","remainingSegments","slice","join","finalResult","testPath","childRoute","hideRoute","parentNode","removeChild","showRoute","nextSibling","insertBefore","applyRoute","fullPath","basename","sliced","topLevelRoutes","rawSegments","filter","s","sort","a","b","lastRouteA","at","lastRouteB","diffSegmentCount","diffWeight","matchRoutes","committed","routesSet","queueMicrotask","navigate","lastRouteSet","force","showRouteContent","getNavigation","nav","window","navigation","addEventListener","removeEventListener","_cachedExtensions","_cachedExtPattern","getExtPattern","exts","normalizePathname","p","extPattern","normalizeBasename","hasAccessorOnPrototype","proto","getPrototypeOf","descriptor","getOwnPropertyDescriptor","Router","inputs","attribute","commands","_outlet","_template","_basename","_fallbackRoute","_listeningPopState","_listeningNavigate","_navigateUrl","_normalizePathname","_normalizeBasename","_joinInternalPath","to","base","_notifyLocationChange","_getBasename","baseURI","pathname","_getOutlet","next","nextElementSibling","matches","body","_getTemplate","changed","navigateUrl","finally","finished","history","pushState","_isOwnPath","_onNavigateFunc","navEvent","canIntercept","hashChange","downloadRequest","destination","intercept","_onNavigate","bind","_onPopState","location","hasBaseTag","href","declaration","input","prototype","hasOwnProperty","call","record","upgradeProperties","Link","observedAttributes","_router","_anchorElement","_onClick","ancestor","closest","root","getRootNode","found","style","display","internal","_setAnchorHref","anchor","_updateActiveState","defaultPrevented","button","metaKey","ctrlKey","shiftKey","altKey","preventDefault","remove","attributeChangedCallback","oldValue","newValue","currentPath","linkPath","classList","add","anchorElement","headStack","initialHeadValues","initialHeadCaptured","keyCache","WeakMap","Head","_childElementArray","child","_captureInitialHead","_reapplyHead","index","indexOf","splice","childElementArray","_getKey","el","cached","_computeKey","tag","src","outerHTML","media","_buildHeadElementMap","allKeys","headElementMap","targetElement","current","delete","registerComponents","define","bootstrapRouter","partialConfig","assign","isArray","VERSION"],"mappings":"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"}
|