@real-router/core 0.80.0 → 0.82.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/README.md +68 -55
- package/dist/cjs/Router-CCmcEi-S.js +2 -0
- package/dist/cjs/Router-CCmcEi-S.js.map +1 -0
- package/dist/cjs/Router.d.ts +7 -6
- package/dist/cjs/Router.d.ts.map +1 -1
- package/dist/cjs/Router.js +1 -1
- package/dist/cjs/Router.js.map +1 -1
- package/dist/cjs/api/getPluginApi.d.ts.map +1 -1
- package/dist/cjs/api/getPluginApi.js +1 -1
- package/dist/cjs/api/getPluginApi.js.map +1 -1
- package/dist/cjs/api/getRoutesApi.d.ts.map +1 -1
- package/dist/cjs/api/getRoutesApi.js +1 -1
- package/dist/cjs/api/getRoutesApi.js.map +1 -1
- package/dist/cjs/api.js +2 -1
- package/dist/cjs/api.js.map +1 -1
- package/dist/cjs/buildParamMeta-0m11OIJS.js +2 -0
- package/dist/cjs/buildParamMeta-0m11OIJS.js.map +1 -0
- package/dist/cjs/channels/defaults.js +2 -0
- package/dist/cjs/channels/defaults.js.map +1 -0
- package/dist/cjs/channels/guard.js +2 -0
- package/dist/cjs/channels/guard.js.map +1 -0
- package/dist/cjs/channels/modeGate.js +2 -0
- package/dist/cjs/channels/modeGate.js.map +1 -0
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +1 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/createRouter.d.ts +1 -1
- package/dist/cjs/createRouter.d.ts.map +1 -1
- package/dist/cjs/createRouter.js.map +1 -1
- package/dist/cjs/engine/builder/buildTree.js +1 -1
- package/dist/cjs/engine/builder/buildTree.js.map +1 -1
- package/dist/cjs/engine/path-matcher/SegmentMatcher.d.ts +14 -1
- package/dist/cjs/engine/path-matcher/SegmentMatcher.d.ts.map +1 -1
- package/dist/cjs/engine/path-matcher/SegmentMatcher.js +1 -1
- package/dist/cjs/engine/path-matcher/SegmentMatcher.js.map +1 -1
- package/dist/cjs/engine/path-matcher/registration/buildParts.js +1 -1
- package/dist/cjs/engine/path-matcher/registration/buildParts.js.map +1 -1
- package/dist/cjs/engine/path-matcher/registration/context.js +1 -1
- package/dist/cjs/engine/path-matcher/registration/context.js.map +1 -1
- package/dist/cjs/engine/path-matcher/registration/errors.js +1 -1
- package/dist/cjs/engine/path-matcher/registration/errors.js.map +1 -1
- package/dist/cjs/engine/path-matcher/registration/index.js +1 -1
- package/dist/cjs/engine/path-matcher/registration/index.js.map +1 -1
- package/dist/cjs/engine/path-matcher/registration/trieNodes.js.map +1 -1
- package/dist/cjs/engine/path-matcher/types.d.ts +3 -0
- package/dist/cjs/engine/path-matcher/types.d.ts.map +1 -1
- package/dist/cjs/engine/search-params/strategies/number.js +1 -1
- package/dist/cjs/engine/search-params/strategies/number.js.map +1 -1
- package/dist/cjs/engine/validation/routes.js +1 -1
- package/dist/cjs/engine/validation/routes.js.map +1 -1
- package/dist/cjs/helpers.js +1 -1
- package/dist/cjs/helpers.js.map +1 -1
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internals.d.ts +30 -8
- package/dist/cjs/internals.d.ts.map +1 -1
- package/dist/cjs/internals.js +1 -1
- package/dist/cjs/internals.js.map +1 -1
- package/dist/cjs/limits.js +2 -0
- package/dist/cjs/limits.js.map +1 -0
- package/dist/cjs/namespaces/EventBusNamespace/EventBusNamespace.js.map +1 -1
- package/dist/cjs/namespaces/NavigationNamespace/NavigationNamespace.js +1 -1
- package/dist/cjs/namespaces/NavigationNamespace/NavigationNamespace.js.map +1 -1
- package/dist/cjs/namespaces/OptionsNamespace/OptionsNamespace.js.map +1 -1
- package/dist/cjs/namespaces/OptionsNamespace/constants.js +1 -1
- package/dist/cjs/namespaces/OptionsNamespace/constants.js.map +1 -1
- package/dist/cjs/namespaces/OptionsNamespace/helpers.js.map +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/RoutesNamespace.js +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/RoutesNamespace.js.map +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/helpers.js +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/helpers.js.map +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/routesStore.d.ts +8 -0
- package/dist/cjs/namespaces/RoutesNamespace/routesStore.d.ts.map +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/routesStore.js +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/routesStore.js.map +1 -1
- package/dist/cjs/namespaces/RoutesNamespace/types.d.ts +24 -7
- package/dist/cjs/namespaces/RoutesNamespace/types.d.ts.map +1 -1
- package/dist/cjs/namespaces/StateNamespace/StateNamespace.js +1 -1
- package/dist/cjs/namespaces/StateNamespace/StateNamespace.js.map +1 -1
- package/dist/cjs/pipeline/buildURL.js +2 -0
- package/dist/cjs/pipeline/buildURL.js.map +1 -0
- package/dist/cjs/pipeline/canonicalize.js +2 -0
- package/dist/cjs/pipeline/canonicalize.js.map +1 -0
- package/dist/cjs/pipeline/materialize.js +2 -0
- package/dist/cjs/pipeline/materialize.js.map +1 -0
- package/dist/cjs/pipeline/port.d.ts +147 -0
- package/dist/cjs/pipeline/port.d.ts.map +1 -0
- package/dist/cjs/routerFSM.js +1 -1
- package/dist/cjs/routerFSM.js.map +1 -1
- package/dist/cjs/transitionPath.js +1 -1
- package/dist/cjs/transitionPath.js.map +1 -1
- package/dist/cjs/types/RouterValidator.d.ts +14 -0
- package/dist/cjs/types/RouterValidator.d.ts.map +1 -1
- package/dist/cjs/types/api.d.ts +20 -11
- package/dist/cjs/types/api.d.ts.map +1 -1
- package/dist/cjs/types/base.d.ts +63 -4
- package/dist/cjs/types/base.d.ts.map +1 -1
- package/dist/cjs/types/constants.d.ts +1 -0
- package/dist/cjs/types/constants.d.ts.map +1 -1
- package/dist/cjs/types/router.d.ts +112 -23
- package/dist/cjs/types/router.d.ts.map +1 -1
- package/dist/cjs/types/tree-changed.d.ts +1 -1
- package/dist/cjs/types/tree-changed.d.ts.map +1 -1
- package/dist/cjs/types.d.ts +20 -11
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/utils/event-emitter/EventEmitter.js.map +1 -0
- package/dist/cjs/utils/fsm/fsm.js.map +1 -0
- package/dist/cjs/utils/logger/RouterLogger.js.map +1 -0
- package/dist/cjs/utils/logger/constants.js.map +1 -0
- package/dist/cjs/validation.js +2 -1
- package/dist/cjs/validation.js.map +1 -1
- package/dist/cjs/wiring/wireNamespaces.js +1 -1
- package/dist/cjs/wiring/wireNamespaces.js.map +1 -1
- package/dist/esm/Router-DEpNuwBW.mjs +2 -0
- package/dist/esm/Router-DEpNuwBW.mjs.map +1 -0
- package/dist/esm/Router.d.mts +7 -6
- package/dist/esm/Router.d.mts.map +1 -1
- package/dist/esm/api/getPluginApi.d.mts.map +1 -1
- package/dist/esm/api/getRoutesApi.d.mts.map +1 -1
- package/dist/esm/api.mjs +1 -1
- package/dist/esm/api.mjs.map +1 -1
- package/dist/esm/buildParamMeta-D8td47fL.mjs +2 -0
- package/dist/esm/buildParamMeta-D8td47fL.mjs.map +1 -0
- package/dist/esm/constants.d.mts.map +1 -1
- package/dist/esm/createRouter.d.mts +1 -1
- package/dist/esm/createRouter.d.mts.map +1 -1
- package/dist/esm/engine/path-matcher/SegmentMatcher.d.mts +14 -1
- package/dist/esm/engine/path-matcher/SegmentMatcher.d.mts.map +1 -1
- package/dist/esm/engine/path-matcher/types.d.mts +3 -0
- package/dist/esm/engine/path-matcher/types.d.mts.map +1 -1
- package/dist/esm/index.d.mts +3 -3
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/internals.d.mts +30 -8
- package/dist/esm/internals.d.mts.map +1 -1
- package/dist/esm/namespaces/RoutesNamespace/routesStore.d.mts +8 -0
- package/dist/esm/namespaces/RoutesNamespace/routesStore.d.mts.map +1 -1
- package/dist/esm/namespaces/RoutesNamespace/types.d.mts +24 -7
- package/dist/esm/namespaces/RoutesNamespace/types.d.mts.map +1 -1
- package/dist/esm/pipeline/port.d.mts +147 -0
- package/dist/esm/pipeline/port.d.mts.map +1 -0
- package/dist/esm/types/RouterValidator.d.mts +14 -0
- package/dist/esm/types/RouterValidator.d.mts.map +1 -1
- package/dist/esm/types/api.d.mts +20 -11
- package/dist/esm/types/api.d.mts.map +1 -1
- package/dist/esm/types/base.d.mts +63 -4
- package/dist/esm/types/base.d.mts.map +1 -1
- package/dist/esm/types/constants.d.mts +1 -0
- package/dist/esm/types/constants.d.mts.map +1 -1
- package/dist/esm/types/router.d.mts +112 -23
- package/dist/esm/types/router.d.mts.map +1 -1
- package/dist/esm/types/tree-changed.d.mts +1 -1
- package/dist/esm/types/tree-changed.d.mts.map +1 -1
- package/dist/esm/types.d.mts +20 -11
- package/dist/esm/types.d.mts.map +1 -1
- package/dist/esm/validation.mjs +1 -1
- package/dist/esm/validation.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/cjs/Router-DGUed2F4.js +0 -2
- package/dist/cjs/Router-DGUed2F4.js.map +0 -1
- package/dist/cjs/buildParamMeta-DniluAIV.js +0 -2
- package/dist/cjs/buildParamMeta-DniluAIV.js.map +0 -1
- package/dist/cjs/foundation/event-emitter/EventEmitter.js.map +0 -1
- package/dist/cjs/foundation/fsm/fsm.js.map +0 -1
- package/dist/cjs/foundation/logger/RouterLogger.js.map +0 -1
- package/dist/cjs/foundation/logger/constants.js.map +0 -1
- package/dist/cjs/namespaces/StateNamespace/helpers.js +0 -2
- package/dist/cjs/namespaces/StateNamespace/helpers.js.map +0 -1
- package/dist/cjs/stateMetaStore.js +0 -2
- package/dist/cjs/stateMetaStore.js.map +0 -1
- package/dist/esm/Router-Bk6PfSE8.mjs +0 -2
- package/dist/esm/Router-Bk6PfSE8.mjs.map +0 -1
- package/dist/esm/buildParamMeta-bOLhLF9h.mjs +0 -2
- package/dist/esm/buildParamMeta-bOLhLF9h.mjs.map +0 -1
- /package/dist/cjs/{foundation → utils}/event-emitter/EventEmitter.js +0 -0
- /package/dist/cjs/{foundation → utils}/fsm/fsm.js +0 -0
- /package/dist/cjs/{foundation → utils}/logger/RouterLogger.js +0 -0
- /package/dist/cjs/{foundation → utils}/logger/constants.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","names":["INVALID_QUERY_NAME_RGX","buildParamMeta","describeRemovedForm","findSegmentGrammarError"],"sources":["../../src/engine/validation/routes.ts","../../src/engine/validation/route-batch.ts"],"sourcesContent":["import {\n buildParamMeta,\n describeRemovedForm,\n findSegmentGrammarError,\n INVALID_QUERY_NAME_RGX,\n} from \"../path-matcher\";\n\nimport type { RemovedForm, SegmentErrorCode } from \"../path-matcher\";\nimport type { RouteTree } from \"../types\";\n\n/**\n * Creates a TypeError with consistent router error message format.\n *\n * @param methodName - Name of the method that triggered the error\n * @param message - Error message\n * @returns TypeError with formatted message\n * @internal\n */\nfunction createRouterError(methodName: string, message: string): TypeError {\n return new TypeError(`[router.${methodName}] ${message}`);\n}\n\n/**\n * Rejects a param name repeated within one route's own path (`/:id/:id`, a\n * param+splat clash `/:x/*x`, #1151). `buildParamMeta.urlParams` lists every\n * path-binding name — params AND splats — in order, keeping duplicates (`/:x/*x`\n * → `[\"x\", \"x\"]`), so a single pass over it catches both. The trie binds the\n * duplicates at different positions under one name, so match's later capture\n * silently overwrites the earlier and `rewritePathOnMatch` then rewrites the\n * user's URL from the single survivor. The #736 conflict guard only fires on\n * DIFFERENTLY-named params at one position, so this same-name case slips through.\n * path-matcher's `registerTree` backstop additionally catches CROSS-level dups (a\n * parent's param reused by a child), which this per-path gate cannot see.\n * Extracted so `validateRoutePath` stays within the cognitive-complexity budget.\n */\nfunction validateUniqueParamNames(\n urlParams: readonly string[],\n routeName: string,\n methodName: string,\n path: string,\n): void {\n const seen = new Set<string>();\n\n for (const name of urlParams) {\n if (seen.has(name)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": duplicate parameter name ':${name}' in \"${path}\" (a param name must be unique within a route — the second binding would overwrite the first)`,\n );\n }\n\n seen.add(name);\n }\n}\n\n/**\n * #1242 §5.1/§5.3: rejects a malformed query-param declaration — a query name\n * carrying `<`/`>` (`/a?fil<ter` — a `<` in a plain query tail; never round-trips),\n * or one that collides with a path-param name (`/a/:tab?tab`, where buildPath emits\n * the value twice). Narrow to `<>`: a `=` in the declaration (`?tab=1`, §5.2) is\n * tolerated today and left as a separate call. (Under M1 a reverse-order typo\n * `/a/:b?<c>` is caught earlier as optional-removed — the `?<` keeps it in the\n * path, §3.3.) path-matcher's `registerTree` backstops both; this gate adds the\n * route-contextual message.\n */\nfunction validateQueryParamDeclarations(\n urlParams: readonly string[],\n queryParams: readonly string[],\n routeName: string,\n methodName: string,\n path: string,\n): void {\n const urlParamSet = new Set(urlParams);\n\n for (const name of queryParams) {\n if (INVALID_QUERY_NAME_RGX.test(name)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": invalid query-param name \"${name}\" in \"${path}\" (a query-param name cannot contain '<' or '>' — it would never round-trip; rename the query param)`,\n );\n }\n\n if (urlParamSet.has(name)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": \"${name}\" is declared as both a path param and a query param in \"${path}\" — buildPath would emit its value twice (rename one)`,\n );\n }\n }\n}\n\n/**\n * Reports whether a path has a raw non-ASCII code point (≥ U+0080) in a STATIC\n * segment (`/café`, `/меню`, #1154). match rejects any non-ASCII input byte\n * (`#scanPath`) and compares static trie keys raw, so such a route registers but\n * is unmatchable — `buildPath` emits `/café`, which its own `match` rejects. Only\n * static text is flagged: a marker-led segment (`:café`, a non-ASCII param NAME)\n * is skipped. A `for…of` code-point scan tracking segment start. Runs AFTER the\n * removed-form / grammar rejections, so no `<`/`>` (a former constraint) can\n * reach it — the 3-token grammar has no constraint body to skip (M1, #1516).\n */\nfunction hasNonAsciiStatic(path: string): boolean {\n let atSegmentStart = true;\n let segmentIsMarker = false;\n\n for (const char of path) {\n if (char === \"/\") {\n atSegmentStart = true;\n\n continue;\n }\n\n if (atSegmentStart) {\n segmentIsMarker = char === \":\" || char === \"*\";\n atSegmentStart = false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- non-empty code point from for-of\n if (!segmentIsMarker && char.codePointAt(0)! >= 0x80) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Maps a SURVIVING per-segment grammar error code (from `findSegmentGrammarError`)\n * to the gate's route-contextual message. The removed-form codes (`optional-removed`\n * / `constraint-removed`) are NOT handled here — they carry a richer replacement\n * recipe built by `removedFormMessage` from `describeRemovedForm`.\n */\nfunction gateGrammarMessage(\n code: Exclude<SegmentErrorCode, \"optional-removed\" | \"constraint-removed\">,\n routeName: string,\n path: string,\n): string {\n switch (code) {\n case \"name-less\":\n case \"trailing-marker\": {\n return `Invalid path for route \"${routeName}\": parameter marker (':' or '*') without a name in \"${path}\"`;\n }\n case \"fused-marker\": {\n return `Invalid path for route \"${routeName}\": parameter marker (':' or '*') must begin a segment, but \"${path}\" fuses one to a static prefix (use a boundary marker like \"/a/:b\")`;\n }\n }\n}\n\n/**\n * Builds the route-contextual replacement recipe for a removed form (M1) — the\n * RICH tier (the matcher backstop uses a shorter, path-free recipe). For an\n * optional it names the offending segment and the two concrete sibling paths that\n * replace it (computed from the actual path by `describeRemovedForm`); for a\n * constraint it names the offending segment and points to a guard.\n */\nfunction removedFormMessage(removed: RemovedForm, routeName: string): string {\n if (removed.code === \"optional-removed\") {\n return `Invalid path for route \"${routeName}\": optional params are not supported — \"${removed.segment}\". Declare two sibling routes instead: \"${removed.withoutSegment}\" and \"${removed.requiredForm}\" (the route hierarchy already expresses optionality)`;\n }\n\n return `Invalid path for route \"${routeName}\": regex constraints are not supported — '<' and '>' are reserved in path segments (\"${removed.segment}\"). Match the segment as a plain string and validate the value in a guard (canActivate) or app code`;\n}\n\n/**\n * Validates route path format.\n * Throws a descriptive error if validation fails.\n *\n * Allows:\n * - Empty string (for grouping/root routes)\n * - Absolute paths: /path, ~path\n * - Query strings: ?query\n * - Relative segments: segment\n *\n * Prevents:\n * - Non-string values\n * - Double slashes (//)\n * - Absolute paths (~) under parameterized parent nodes\n *\n * @param path - Route path to validate\n * @param routeName - Name of route (for error messages)\n * @param methodName - Name of calling method for error messages\n * @param parentNode - Optional parent node for context validation\n * @throws {TypeError} If path is invalid\n *\n * @example\n * // Valid paths\n * validateRoutePath(\"\", \"home\", \"add\"); // ok (empty for grouping)\n * validateRoutePath(\"/users\", \"users\", \"add\"); // ok (absolute)\n * validateRoutePath(\"~dashboard\", \"dash\", \"add\"); // ok (absolute, if no parameterized parent)\n * validateRoutePath(\"?tab=1\", \"home\", \"add\"); // ok (query)\n * validateRoutePath(\"profile\", \"users.profile\", \"add\"); // ok (relative)\n *\n * @example\n * // Invalid paths (throws)\n * validateRoutePath(\"/users//list\", \"users.list\", \"add\"); // throws (double slash)\n * validateRoutePath(\"~dash\", \"dash\", \"add\", paramParent); // throws (~ under parameterized parent)\n */\n// A format-validation gate: a flat sequence of INDEPENDENT guard clauses (type,\n// whitespace, format, double-slash, dup-param, query-decl, the M1 removed-form\n// recipe, surviving grammar markers (name-less / fused / trailing), non-ASCII\n// static, absolute-under-param). Each is a simple early throw; extracting them\n// would only scatter one checklist.\n\nexport function validateRoutePath(\n path: unknown,\n routeName: string,\n methodName: string,\n parentNode?: RouteTree,\n): asserts path is string {\n // Type check\n if (typeof path !== \"string\") {\n // Get type description for error message\n let typeDesc: string;\n\n if (path === null) {\n typeDesc = \"null\";\n } else if (Array.isArray(path)) {\n typeDesc = \"array\";\n } else {\n typeDesc = typeof path;\n }\n\n throw createRouterError(\n methodName,\n `Route path must be a string, got ${typeDesc}`,\n );\n }\n\n // Empty path is valid (for grouping/root)\n if (path === \"\") {\n return;\n }\n\n // No whitespace characters (spaces, tabs, newlines)\n if (/\\s/.test(path)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": whitespace not allowed in \"${path}\"`,\n );\n }\n\n // Valid path pattern\n if (!/^([/?~]|[^/]+$)/.test(path)) {\n throw createRouterError(\n methodName,\n `Route \"${routeName}\" has invalid path format: \"${path}\". Path should start with '/', '~', '?' or be a relative segment.`,\n );\n }\n\n // No double slashes\n if (path.includes(\"//\")) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": double slashes not allowed in \"${path}\"`,\n );\n }\n\n // The grammar checks below scan only the URL-path portion: `buildParamMeta`\n // strips the query the same way the trie does, so a `:`/`*` inside a query\n // declaration is not falsely flagged. (`buildParamMeta` is total — the 3-token\n // grammar has no constraint body to compile, so it never throws — M1, #1516.)\n const { pathPattern, urlParams, queryParams } = buildParamMeta(path);\n\n // Duplicate param name within this route's own path (`/:id/:id`, `/:x/*x`, #1151).\n validateUniqueParamNames(urlParams, routeName, methodName, path);\n\n // Malformed query-param declarations (#1242 §5.1/§5.2/§5.3): a query name with\n // `<>`, or one that collides with a path-param name.\n validateQueryParamDeclarations(\n urlParams,\n queryParams,\n routeName,\n methodName,\n path,\n );\n\n // Removed-form (M1) rejection first — a `:x?` optional or a `<re>` constraint —\n // with the RICH route-contextual replacement recipe (the offending segment plus,\n // for an optional, the two computed sibling paths). Returns undefined when the\n // path's first grammar error is a SURVIVING code, so the fall-through below runs.\n const removed = describeRemovedForm(pathPattern);\n\n if (removed !== undefined) {\n throw createRouterError(methodName, removedFormMessage(removed, routeName));\n }\n\n // Surviving per-segment grammar rejections via the canonical `parseSegment`\n // tokenizer: name-less (#858/#863), fused-marker (#1050), trailing-marker\n // (#1324). `findSegmentGrammarError` runs the same split+parse the matcher uses,\n // so the gate cannot drift. (Only removed-form codes reach `removed` above; the\n // first error here is therefore always a surviving code.)\n const grammarError = findSegmentGrammarError(pathPattern);\n\n if (grammarError !== undefined) {\n throw createRouterError(\n methodName,\n gateGrammarMessage(\n grammarError as Exclude<\n SegmentErrorCode,\n \"optional-removed\" | \"constraint-removed\"\n >,\n routeName,\n path,\n ),\n );\n }\n\n // Raw non-ASCII in a STATIC segment (`/café`, `/меню`, #1154). match rejects\n // non-ASCII input and compares static keys raw, so the route registers but never\n // matches. Reject with the percent-encode workaround (path-matcher backstops at\n // `registerTree`); a non-ASCII param NAME or constraint body is unaffected.\n if (hasNonAsciiStatic(pathPattern)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": non-ASCII static segment in \"${path}\" — match compares static segments raw and rejects non-ASCII input, so this route would never match. Percent-encode it (e.g. '/caf%C3%A9') or use a param`,\n );\n }\n\n // Absolute paths under parameterized parents\n // Check if parent has URL parameters via paramTypeMap\n const hasUrlParams = parentNode && parentNode.paramMeta.urlParams.length > 0;\n\n if (path.startsWith(\"~\") && hasUrlParams) {\n throw createRouterError(\n methodName,\n `Absolute path \"${path}\" cannot be used under parent route with URL parameters`,\n );\n }\n}\n","/**\n * Batch route validation utilities.\n *\n * Provides validation for adding routes with cross-batch duplicate detection.\n * Used by router.addRoute() to ensure atomicity - all routes validated before any modification.\n */\n\nimport { validateRoutePath } from \"./routes\";\n\nimport type { RouteDefinition, RouteTree } from \"../types\";\n\n/**\n * Pattern for route name validation.\n * Each route name must start with letter/underscore, followed by alphanumeric/hyphen/underscore.\n * Dots are NOT allowed - use children array or { parent } option in addRoute() instead.\n * Rejects: names starting with numbers/hyphens, names containing dots.\n */\nconst ROUTE_NAME_PATTERN = /^[A-Z_a-z][\\w-]*$/;\n\n/**\n * Checks if string contains at least one non-whitespace character.\n */\nconst HAS_NON_WHITESPACE = /\\S/;\n\n/**\n * Maximum route name length to prevent DoS and performance issues.\n */\nconst MAX_ROUTE_NAME_LENGTH = 10_000;\n\n/**\n * Gets a human-readable description of a value's type.\n * Used for error messages to provide helpful debugging information.\n */\nfunction getTypeDescription(value: unknown): string {\n // Handle null explicitly (typeof null === \"object\")\n if (value === null) {\n return \"null\";\n }\n\n if (typeof value === \"object\") {\n // Read `constructor`/`.name` defensively: an adversarial own `constructor`\n // (null, a string, a number, …) is not a real constructor and must not crash\n // here nor yield a non-string (#903); a THROWING accessor — a `constructor`\n // getter, a function constructor with a throwing `.name` getter, or a Proxy\n // that throws on [[Get]] — must not crash either (#1052). Both fall back to\n // \"object\". (Byte-identical twin of type-guards' getTypeDescription —\n // route-tree has no type-guards dependency, so the hardening is duplicated.)\n try {\n const ctor: unknown = (value as { constructor?: unknown }).constructor;\n\n // Return constructor name for class instances\n if (typeof ctor === \"function\" && ctor.name !== \"Object\") {\n return ctor.name || \"object\"; // empty name (anonymous class) → \"object\"\n }\n } catch {\n // Throwing constructor/.name getter or Proxy [[Get]] → fall through (#1052).\n }\n\n // Plain object\n return \"object\";\n }\n\n // Primitive types (string, number, boolean, undefined, etc.)\n return typeof value;\n}\n\n/**\n * Checks if an object has getters or setters.\n * Used to detect potentially malicious route objects that could mutate during processing.\n *\n * @param obj - Object to check\n * @returns true if object has getters or setters\n */\nfunction hasGettersOrSetters(obj: Record<string, unknown>): boolean {\n for (const key of Object.keys(obj)) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\n if (descriptor && (descriptor.get || descriptor.set)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Validates that route is a plain object without getters/setters.\n * Prevents malicious objects that could mutate during processing.\n *\n * @param route - Route to validate\n * @param methodName - Calling method for error context\n * @throws {TypeError} If route is not a plain object\n */\nfunction validateRouteType(\n route: unknown,\n methodName: string,\n): asserts route is Record<string, unknown> {\n if (!route || typeof route !== \"object\") {\n throw new TypeError(\n `[router.${methodName}] Route must be an object, got ${getTypeDescription(route)}`,\n );\n }\n\n // Check for plain object (prototype must be Object.prototype or null)\n const proto: object | null = Object.getPrototypeOf(route) as object | null;\n\n if (proto !== Object.prototype && proto !== null) {\n throw new TypeError(\n `[router.${methodName}] Route must be a plain object, got ${getTypeDescription(route)}`,\n );\n }\n\n // Check for getters/setters (could cause mutations during processing)\n if (hasGettersOrSetters(route as Record<string, unknown>)) {\n throw new TypeError(\n `[router.${methodName}] Route must not have getters or setters`,\n );\n }\n}\n\n/**\n * Validates that encodeParams is a function if provided.\n *\n * @param route - Route configuration\n * @param methodName - Calling method for error context\n * @throws {TypeError} If encodeParams is not a function\n */\nfunction validateEncodeParams(\n route: Record<string, unknown>,\n methodName: string,\n): void {\n if (\n route.encodeParams !== undefined &&\n typeof route.encodeParams !== \"function\"\n ) {\n throw new TypeError(\n `[router.${methodName}] Route \"${String(route.name)}\" encodeParams must be a function`,\n );\n }\n}\n\n/**\n * Validates that decodeParams is a function if provided.\n *\n * @param route - Route configuration\n * @param methodName - Calling method for error context\n * @throws {TypeError} If decodeParams is not a function\n */\nfunction validateDecodeParams(\n route: Record<string, unknown>,\n methodName: string,\n): void {\n if (\n route.decodeParams !== undefined &&\n typeof route.decodeParams !== \"function\"\n ) {\n throw new TypeError(\n `[router.${methodName}] Route \"${String(route.name)}\" decodeParams must be a function`,\n );\n }\n}\n\n/**\n * Validates that route name is a valid string matching the expected format.\n *\n * Route name rules:\n * - Must be a string\n * - Cannot be empty or whitespace-only\n * - Cannot contain dots (use children array or { parent } option instead)\n * - Must match [a-zA-Z_][a-zA-Z0-9_-]*\n *\n * @param route - Route configuration\n * @param methodName - Calling method for error context\n * @throws {TypeError} If name is missing, not a string, or invalid format\n */\nfunction validateRouteName(\n route: Record<string, unknown>,\n methodName: string,\n): asserts route is Record<string, unknown> & { name: string } {\n if (typeof route.name !== \"string\") {\n throw new TypeError(\n `[router.${methodName}] Route name must be a string, got ${getTypeDescription(route.name)}`,\n );\n }\n\n const name = route.name;\n\n // Empty string is not allowed for addRoute (unlike root node in type-guards)\n if (name === \"\") {\n throw new TypeError(`[router.${methodName}] Route name cannot be empty`);\n }\n\n // Whitespace-only strings are invalid\n if (!HAS_NON_WHITESPACE.test(name)) {\n throw new TypeError(\n `[router.${methodName}] Route name cannot contain only whitespace`,\n );\n }\n\n // Length check for technical safety\n if (name.length > MAX_ROUTE_NAME_LENGTH) {\n throw new TypeError(\n `[router.${methodName}] Route name exceeds maximum length of ${MAX_ROUTE_NAME_LENGTH} characters`,\n );\n }\n\n // System routes bypass pattern validation (e.g., @@router/UNKNOWN_ROUTE)\n if (name.startsWith(\"@@\")) {\n return;\n }\n\n // Dots are not allowed in route names\n if (name.includes(\".\")) {\n throw new TypeError(\n `[router.${methodName}] Route name \"${name}\" cannot contain dots. ` +\n `Use children array or { parent } option in addRoute() instead.`,\n );\n }\n\n // Validate route pattern (ASCII only: letters, numbers, underscores, hyphens)\n if (!ROUTE_NAME_PATTERN.test(name)) {\n throw new TypeError(\n `[router.${methodName}] Invalid route name \"${name}\". ` +\n `Name must start with a letter or underscore, ` +\n `followed by letters, numbers, underscores, or hyphens.`,\n );\n }\n}\n\n/**\n * Finds a node by its fullName in the tree.\n * Even though user-provided route names cannot contain dots,\n * fullName is computed during validation (e.g., \"parent.child\").\n *\n * @param rootNode - Root node to start from\n * @param fullName - Full route name (e.g., \"users.profile\")\n * @returns The resolved node, or undefined if not found\n */\nfunction findNodeByFullName(\n rootNode: RouteTree,\n fullName: string,\n): RouteTree | undefined {\n // Fast path: single-segment names don't need splitting\n // Stryker disable next-line ConditionalExpression,StringLiteral,BlockStatement: equivalent — the fast path is a pure optimization; for a dotless name the general path below yields the identical result (`name.split(\".\")` → `[name]`, a one-iteration `children.get(name)`). (BooleanLiteral stays live: dropping the `!` runs the fast path for a dotted name → `children.get(\"a.b\")` is undefined = killed.)\n if (!fullName.includes(\".\")) {\n return rootNode.children.get(fullName);\n }\n\n let current: RouteTree | undefined = rootNode;\n\n for (const segment of fullName.split(\".\")) {\n current = current.children.get(segment);\n\n if (!current) {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Checks for duplicate route name in existing tree.\n *\n * @param rootNode - Root node to search in\n * @param fullName - Full route name (dot-notation)\n * @param methodName - Calling method for error context\n * @throws {Error} If route name already exists\n */\nfunction checkTreeNameDuplicate(\n rootNode: RouteTree,\n fullName: string,\n methodName: string,\n): void {\n if (findNodeByFullName(rootNode, fullName)) {\n throw new Error(\n `[router.${methodName}] Route \"${fullName}\" already exists`,\n );\n }\n}\n\n/**\n * Checks for duplicate route name in current batch.\n *\n * @param seenNames - Set of names already seen in batch\n * @param fullName - Full route name to check\n * @param methodName - Calling method for error context\n * @throws {Error} If duplicate name in batch\n */\nfunction checkBatchNameDuplicate(\n seenNames: Set<string>,\n fullName: string,\n methodName: string,\n): void {\n if (seenNames.has(fullName)) {\n throw new Error(\n `[router.${methodName}] Duplicate route \"${fullName}\" in batch`,\n );\n }\n\n seenNames.add(fullName);\n}\n\n/**\n * Checks for duplicate path in existing tree at same parent level.\n *\n * @param rootNode - Root node to search in\n * @param parentName - Parent route name (empty string for root level)\n * @param routePath - Path to check for duplicates\n * @throws {Error} If path already exists at this level\n */\nfunction checkTreePathDuplicate(\n rootNode: RouteTree,\n parentName: string,\n routePath: string,\n methodName: string,\n): void {\n const parentNode =\n parentName === \"\" ? rootNode : findNodeByFullName(rootNode, parentName);\n\n if (!parentNode) {\n return; // Parent doesn't exist, so no duplicate\n }\n\n for (const child of parentNode.children.values()) {\n if (child.path === routePath) {\n throw new Error(\n `[router.${methodName}] Path \"${routePath}\" is already defined`,\n );\n }\n }\n}\n\n/**\n * Checks for duplicate path in current batch at same parent level.\n *\n * @param seenPathsByParent - Map of paths by parent name\n * @param parentName - Parent route name (empty string for root level)\n * @param routePath - Path to check for duplicates\n * @throws {Error} If path already exists at this level in batch\n */\nfunction checkBatchPathDuplicate(\n seenPathsByParent: Map<string, Set<string>>,\n parentName: string,\n routePath: string,\n methodName: string,\n): void {\n const pathsAtLevel = seenPathsByParent.get(parentName);\n\n if (pathsAtLevel?.has(routePath)) {\n throw new Error(\n `[router.${methodName}] Path \"${routePath}\" is already defined`,\n );\n }\n\n if (pathsAtLevel) {\n pathsAtLevel.add(routePath);\n } else {\n seenPathsByParent.set(parentName, new Set([routePath]));\n }\n}\n\n/**\n * Validates route structure for add operations.\n *\n * Performs comprehensive validation including:\n * - Type check (must be object)\n * - Name validation\n * - Path validation\n * - Duplicate name detection (in tree and batch)\n * - Duplicate path detection (in tree and batch)\n * - Recursive children validation\n *\n * @param route - Route to validate\n * @param methodName - Calling method for error context\n * @param rootNode - Optional root node for duplicate checking\n * @param parentName - Parent route name for building full path (used in recursion)\n * @param seenNames - Set of names already seen in this batch\n * @param seenPathsByParent - Map of paths by parent for path duplicate detection\n * @throws {TypeError} If route structure is invalid\n * @throws {Error} If route already exists (duplicate)\n * @throws {Error} If path already defined (duplicate)\n *\n * @example\n * ```typescript\n * const seenNames = new Set<string>();\n * const seenPaths = new Map<string, Set<string>>();\n *\n * // Validate routes before adding\n * for (const route of routes) {\n * validateRoute(route, \"add\", rootNode, \"\", seenNames, seenPaths);\n * }\n * ```\n */\nexport function validateRoute(\n route: unknown,\n methodName: string,\n rootNode?: RouteTree,\n parentName = \"\",\n seenNames?: Set<string>,\n seenPathsByParent?: Map<string, Set<string>>,\n): asserts route is RouteDefinition {\n validateRouteType(route, methodName);\n\n const routeDef = route;\n\n // Validate that name is a non-empty string\n validateRouteName(routeDef, methodName);\n\n // Validate path structure\n validateRoutePath(routeDef.path, routeDef.name, methodName, rootNode);\n\n // Validate optional function properties\n validateEncodeParams(routeDef, methodName);\n validateDecodeParams(routeDef, methodName);\n\n const routeName = routeDef.name;\n const fullName = parentName ? `${parentName}.${routeName}` : routeName;\n\n // Check for duplicate name in existing tree\n if (rootNode && fullName) {\n checkTreeNameDuplicate(rootNode, fullName, methodName);\n }\n\n // Check for duplicate name in current batch\n if (seenNames) {\n checkBatchNameDuplicate(seenNames, fullName, methodName);\n }\n\n const routePath = routeDef.path;\n const pathCheckParent = parentName;\n\n // Check for duplicate path in existing tree\n if (rootNode) {\n checkTreePathDuplicate(rootNode, pathCheckParent, routePath, methodName);\n }\n\n // Check for duplicate path in current batch\n if (seenPathsByParent) {\n checkBatchPathDuplicate(\n seenPathsByParent,\n pathCheckParent,\n routePath,\n methodName,\n );\n }\n\n // Validate children recursively\n if (routeDef.children !== undefined) {\n if (!Array.isArray(routeDef.children)) {\n throw new TypeError(\n `[router.${methodName}] Route \"${routeName}\" children must be an array, got ${getTypeDescription(routeDef.children)}`,\n );\n }\n\n for (const child of routeDef.children) {\n validateRoute(\n child,\n methodName,\n rootNode,\n fullName,\n seenNames,\n seenPathsByParent,\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation.js","names":["INVALID_QUERY_NAME_RGX","buildParamMeta","describeRemovedForm","findSegmentGrammarError"],"sources":["../../src/engine/validation/routes.ts","../../src/engine/validation/route-batch.ts"],"sourcesContent":["import {\n buildParamMeta,\n describeRemovedForm,\n findSegmentGrammarError,\n INVALID_QUERY_NAME_RGX,\n} from \"../path-matcher\";\n\nimport type { RemovedForm, SegmentErrorCode } from \"../path-matcher\";\nimport type { RouteTree } from \"../types\";\n\n/**\n * Creates a TypeError with consistent router error message format.\n *\n * @param methodName - Name of the method that triggered the error\n * @param message - Error message\n * @returns TypeError with formatted message\n * @internal\n */\nfunction createRouterError(methodName: string, message: string): TypeError {\n return new TypeError(`[router.${methodName}] ${message}`);\n}\n\n/**\n * Rejects a param name repeated within one route's own path (`/:id/:id`, a\n * param+splat clash `/:x/*x`, #1151). `buildParamMeta.urlParams` lists every\n * path-binding name — params AND splats — in order, keeping duplicates (`/:x/*x`\n * → `[\"x\", \"x\"]`), so a single pass over it catches both. The trie binds the\n * duplicates at different positions under one name, so match's later capture\n * silently overwrites the earlier and `rewritePathOnMatch` then rewrites the\n * user's URL from the single survivor. The #736 conflict guard only fires on\n * DIFFERENTLY-named params at one position, so this same-name case slips through.\n * path-matcher's `registerTree` backstop additionally catches CROSS-level dups (a\n * parent's param reused by a child), which this per-path gate cannot see.\n * Extracted so `validateRoutePath` stays within the cognitive-complexity budget.\n */\nfunction validateUniqueParamNames(\n urlParams: readonly string[],\n routeName: string,\n methodName: string,\n path: string,\n): void {\n const seen = new Set<string>();\n\n for (const name of urlParams) {\n if (seen.has(name)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": duplicate parameter name ':${name}' in \"${path}\" (a param name must be unique within a route — the second binding would overwrite the first)`,\n );\n }\n\n seen.add(name);\n }\n}\n\n/**\n * #1242 §5.1/§5.3: rejects a malformed query-param declaration — a query name\n * carrying `<`/`>` (`/a?fil<ter` — a `<` in a plain query tail; never round-trips),\n * or one that collides with a path-param name (`/a/:tab?tab`, where buildPath emits\n * the value twice). Narrow to `<>`: a `=` in the declaration (`?tab=1`, §5.2) is\n * tolerated today and left as a separate call. (Under M1 a reverse-order typo\n * `/a/:b?<c>` is caught earlier as optional-removed — the `?<` keeps it in the\n * path, §3.3.) path-matcher's `registerTree` backstops both; this gate adds the\n * route-contextual message.\n */\nfunction validateQueryParamDeclarations(\n queryParams: readonly string[],\n routeName: string,\n methodName: string,\n path: string,\n): void {\n // A path/query name collision (`/a/:tab?tab`) is legal under M2: `tab` lives\n // in both `state.params` and `state.search` as separate channels (RFC-4 M2 /\n // #1548), so the former \"declared as both\" rejection is gone. Only a query\n // name that can never round-trip (contains `<`/`>`) is still rejected.\n for (const name of queryParams) {\n if (INVALID_QUERY_NAME_RGX.test(name)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": invalid query-param name \"${name}\" in \"${path}\" (a query-param name cannot contain '<' or '>' — it would never round-trip; rename the query param)`,\n );\n }\n }\n}\n\n/**\n * Reports whether a path has a raw non-ASCII code point (≥ U+0080) in a STATIC\n * segment (`/café`, `/меню`, #1154). match rejects any non-ASCII input byte\n * (`#scanPath`) and compares static trie keys raw, so such a route registers but\n * is unmatchable — `buildPath` emits `/café`, which its own `match` rejects. Only\n * static text is flagged: a marker-led segment (`:café`, a non-ASCII param NAME)\n * is skipped. A `for…of` code-point scan tracking segment start. Runs AFTER the\n * removed-form / grammar rejections, so no `<`/`>` (a former constraint) can\n * reach it — the 3-token grammar has no constraint body to skip (M1, #1516).\n */\nfunction hasNonAsciiStatic(path: string): boolean {\n let atSegmentStart = true;\n let segmentIsMarker = false;\n\n for (const char of path) {\n if (char === \"/\") {\n atSegmentStart = true;\n\n continue;\n }\n\n if (atSegmentStart) {\n segmentIsMarker = char === \":\" || char === \"*\";\n atSegmentStart = false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- non-empty code point from for-of\n if (!segmentIsMarker && char.codePointAt(0)! >= 0x80) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Maps a SURVIVING per-segment grammar error code (from `findSegmentGrammarError`)\n * to the gate's route-contextual message. The removed-form codes (`optional-removed`\n * / `constraint-removed`) are NOT handled here — they carry a richer replacement\n * recipe built by `removedFormMessage` from `describeRemovedForm`.\n */\nfunction gateGrammarMessage(\n code: Exclude<SegmentErrorCode, \"optional-removed\" | \"constraint-removed\">,\n routeName: string,\n path: string,\n): string {\n switch (code) {\n case \"name-less\":\n case \"trailing-marker\": {\n return `Invalid path for route \"${routeName}\": parameter marker (':' or '*') without a name in \"${path}\"`;\n }\n case \"fused-marker\": {\n return `Invalid path for route \"${routeName}\": parameter marker (':' or '*') must begin a segment, but \"${path}\" fuses one to a static prefix (use a boundary marker like \"/a/:b\")`;\n }\n }\n}\n\n/**\n * Builds the route-contextual replacement recipe for a removed form (M1) — the\n * RICH tier (the matcher backstop uses a shorter, path-free recipe). For an\n * optional it names the offending segment and the two concrete sibling paths that\n * replace it (computed from the actual path by `describeRemovedForm`); for a\n * constraint it names the offending segment and points to a guard.\n */\nfunction removedFormMessage(removed: RemovedForm, routeName: string): string {\n if (removed.code === \"optional-removed\") {\n return `Invalid path for route \"${routeName}\": optional params are not supported — \"${removed.segment}\". Declare two sibling routes instead: \"${removed.withoutSegment}\" and \"${removed.requiredForm}\" (the route hierarchy already expresses optionality)`;\n }\n\n return `Invalid path for route \"${routeName}\": regex constraints are not supported — '<' and '>' are reserved in path segments (\"${removed.segment}\"). Match the segment as a plain string and validate the value in a guard (canActivate) or app code`;\n}\n\n/**\n * Validates route path format.\n * Throws a descriptive error if validation fails.\n *\n * Allows:\n * - Empty string (for grouping/root routes)\n * - Absolute paths: /path, ~path\n * - Query strings: ?query\n * - Relative segments: segment\n *\n * Prevents:\n * - Non-string values\n * - Double slashes (//)\n * - Absolute paths (~) under parameterized parent nodes\n *\n * @param path - Route path to validate\n * @param routeName - Name of route (for error messages)\n * @param methodName - Name of calling method for error messages\n * @param parentNode - Optional parent node for context validation\n * @throws {TypeError} If path is invalid\n *\n * @example\n * // Valid paths\n * validateRoutePath(\"\", \"home\", \"add\"); // ok (empty for grouping)\n * validateRoutePath(\"/users\", \"users\", \"add\"); // ok (absolute)\n * validateRoutePath(\"~dashboard\", \"dash\", \"add\"); // ok (absolute, if no parameterized parent)\n * validateRoutePath(\"?tab=1\", \"home\", \"add\"); // ok (query)\n * validateRoutePath(\"profile\", \"users.profile\", \"add\"); // ok (relative)\n *\n * @example\n * // Invalid paths (throws)\n * validateRoutePath(\"/users//list\", \"users.list\", \"add\"); // throws (double slash)\n * validateRoutePath(\"~dash\", \"dash\", \"add\", paramParent); // throws (~ under parameterized parent)\n */\n// A format-validation gate: a flat sequence of INDEPENDENT guard clauses (type,\n// whitespace, format, double-slash, dup-param, query-decl, the M1 removed-form\n// recipe, surviving grammar markers (name-less / fused / trailing), non-ASCII\n// static, absolute-under-param). Each is a simple early throw; extracting them\n// would only scatter one checklist.\n\nexport function validateRoutePath(\n path: unknown,\n routeName: string,\n methodName: string,\n parentNode?: RouteTree,\n): asserts path is string {\n // Type check\n if (typeof path !== \"string\") {\n // Get type description for error message\n let typeDesc: string;\n\n if (path === null) {\n typeDesc = \"null\";\n } else if (Array.isArray(path)) {\n typeDesc = \"array\";\n } else {\n typeDesc = typeof path;\n }\n\n throw createRouterError(\n methodName,\n `Route path must be a string, got ${typeDesc}`,\n );\n }\n\n // Empty path is valid (for grouping/root)\n if (path === \"\") {\n return;\n }\n\n // No whitespace characters (spaces, tabs, newlines)\n if (/\\s/.test(path)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": whitespace not allowed in \"${path}\"`,\n );\n }\n\n // Valid path pattern\n if (!/^([/?~]|[^/]+$)/.test(path)) {\n throw createRouterError(\n methodName,\n `Route \"${routeName}\" has invalid path format: \"${path}\". Path should start with '/', '~', '?' or be a relative segment.`,\n );\n }\n\n // No double slashes\n if (path.includes(\"//\")) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": double slashes not allowed in \"${path}\"`,\n );\n }\n\n // The grammar checks below scan only the URL-path portion: `buildParamMeta`\n // strips the query the same way the trie does, so a `:`/`*` inside a query\n // declaration is not falsely flagged. (`buildParamMeta` is total — the 3-token\n // grammar has no constraint body to compile, so it never throws — M1, #1516.)\n const { pathPattern, urlParams, queryParams } = buildParamMeta(path);\n\n // Duplicate param name within this route's own path (`/:id/:id`, `/:x/*x`, #1151).\n validateUniqueParamNames(urlParams, routeName, methodName, path);\n\n // Malformed query-param declarations (#1242 §5.1): a query name with `<>`\n // (never round-trips). Name collisions with a path param are legal under M2\n // (separate params/search channels, #1548).\n validateQueryParamDeclarations(queryParams, routeName, methodName, path);\n\n // Removed-form (M1) rejection first — a `:x?` optional or a `<re>` constraint —\n // with the RICH route-contextual replacement recipe (the offending segment plus,\n // for an optional, the two computed sibling paths). Returns undefined when the\n // path's first grammar error is a SURVIVING code, so the fall-through below runs.\n const removed = describeRemovedForm(pathPattern);\n\n if (removed !== undefined) {\n throw createRouterError(methodName, removedFormMessage(removed, routeName));\n }\n\n // Surviving per-segment grammar rejections via the canonical `parseSegment`\n // tokenizer: name-less (#858/#863), fused-marker (#1050), trailing-marker\n // (#1324). `findSegmentGrammarError` runs the same split+parse the matcher uses,\n // so the gate cannot drift. (Only removed-form codes reach `removed` above; the\n // first error here is therefore always a surviving code.)\n const grammarError = findSegmentGrammarError(pathPattern);\n\n if (grammarError !== undefined) {\n throw createRouterError(\n methodName,\n gateGrammarMessage(\n grammarError as Exclude<\n SegmentErrorCode,\n \"optional-removed\" | \"constraint-removed\"\n >,\n routeName,\n path,\n ),\n );\n }\n\n // Raw non-ASCII in a STATIC segment (`/café`, `/меню`, #1154). match rejects\n // non-ASCII input and compares static keys raw, so the route registers but never\n // matches. Reject with the percent-encode workaround (path-matcher backstops at\n // `registerTree`); a non-ASCII param NAME or constraint body is unaffected.\n if (hasNonAsciiStatic(pathPattern)) {\n throw createRouterError(\n methodName,\n `Invalid path for route \"${routeName}\": non-ASCII static segment in \"${path}\" — match compares static segments raw and rejects non-ASCII input, so this route would never match. Percent-encode it (e.g. '/caf%C3%A9') or use a param`,\n );\n }\n\n // Absolute paths under parameterized parents\n // Check if parent has URL parameters via paramTypeMap\n const hasUrlParams = parentNode && parentNode.paramMeta.urlParams.length > 0;\n\n if (path.startsWith(\"~\") && hasUrlParams) {\n throw createRouterError(\n methodName,\n `Absolute path \"${path}\" cannot be used under parent route with URL parameters`,\n );\n }\n}\n","/**\n * Batch route validation utilities.\n *\n * Provides validation for adding routes with cross-batch duplicate detection.\n * Used by router.addRoute() to ensure atomicity - all routes validated before any modification.\n */\n\nimport { validateRoutePath } from \"./routes\";\n\nimport type { RouteDefinition, RouteTree } from \"../types\";\n\n/**\n * Pattern for route name validation.\n * Each route name must start with letter/underscore, followed by alphanumeric/hyphen/underscore.\n * Dots are NOT allowed - use children array or { parent } option in addRoute() instead.\n * Rejects: names starting with numbers/hyphens, names containing dots.\n */\nconst ROUTE_NAME_PATTERN = /^[A-Z_a-z][\\w-]*$/;\n\n/**\n * Checks if string contains at least one non-whitespace character.\n */\nconst HAS_NON_WHITESPACE = /\\S/;\n\n/**\n * Maximum route name length to prevent DoS and performance issues.\n */\nconst MAX_ROUTE_NAME_LENGTH = 10_000;\n\n/**\n * Gets a human-readable description of a value's type.\n * Used for error messages to provide helpful debugging information.\n */\nfunction getTypeDescription(value: unknown): string {\n // Handle null explicitly (typeof null === \"object\")\n if (value === null) {\n return \"null\";\n }\n\n if (typeof value === \"object\") {\n // Read `constructor`/`.name` defensively: an adversarial own `constructor`\n // (null, a string, a number, …) is not a real constructor and must not crash\n // here nor yield a non-string (#903); a THROWING accessor — a `constructor`\n // getter, a function constructor with a throwing `.name` getter, or a Proxy\n // that throws on [[Get]] — must not crash either (#1052). Both fall back to\n // \"object\". (Byte-identical twin of type-guards' getTypeDescription —\n // route-tree has no type-guards dependency, so the hardening is duplicated.)\n try {\n const ctor: unknown = (value as { constructor?: unknown }).constructor;\n\n // Return constructor name for class instances\n if (typeof ctor === \"function\" && ctor.name !== \"Object\") {\n return ctor.name || \"object\"; // empty name (anonymous class) → \"object\"\n }\n } catch {\n // Throwing constructor/.name getter or Proxy [[Get]] → fall through (#1052).\n }\n\n // Plain object\n return \"object\";\n }\n\n // Primitive types (string, number, boolean, undefined, etc.)\n return typeof value;\n}\n\n/**\n * Checks if an object has getters or setters.\n * Used to detect potentially malicious route objects that could mutate during processing.\n *\n * @param obj - Object to check\n * @returns true if object has getters or setters\n */\nfunction hasGettersOrSetters(obj: Record<string, unknown>): boolean {\n for (const key of Object.keys(obj)) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\n if (descriptor && (descriptor.get || descriptor.set)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Validates that route is a plain object without getters/setters.\n * Prevents malicious objects that could mutate during processing.\n *\n * @param route - Route to validate\n * @param methodName - Calling method for error context\n * @throws {TypeError} If route is not a plain object\n */\nfunction validateRouteType(\n route: unknown,\n methodName: string,\n): asserts route is Record<string, unknown> {\n if (!route || typeof route !== \"object\") {\n throw new TypeError(\n `[router.${methodName}] Route must be an object, got ${getTypeDescription(route)}`,\n );\n }\n\n // Check for plain object (prototype must be Object.prototype or null)\n const proto: object | null = Object.getPrototypeOf(route) as object | null;\n\n if (proto !== Object.prototype && proto !== null) {\n throw new TypeError(\n `[router.${methodName}] Route must be a plain object, got ${getTypeDescription(route)}`,\n );\n }\n\n // Check for getters/setters (could cause mutations during processing)\n if (hasGettersOrSetters(route as Record<string, unknown>)) {\n throw new TypeError(\n `[router.${methodName}] Route must not have getters or setters`,\n );\n }\n}\n\n/**\n * Validates that encodeParams is a function if provided.\n *\n * @param route - Route configuration\n * @param methodName - Calling method for error context\n * @throws {TypeError} If encodeParams is not a function\n */\nfunction validateEncodeParams(\n route: Record<string, unknown>,\n methodName: string,\n): void {\n if (\n route.encodeParams !== undefined &&\n typeof route.encodeParams !== \"function\"\n ) {\n throw new TypeError(\n `[router.${methodName}] Route \"${String(route.name)}\" encodeParams must be a function`,\n );\n }\n}\n\n/**\n * Validates that decodeParams is a function if provided.\n *\n * @param route - Route configuration\n * @param methodName - Calling method for error context\n * @throws {TypeError} If decodeParams is not a function\n */\nfunction validateDecodeParams(\n route: Record<string, unknown>,\n methodName: string,\n): void {\n if (\n route.decodeParams !== undefined &&\n typeof route.decodeParams !== \"function\"\n ) {\n throw new TypeError(\n `[router.${methodName}] Route \"${String(route.name)}\" decodeParams must be a function`,\n );\n }\n}\n\n/**\n * Validates that route name is a valid string matching the expected format.\n *\n * Route name rules:\n * - Must be a string\n * - Cannot be empty or whitespace-only\n * - Cannot contain dots (use children array or { parent } option instead)\n * - Must match [a-zA-Z_][a-zA-Z0-9_-]*\n *\n * @param route - Route configuration\n * @param methodName - Calling method for error context\n * @throws {TypeError} If name is missing, not a string, or invalid format\n */\nfunction validateRouteName(\n route: Record<string, unknown>,\n methodName: string,\n): asserts route is Record<string, unknown> & { name: string } {\n if (typeof route.name !== \"string\") {\n throw new TypeError(\n `[router.${methodName}] Route name must be a string, got ${getTypeDescription(route.name)}`,\n );\n }\n\n const name = route.name;\n\n // Empty string is not allowed for addRoute (unlike root node in type-guards)\n if (name === \"\") {\n throw new TypeError(`[router.${methodName}] Route name cannot be empty`);\n }\n\n // Whitespace-only strings are invalid\n if (!HAS_NON_WHITESPACE.test(name)) {\n throw new TypeError(\n `[router.${methodName}] Route name cannot contain only whitespace`,\n );\n }\n\n // Length check for technical safety\n if (name.length > MAX_ROUTE_NAME_LENGTH) {\n throw new TypeError(\n `[router.${methodName}] Route name exceeds maximum length of ${MAX_ROUTE_NAME_LENGTH} characters`,\n );\n }\n\n // System routes bypass pattern validation (e.g., @@router/UNKNOWN_ROUTE)\n if (name.startsWith(\"@@\")) {\n return;\n }\n\n // Dots are not allowed in route names\n if (name.includes(\".\")) {\n throw new TypeError(\n `[router.${methodName}] Route name \"${name}\" cannot contain dots. ` +\n `Use children array or { parent } option in addRoute() instead.`,\n );\n }\n\n // Validate route pattern (ASCII only: letters, numbers, underscores, hyphens)\n if (!ROUTE_NAME_PATTERN.test(name)) {\n throw new TypeError(\n `[router.${methodName}] Invalid route name \"${name}\". ` +\n `Name must start with a letter or underscore, ` +\n `followed by letters, numbers, underscores, or hyphens.`,\n );\n }\n}\n\n/**\n * Finds a node by its fullName in the tree.\n * Even though user-provided route names cannot contain dots,\n * fullName is computed during validation (e.g., \"parent.child\").\n *\n * @param rootNode - Root node to start from\n * @param fullName - Full route name (e.g., \"users.profile\")\n * @returns The resolved node, or undefined if not found\n */\nfunction findNodeByFullName(\n rootNode: RouteTree,\n fullName: string,\n): RouteTree | undefined {\n // Fast path: single-segment names don't need splitting\n // Stryker disable next-line ConditionalExpression,StringLiteral,BlockStatement: equivalent — the fast path is a pure optimization; for a dotless name the general path below yields the identical result (`name.split(\".\")` → `[name]`, a one-iteration `children.get(name)`). (BooleanLiteral stays live: dropping the `!` runs the fast path for a dotted name → `children.get(\"a.b\")` is undefined = killed.)\n if (!fullName.includes(\".\")) {\n return rootNode.children.get(fullName);\n }\n\n let current: RouteTree | undefined = rootNode;\n\n for (const segment of fullName.split(\".\")) {\n current = current.children.get(segment);\n\n if (!current) {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Checks for duplicate route name in existing tree.\n *\n * @param rootNode - Root node to search in\n * @param fullName - Full route name (dot-notation)\n * @param methodName - Calling method for error context\n * @throws {Error} If route name already exists\n */\nfunction checkTreeNameDuplicate(\n rootNode: RouteTree,\n fullName: string,\n methodName: string,\n): void {\n if (findNodeByFullName(rootNode, fullName)) {\n throw new Error(\n `[router.${methodName}] Route \"${fullName}\" already exists`,\n );\n }\n}\n\n/**\n * Checks for duplicate route name in current batch.\n *\n * @param seenNames - Set of names already seen in batch\n * @param fullName - Full route name to check\n * @param methodName - Calling method for error context\n * @throws {Error} If duplicate name in batch\n */\nfunction checkBatchNameDuplicate(\n seenNames: Set<string>,\n fullName: string,\n methodName: string,\n): void {\n if (seenNames.has(fullName)) {\n throw new Error(\n `[router.${methodName}] Duplicate route \"${fullName}\" in batch`,\n );\n }\n\n seenNames.add(fullName);\n}\n\n/**\n * Checks for duplicate path in existing tree at same parent level.\n *\n * @param rootNode - Root node to search in\n * @param parentName - Parent route name (empty string for root level)\n * @param routePath - Path to check for duplicates\n * @throws {Error} If path already exists at this level\n */\nfunction checkTreePathDuplicate(\n rootNode: RouteTree,\n parentName: string,\n routePath: string,\n methodName: string,\n): void {\n const parentNode =\n parentName === \"\" ? rootNode : findNodeByFullName(rootNode, parentName);\n\n if (!parentNode) {\n return; // Parent doesn't exist, so no duplicate\n }\n\n for (const child of parentNode.children.values()) {\n if (child.path === routePath) {\n throw new Error(\n `[router.${methodName}] Path \"${routePath}\" is already defined`,\n );\n }\n }\n}\n\n/**\n * Checks for duplicate path in current batch at same parent level.\n *\n * @param seenPathsByParent - Map of paths by parent name\n * @param parentName - Parent route name (empty string for root level)\n * @param routePath - Path to check for duplicates\n * @throws {Error} If path already exists at this level in batch\n */\nfunction checkBatchPathDuplicate(\n seenPathsByParent: Map<string, Set<string>>,\n parentName: string,\n routePath: string,\n methodName: string,\n): void {\n const pathsAtLevel = seenPathsByParent.get(parentName);\n\n if (pathsAtLevel?.has(routePath)) {\n throw new Error(\n `[router.${methodName}] Path \"${routePath}\" is already defined`,\n );\n }\n\n if (pathsAtLevel) {\n pathsAtLevel.add(routePath);\n } else {\n seenPathsByParent.set(parentName, new Set([routePath]));\n }\n}\n\n/**\n * Validates route structure for add operations.\n *\n * Performs comprehensive validation including:\n * - Type check (must be object)\n * - Name validation\n * - Path validation\n * - Duplicate name detection (in tree and batch)\n * - Duplicate path detection (in tree and batch)\n * - Recursive children validation\n *\n * @param route - Route to validate\n * @param methodName - Calling method for error context\n * @param rootNode - Optional root node for duplicate checking\n * @param parentName - Parent route name for building full path (used in recursion)\n * @param seenNames - Set of names already seen in this batch\n * @param seenPathsByParent - Map of paths by parent for path duplicate detection\n * @throws {TypeError} If route structure is invalid\n * @throws {Error} If route already exists (duplicate)\n * @throws {Error} If path already defined (duplicate)\n *\n * @example\n * ```typescript\n * const seenNames = new Set<string>();\n * const seenPaths = new Map<string, Set<string>>();\n *\n * // Validate routes before adding\n * for (const route of routes) {\n * validateRoute(route, \"add\", rootNode, \"\", seenNames, seenPaths);\n * }\n * ```\n */\nexport function validateRoute(\n route: unknown,\n methodName: string,\n rootNode?: RouteTree,\n parentName = \"\",\n seenNames?: Set<string>,\n seenPathsByParent?: Map<string, Set<string>>,\n): asserts route is RouteDefinition {\n validateRouteType(route, methodName);\n\n const routeDef = route;\n\n // Validate that name is a non-empty string\n validateRouteName(routeDef, methodName);\n\n // Validate path structure\n validateRoutePath(routeDef.path, routeDef.name, methodName, rootNode);\n\n // Validate optional function properties\n validateEncodeParams(routeDef, methodName);\n validateDecodeParams(routeDef, methodName);\n\n const routeName = routeDef.name;\n const fullName = parentName ? `${parentName}.${routeName}` : routeName;\n\n // Check for duplicate name in existing tree\n if (rootNode && fullName) {\n checkTreeNameDuplicate(rootNode, fullName, methodName);\n }\n\n // Check for duplicate name in current batch\n if (seenNames) {\n checkBatchNameDuplicate(seenNames, fullName, methodName);\n }\n\n const routePath = routeDef.path;\n const pathCheckParent = parentName;\n\n // Check for duplicate path in existing tree\n if (rootNode) {\n checkTreePathDuplicate(rootNode, pathCheckParent, routePath, methodName);\n }\n\n // Check for duplicate path in current batch\n if (seenPathsByParent) {\n checkBatchPathDuplicate(\n seenPathsByParent,\n pathCheckParent,\n routePath,\n methodName,\n );\n }\n\n // Validate children recursively\n if (routeDef.children !== undefined) {\n if (!Array.isArray(routeDef.children)) {\n throw new TypeError(\n `[router.${methodName}] Route \"${routeName}\" children must be an array, got ${getTypeDescription(routeDef.children)}`,\n );\n }\n\n for (const child of routeDef.children) {\n validateRoute(\n child,\n methodName,\n rootNode,\n fullName,\n seenNames,\n seenPathsByParent,\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../
|
|
1
|
+
const e=require("../internals.js"),t=require("../namespaces/OptionsNamespace/helpers.js"),n=require("../pipeline/canonicalize.js"),r=require("../pipeline/buildURL.js"),i=require("../pipeline/materialize.js");function a(t){let n=o(t),r=f(t),i=()=>e.getInternals(t.router).validator;s(t),c(t,i),l(t,n,i),u(t,r,i),d(t,n,i),p(t,r),m(t),h(t,r)}function o(e){let{router:t,dependenciesStore:n}=e,r=e=>n.dependencies[e];return e=>e(t,r)}function s(e){e.dependenciesStore.limits=e.limits,e.eventBus.setLimits({maxListeners:e.limits.maxListeners,warnListeners:e.limits.warnListeners})}function c(e,t){e.eventBus.setValidatorAccessor(t)}function l(t,n,r){let i={logger:e.getInternals(t.router).logger,compileFactory:n,getValidator:r};t.routeLifecycle.setDependencies(i)}function u(t,n,r){let i={logger:e.getInternals(t.router).logger,getValidator:r,port:n,addActivateGuard:(e,n,r)=>{t.routeLifecycle.addCanActivate(e,n,!0,r)},addDeactivateGuard:(e,n,r)=>{t.routeLifecycle.addCanDeactivate(e,n,!0,r)},compileGuard:(e,n)=>t.routeLifecycle.compileGuardFactory(e,n),getState:()=>t.state.get(),areStatesEqual:(e,n,r)=>t.state.areStatesEqual(e,n,r),getDependency:e=>t.dependenciesStore.dependencies[e]};t.routes.setDependencies(i),t.routes.setLifecycleNamespace(t.routeLifecycle)}function d(t,n,r){let i={logger:e.getInternals(t.router).logger,addEventListener:(e,n)=>t.eventBus.addEventListener(e,n),canNavigate:()=>t.eventBus.canBeginTransition(),compileFactory:n,getValidator:r};t.plugins.setDependencies(i)}function f(t){let n=e.getInternals(t.router),r=t.routes.getStore(),i=(e,t)=>{n.validator?.state.reportUndeclaredParamKey(e,t)},a=(e,t)=>{n.validator?.state.reportDroppedQueryKey(e,t)};return{resolveForward:(e,t,r)=>n.forwardState(e,t,r),defaultParams:e=>r.config.defaultParams[e],defaultSearch:e=>r.config.defaultSearch[e],buildPath:(e,t,r)=>n.buildPath(e,t,r),queryNames:e=>t.routes.getQueryParams(e),pathNames:e=>t.routes.hasRoute(e)?t.routes.getUrlParams(e):void 0,admitsUndeclaredQuery:()=>t.options.get().queryParamsMode===`loose`,get reportDroppedQueryKey(){return n.validator?a:void 0},get reportUndeclaredParamKey(){return n.validator?i:void 0}}}function p(a,o){let s={logger:e.getInternals(a.router).logger,getOptions:()=>a.options.get(),hasRoute:e=>a.routes.hasRoute(e),getQueryParams:e=>a.routes.getQueryParams(e),getMetaForState:e=>a.routes.getMetaForState(e),getState:()=>a.state.get(),setState:e=>{a.state.set(e)},buildNavigateState:(t,s,c)=>{e.getInternals(a.router).validator?.routes.validateStateBuilderArgs(t,s,`navigate`);let l=n.canonicalize(o,t,s,c,{diagnoseUndeclared:!0});if(a.routes.getMetaForState(l.name)!==void 0)return i.materialize(l,{path:r.buildURL(l,o),skipFreeze:!0})},resolveDefault:()=>{let n=a.options.get(),r=e.getInternals(a.router),i=t.resolveOption(n.defaultRoute,e=>a.dependenciesStore.dependencies[e]),o=t.resolveOption(n.defaultParams,e=>a.dependenciesStore.dependencies[e]),s=t.resolveOption(n.defaultSearch,e=>a.dependenciesStore.dependencies[e]);return typeof n.defaultRoute==`function`&&r.validator?.options.validateResolvedDefaultRoute(i,r.routeGetStore()),{route:i,params:o,search:s}},startTransition:(e,t)=>{a.eventBus.sendNavigate(e,t)},cancelNavigation:e=>{a.eventBus.sendCancelIfPossible(a.state.get(),e)},sendTransitionDone:(e,t,n)=>{a.eventBus.sendComplete(e,t,n)},sendTransitionFail:(e,t,n)=>{a.eventBus.sendFail(e,t,n)},emitTransitionError:(e,t,n)=>{a.eventBus.sendFailSafe(e,t,n)},emitTransitionSuccess:(e,t,n)=>{a.eventBus.emitTransitionSuccess(e,t,n)},sendLeaveApprove:(e,t)=>{a.eventBus.sendLeaveApprove(e,t)},canNavigate:()=>a.eventBus.canBeginTransition(),getLifecycleFunctions:()=>a.routeLifecycle.getFunctions(),isActive:()=>a.router.isActive(),isTransitioning:()=>a.eventBus.isTransitioning(),clearCanDeactivate:e=>{a.routeLifecycle.clearCanDeactivate(e,`external`)},hasLeaveListeners:()=>a.eventBus.hasLeaveListeners(),hasPreCommitListeners:()=>a.eventBus.hasPreCommitListeners(),awaitLeaveListeners:(e,t,n)=>a.eventBus.awaitLeaveListeners(e,t,n)};a.navigation.setDependencies(s)}function m(e){e.lifecycle.setDependencies({getOptions:()=>e.options.get(),navigateToState:(t,n)=>e.navigation.navigateToState(t,n),navigateToNotFound:t=>e.navigation.navigateToNotFound(t),clearState:()=>{e.state.set(void 0)},matchPath:t=>e.routes.matchPath(t,e.options.get()),completeStart:()=>{e.eventBus.sendStarted()},isIdle:()=>e.eventBus.isIdle(),emitTransitionError:(t,n,r)=>{e.eventBus.sendFail(t,n,r)}})}function h(e,t){e.state.setDependencies({port:()=>t,getUrlParams:t=>e.routes.getUrlParams(t)})}exports.wireNamespaces=a;
|
|
2
2
|
//# sourceMappingURL=wireNamespaces.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wireNamespaces.js","names":["getInternals","normalizeParams","resolveOption"],"sources":["../../../src/wiring/wireNamespaces.ts"],"sourcesContent":["// packages/core/src/wiring/wireNamespaces.ts\n\nimport { normalizeParams } from \"../helpers\";\nimport { getInternals } from \"../internals\";\nimport { resolveOption } from \"../namespaces/OptionsNamespace\";\n\nimport type { NamespaceBag } from \"./types\";\nimport type { NavigationDependencies } from \"../namespaces/NavigationNamespace\";\nimport type { PluginsDependencies } from \"../namespaces/PluginsNamespace\";\nimport type { RouteLifecycleDependencies } from \"../namespaces/RouteLifecycleNamespace\";\nimport type { RouterLifecycleDependencies } from \"../namespaces/RouterLifecycleNamespace\";\nimport type { RoutesDependencies } from \"../namespaces/RoutesNamespace\";\nimport type { Router } from \"../Router\";\nimport type { DefaultDependencies, Params } from \"../types\";\nimport type { RouterValidator } from \"../types/RouterValidator\";\n\n/**\n * Compiles a guard/plugin factory against the router + a cached `getDependency`\n * accessor. One generic function serves both RouteLifecycle (`GuardFnFactory →\n * GuardFn`) and Plugins (`PluginFactory → Plugin`).\n */\ntype CompileFactory<Dependencies extends DefaultDependencies> = <T>(\n factory: (\n router: Router<Dependencies>,\n getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],\n ) => T,\n) => T;\n\n/**\n * Wires the inter-namespace dependencies of a freshly-constructed router.\n *\n * Replaces the former `RouterWiringBuilder` class + `wireRouter` director\n * (#1334): a single call-site with a fixed sequence and nothing to build is a\n * pack of procedures over a shared bag, not a builder — plain functions over a\n * `NamespaceBag` drop the triple-repeated field list and the builder instance.\n *\n * Call order is arbitrary (#1331): no `wire*` function runs user code or\n * eagerly reads another namespace's deps. (`wireLimits` is the one eager\n * *write* — it hands the frozen limits object to dependenciesStore/eventBus;\n * the rest only store deps-closures.) Initial-route guard factories are\n * flushed afterwards, from the constructor's `flushPendingGuards()` call.\n */\nexport function wireNamespaces<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n // One shared factory for both guard and plugin compilation (#1334); the\n // `getDependency` closure is allocated once here, not per compile call.\n const compileFactory = createCompileFactory(ns);\n\n // Shared by RouteLifecycle and Plugins — one allocation. Internals are\n // registered before wiring (#1331), so this never throws; returns null until\n // validation-plugin installs the validator.\n const getValidator = (): RouterValidator | null =>\n getInternals(ns.router).validator;\n\n wireLimits(ns);\n wireEventBus(ns, getValidator);\n wireRouteLifecycle(ns, compileFactory, getValidator);\n wireRoutes(ns);\n wirePlugins(ns, compileFactory, getValidator);\n wireNavigation(ns);\n wireRouterLifecycle(ns);\n wireState(ns);\n}\n\nfunction createCompileFactory<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): CompileFactory<Dependencies> {\n const { router, dependenciesStore } = ns;\n\n const getDependency = <K extends keyof Dependencies>(\n name: K,\n ): Dependencies[K] => dependenciesStore.dependencies[name] as Dependencies[K];\n\n return <T>(\n factory: (\n router: Router<Dependencies>,\n getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],\n ) => T,\n ): T => factory(router, getDependency);\n}\n\nfunction wireLimits<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n ns.dependenciesStore.limits = ns.limits;\n ns.eventBus.setLimits({\n maxListeners: ns.limits.maxListeners,\n warnListeners: ns.limits.warnListeners,\n });\n}\n\n/**\n * Hands EventBusNamespace the shared lazy validator accessor so `subscribe` /\n * `addEventListener` can run the opt-in listener-count threshold (#1188) — the\n * emitter-side parallel to the plugins / lifecycle / dependencies counters.\n */\nfunction wireEventBus<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n getValidator: () => RouterValidator | null,\n): void {\n ns.eventBus.setValidatorAccessor(getValidator);\n}\n\nfunction wireRouteLifecycle<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n compileFactory: CompileFactory<Dependencies>,\n getValidator: () => RouterValidator | null,\n): void {\n const deps: RouteLifecycleDependencies<Dependencies> = {\n logger: getInternals(ns.router).logger,\n compileFactory,\n getValidator,\n };\n\n ns.routeLifecycle.setDependencies(deps);\n}\n\nfunction wireRoutes<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n const deps: RoutesDependencies<Dependencies> = {\n logger: getInternals(ns.router).logger,\n addActivateGuard: (name, handler, precompiledFn) => {\n ns.routeLifecycle.addCanActivate(name, handler, true, precompiledFn);\n },\n addDeactivateGuard: (name, handler, precompiledFn) => {\n ns.routeLifecycle.addCanDeactivate(name, handler, true, precompiledFn);\n },\n compileGuard: (handler, methodName) =>\n ns.routeLifecycle.compileGuardFactory(handler, methodName),\n makeState: (name, params, path, meta) =>\n ns.state.makeState(name, params, path, meta),\n getState: () => ns.state.get(),\n areStatesEqual: (state1, state2, ignoreQueryParams) =>\n ns.state.areStatesEqual(state1, state2, ignoreQueryParams),\n getDependency: (name) =>\n ns.dependenciesStore.dependencies[name] as Dependencies[typeof name],\n forwardState: <P extends Params = Params>(name: string, params: P) => {\n const ctx = getInternals(ns.router);\n\n ctx.validator?.routes.validateStateBuilderArgs(\n name,\n params,\n \"forwardState\",\n );\n\n return ctx.forwardState(name, params);\n },\n };\n\n ns.routes.setDependencies(deps);\n ns.routes.setLifecycleNamespace(ns.routeLifecycle);\n}\n\nfunction wirePlugins<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n compileFactory: CompileFactory<Dependencies>,\n getValidator: () => RouterValidator | null,\n): void {\n const deps: PluginsDependencies<Dependencies> = {\n logger: getInternals(ns.router).logger,\n addEventListener: (eventName, cb) =>\n ns.eventBus.addEventListener(eventName, cb),\n canNavigate: () => ns.eventBus.canBeginTransition(),\n compileFactory,\n getValidator,\n };\n\n ns.plugins.setDependencies(deps);\n}\n\nfunction wireNavigation<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n const deps: NavigationDependencies = {\n logger: getInternals(ns.router).logger,\n getOptions: () => ns.options.get(),\n hasRoute: (name) => ns.routes.hasRoute(name),\n getState: () => ns.state.get(),\n setState: (state) => {\n ns.state.set(state);\n },\n buildNavigateState: (routeName, routeParams) => {\n const ctx = getInternals(ns.router);\n\n ctx.validator?.routes.validateStateBuilderArgs(\n routeName,\n routeParams,\n \"navigate\",\n );\n\n const forwarded = ctx.forwardState(routeName, routeParams);\n const name = forwarded.name;\n const params = normalizeParams(forwarded.params);\n const meta = ns.routes.getMetaForState(name);\n\n if (meta === undefined) {\n return;\n }\n\n const path = ctx.buildPath(name, params);\n\n return ns.state.makeState(name, params, path, meta, true);\n },\n resolveDefault: () => {\n const options = ns.options.get();\n const ctx = getInternals(ns.router);\n\n const route = resolveOption(\n options.defaultRoute,\n (name: string) =>\n ns.dependenciesStore.dependencies[name as keyof Dependencies],\n );\n const params = resolveOption(\n options.defaultParams,\n /* v8 ignore next -- @preserve: unreachable unless defaultParams is a callback that calls getDependency */\n (name: string) =>\n ns.dependenciesStore.dependencies[name as keyof Dependencies],\n );\n\n if (typeof options.defaultRoute === \"function\") {\n ctx.validator?.options.validateResolvedDefaultRoute(\n route,\n ctx.routeGetStore(),\n );\n }\n\n return { route, params };\n },\n startTransition: (toState, fromState) => {\n ns.eventBus.sendNavigate(toState, fromState);\n },\n cancelNavigation: (reason) => {\n ns.eventBus.sendCancelIfPossible(ns.state.get(), reason);\n },\n sendTransitionDone: (state, fromState, opts) => {\n ns.eventBus.sendComplete(state, fromState, opts);\n },\n sendTransitionFail: (toState, fromState, error) => {\n ns.eventBus.sendFail(toState, fromState, error);\n },\n emitTransitionError: (toState, fromState, error) => {\n ns.eventBus.sendFailSafe(toState, fromState, error);\n },\n emitTransitionSuccess: (toState, fromState, opts) => {\n ns.eventBus.emitTransitionSuccess(toState, fromState, opts);\n },\n sendLeaveApprove: (toState, fromState) => {\n ns.eventBus.sendLeaveApprove(toState, fromState);\n },\n canNavigate: () => ns.eventBus.canBeginTransition(),\n getLifecycleFunctions: () => ns.routeLifecycle.getFunctions(),\n isActive: () => ns.router.isActive(),\n isTransitioning: () => ns.eventBus.isTransitioning(),\n // Post-leave auto-cleanup unregisters only the EXTERNAL (component-managed)\n // guard; a route-config (definition) guard survives for re-entry (#1171).\n clearCanDeactivate: (name: string) => {\n ns.routeLifecycle.clearCanDeactivate(name, \"external\");\n },\n hasLeaveListeners: () => ns.eventBus.hasLeaveListeners(),\n hasPreCommitListeners: () => ns.eventBus.hasPreCommitListeners(),\n awaitLeaveListeners: (toState, fromState, signal) =>\n ns.eventBus.awaitLeaveListeners(toState, fromState, signal),\n };\n\n ns.navigation.setDependencies(deps);\n}\n\nfunction wireRouterLifecycle<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n const deps: RouterLifecycleDependencies = {\n getOptions: () => ns.options.get(),\n navigateToState: (state, opts) =>\n ns.navigation.navigateToState(state, opts),\n navigateToNotFound: (path) => ns.navigation.navigateToNotFound(path),\n clearState: () => {\n ns.state.set(undefined);\n },\n matchPath: (path) => ns.routes.matchPath(path, ns.options.get()),\n completeStart: () => {\n ns.eventBus.sendStarted();\n },\n isIdle: () => ns.eventBus.isIdle(),\n emitTransitionError: (toState, fromState, error) => {\n ns.eventBus.sendFail(toState, fromState, error);\n },\n };\n\n ns.lifecycle.setDependencies(deps);\n}\n\nfunction wireState<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n ns.state.setDependencies({\n getDefaultParams: () => ns.routes.getStore().config.defaultParams,\n buildPath: (name, params) => {\n const ctx = getInternals(ns.router);\n\n return ctx.buildPath(name, params);\n },\n getUrlParams: (name) => ns.routes.getUrlParams(name),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wireNamespaces.js","names":["getInternals","canonicalize","materialize","buildURL","resolveOption"],"sources":["../../../src/wiring/wireNamespaces.ts"],"sourcesContent":["// packages/core/src/wiring/wireNamespaces.ts\n\nimport { getInternals } from \"../internals\";\nimport { resolveOption } from \"../namespaces/OptionsNamespace\";\nimport { buildURL, canonicalize, materialize } from \"../pipeline\";\n\nimport type { NamespaceBag } from \"./types\";\nimport type { NavigationDependencies } from \"../namespaces/NavigationNamespace\";\nimport type { PluginsDependencies } from \"../namespaces/PluginsNamespace\";\nimport type { RouteLifecycleDependencies } from \"../namespaces/RouteLifecycleNamespace\";\nimport type { RouterLifecycleDependencies } from \"../namespaces/RouterLifecycleNamespace\";\nimport type { RoutesDependencies } from \"../namespaces/RoutesNamespace\";\nimport type { RouteResolver } from \"../pipeline\";\nimport type { Router } from \"../Router\";\nimport type { DefaultDependencies } from \"../types\";\nimport type { RouterValidator } from \"../types/RouterValidator\";\n\n/**\n * Compiles a guard/plugin factory against the router + a cached `getDependency`\n * accessor. One generic function serves both RouteLifecycle (`GuardFnFactory →\n * GuardFn`) and Plugins (`PluginFactory → Plugin`).\n */\ntype CompileFactory<Dependencies extends DefaultDependencies> = <T>(\n factory: (\n router: Router<Dependencies>,\n getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],\n ) => T,\n) => T;\n\n/**\n * Wires the inter-namespace dependencies of a freshly-constructed router.\n *\n * Replaces the former `RouterWiringBuilder` class + `wireRouter` director\n * (#1334): a single call-site with a fixed sequence and nothing to build is a\n * pack of procedures over a shared bag, not a builder — plain functions over a\n * `NamespaceBag` drop the triple-repeated field list and the builder instance.\n *\n * Call order is arbitrary (#1331): no `wire*` function runs user code or\n * eagerly reads another namespace's deps. (`wireLimits` is the one eager\n * *write* — it hands the frozen limits object to dependenciesStore/eventBus;\n * the rest only store deps-closures.) Initial-route guard factories are\n * flushed afterwards, from the constructor's `flushPendingGuards()` call.\n */\nexport function wireNamespaces<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n // One shared factory for both guard and plugin compilation (#1334); the\n // `getDependency` closure is allocated once here, not per compile call.\n const compileFactory = createCompileFactory(ns);\n\n // One port per router instance — allocated at wiring time, not per call.\n // Hoisted OUT of `wireNavigation` (Phase 2, step 2-2): `navigate` is no longer\n // its only consumer — the entry points migrating onto the pipeline live in\n // RoutesNamespace, which is wired first. Creation order is safe because the\n // resolver only captures `ns.router`'s internals (registered before wiring,\n // #1331) and the routes store (assigned in the namespace's constructor); every\n // member reads through `ns.*` at CALL time, so no wiring order is baked in.\n const port = createRouteResolver(ns);\n\n // Shared by RouteLifecycle and Plugins — one allocation. Internals are\n // registered before wiring (#1331), so this never throws; returns null until\n // validation-plugin installs the validator.\n const getValidator = (): RouterValidator | null =>\n getInternals(ns.router).validator;\n\n wireLimits(ns);\n wireEventBus(ns, getValidator);\n wireRouteLifecycle(ns, compileFactory, getValidator);\n wireRoutes(ns, port, getValidator);\n wirePlugins(ns, compileFactory, getValidator);\n wireNavigation(ns, port);\n wireRouterLifecycle(ns);\n wireState(ns, port);\n}\n\nfunction createCompileFactory<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): CompileFactory<Dependencies> {\n const { router, dependenciesStore } = ns;\n\n const getDependency = <K extends keyof Dependencies>(\n name: K,\n ): Dependencies[K] => dependenciesStore.dependencies[name] as Dependencies[K];\n\n return <T>(\n factory: (\n router: Router<Dependencies>,\n getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],\n ) => T,\n ): T => factory(router, getDependency);\n}\n\nfunction wireLimits<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n ns.dependenciesStore.limits = ns.limits;\n ns.eventBus.setLimits({\n maxListeners: ns.limits.maxListeners,\n warnListeners: ns.limits.warnListeners,\n });\n}\n\n/**\n * Hands EventBusNamespace the shared lazy validator accessor so `subscribe` /\n * `addEventListener` can run the opt-in listener-count threshold (#1188) — the\n * emitter-side parallel to the plugins / lifecycle / dependencies counters.\n */\nfunction wireEventBus<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n getValidator: () => RouterValidator | null,\n): void {\n ns.eventBus.setValidatorAccessor(getValidator);\n}\n\nfunction wireRouteLifecycle<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n compileFactory: CompileFactory<Dependencies>,\n getValidator: () => RouterValidator | null,\n): void {\n const deps: RouteLifecycleDependencies<Dependencies> = {\n logger: getInternals(ns.router).logger,\n compileFactory,\n getValidator,\n };\n\n ns.routeLifecycle.setDependencies(deps);\n}\n\nfunction wireRoutes<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n port: RouteResolver,\n getValidator: () => RouterValidator | null,\n): void {\n const deps: RoutesDependencies<Dependencies> = {\n logger: getInternals(ns.router).logger,\n getValidator,\n port,\n addActivateGuard: (name, handler, precompiledFn) => {\n ns.routeLifecycle.addCanActivate(name, handler, true, precompiledFn);\n },\n addDeactivateGuard: (name, handler, precompiledFn) => {\n ns.routeLifecycle.addCanDeactivate(name, handler, true, precompiledFn);\n },\n compileGuard: (handler, methodName) =>\n ns.routeLifecycle.compileGuardFactory(handler, methodName),\n getState: () => ns.state.get(),\n areStatesEqual: (state1, state2, ignoreQueryParams) =>\n ns.state.areStatesEqual(state1, state2, ignoreQueryParams),\n getDependency: (name) =>\n ns.dependenciesStore.dependencies[name] as Dependencies[typeof name],\n };\n\n ns.routes.setDependencies(deps);\n ns.routes.setLifecycleNamespace(ns.routeLifecycle);\n}\n\nfunction wirePlugins<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n compileFactory: CompileFactory<Dependencies>,\n getValidator: () => RouterValidator | null,\n): void {\n const deps: PluginsDependencies<Dependencies> = {\n logger: getInternals(ns.router).logger,\n addEventListener: (eventName, cb) =>\n ns.eventBus.addEventListener(eventName, cb),\n canNavigate: () => ns.eventBus.canBeginTransition(),\n compileFactory,\n getValidator,\n };\n\n ns.plugins.setDependencies(deps);\n}\n\n/**\n * The router's implementation of the pipeline's read-model (`RouteResolver`).\n *\n * ⚠ Both ends are wired to the INTERCEPTABLE primitives on purpose — see the\n * port's own docs. `resolveForward` is the `forwardState` seam (interceptors +\n * the centralized channel CHECK that replaced stage ②'s repair), so the seam\n * lives here, in the port implementation, and never inside the pipeline module.\n * `buildPath` is `ctx.buildPath`, because the navigate path prints its URL\n * through that interceptable — reaching for the engine's matcher instead would\n * silently drop `persistent-params`' `buildPath` interceptor from the navigate\n * path.\n */\nfunction createRouteResolver<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): RouteResolver {\n // Hoisted once per router, NOT per call: `navigate` is the hot path, and\n // `getInternals` is a WeakMap lookup. Safe because both references are stable\n // for the router's lifetime — internals are registered before wiring (#1331)\n // and the object is mutated in place, never swapped; `store` is `readonly` on\n // RoutesNamespace, assigned once in its constructor. ⚠ Only `store` itself is\n // stable: `add`/`replace`/`clear` DO swap `store.config`'s sub-maps wholesale\n // (`Object.assign(store.config, artifacts.config)`), so the accessors below\n // must keep re-reading `store.config.defaultParams` per call — hoisting the\n // sub-map would freeze the pre-mutation defaults. The interceptable methods\n // are stable closures that read the live interceptor map on every call, so\n // hoisting them keeps plugin registration fully dynamic.\n const ctx = getInternals(ns.router);\n const store = ns.routes.getStore();\n\n const reportUndeclaredParamKey = (routeName: string, key: string): void => {\n ctx.validator?.state.reportUndeclaredParamKey(routeName, key);\n };\n\n const reportDroppedQueryKey = (routeName: string, key: string): void => {\n ctx.validator?.state.reportDroppedQueryKey(routeName, key);\n };\n\n return {\n resolveForward: (name, params, search) =>\n ctx.forwardState(name, params, search),\n // `config.*` maps are null-prototype, so a missing entry reads as\n // `undefined` (never a proto value). O(1) lookup, no ancestor walk.\n defaultParams: (name) => store.config.defaultParams[name],\n defaultSearch: (name) => store.config.defaultSearch[name],\n buildPath: (name, params, search) => ctx.buildPath(name, params, search),\n queryNames: (name) => ns.routes.getQueryParams(name),\n // `undefined` for a route that does not exist (#1584) — `getUrlParams`\n // answers `[]` for that case and for a real route with no path slots alike,\n // and the diagnostic downstream cannot tell those apart. `hasRoute` is the\n // matcher's own predicate, so no second derivation of existence appears.\n pathNames: (name) =>\n ns.routes.hasRoute(name) ? ns.routes.getUrlParams(name) : undefined,\n // Read per call, not captured: `queryParamsMode` lives in the options\n // namespace, which `setOption` can rewrite after wiring.\n admitsUndeclaredQuery: () => ns.options.get().queryParamsMode === \"loose\",\n // A GETTER for the same reason as its sibling below — a plain closure is\n // always truthy, so the pipeline's `?.` never gated anything and bare core\n // paid #1584's `pathNames` existence lookup once per dropped key with no\n // sink behind it. Both sinks now report their absence honestly.\n get reportDroppedQueryKey() {\n return ctx.validator ? reportDroppedQueryKey : undefined;\n },\n // A GETTER, not a closure — the absence is the gate (#1579). The pipeline\n // reads `port.reportUndeclaredParamKey` and skips the whole caller-bag walk\n // when it is `undefined`; a plain closure is always truthy, so bare core\n // (`validator === null`, the repo default) walked the bag on every commit\n // anyway and the \"opt-in sink\" the design bought was never wired. The\n // validator is installed AFTER wiring, so this cannot be decided once at\n // construction — it has to be read per call, exactly like\n // `admitsUndeclaredQuery` above.\n get reportUndeclaredParamKey() {\n return ctx.validator ? reportUndeclaredParamKey : undefined;\n },\n };\n}\n\nfunction wireNavigation<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n port: RouteResolver,\n): void {\n const deps: NavigationDependencies = {\n logger: getInternals(ns.router).logger,\n getOptions: () => ns.options.get(),\n hasRoute: (name) => ns.routes.hasRoute(name),\n getQueryParams: (name) => ns.routes.getQueryParams(name),\n getMetaForState: (name) => ns.routes.getMetaForState(name),\n getState: () => ns.state.get(),\n setState: (state) => {\n ns.state.set(state);\n },\n buildNavigateState: (routeName, routeParams, routeSearch) => {\n const ctx = getInternals(ns.router);\n\n ctx.validator?.routes.validateStateBuilderArgs(\n routeName,\n routeParams,\n \"navigate\",\n );\n\n // The pipeline (RFC nav-pipeline, milestone 1): `canonicalize` is the sole\n // producer of the canonical intent (① forwardTo resolution through the\n // interceptor zone + ③ route defaults under the caller's value), and both\n // `buildURL` and `materialize` physically accept nothing else — so the URL\n // and the State can never derive from differently-merged channels.\n //\n // Channels stay correct at the seam (#1548/#1549): `routeSearch` (the\n // positional / descriptor form), a declared `?key` riding in the caller's\n // `params` bag, and persistent params injected by a plugin all land in the\n // query channel inside `port.resolveForward`, so one path serves both the\n // positional and the v1 single-bag forms. A colliding name\n // (`/items/:id?id`) keeps its path slot and query twin independent.\n const canonical = canonicalize(\n port,\n routeName,\n routeParams,\n routeSearch,\n {\n diagnoseUndeclared: true,\n },\n );\n const meta = ns.routes.getMetaForState(canonical.name);\n\n if (meta === undefined) {\n return;\n }\n\n // ⑤a then ⑤b: the URL is built from the merged channels (not the raw\n // args), so `state.path` stays in step with `state.search`. `skipFreeze`\n // defers the freeze of the state OBJECT for the transition pipeline; the\n // channels were already frozen at merge time.\n return materialize(canonical, {\n path: buildURL(canonical, port),\n skipFreeze: true,\n });\n },\n resolveDefault: () => {\n const options = ns.options.get();\n const ctx = getInternals(ns.router);\n\n const route = resolveOption(\n options.defaultRoute,\n (name: string) =>\n ns.dependenciesStore.dependencies[name as keyof Dependencies],\n );\n const params = resolveOption(\n options.defaultParams,\n /* v8 ignore next -- @preserve: unreachable unless defaultParams is a callback that calls getDependency */\n (name: string) =>\n ns.dependenciesStore.dependencies[name as keyof Dependencies],\n );\n const search = resolveOption(\n options.defaultSearch,\n /* v8 ignore next -- @preserve: unreachable unless defaultSearch is a callback that calls getDependency */\n (name: string) =>\n ns.dependenciesStore.dependencies[name as keyof Dependencies],\n );\n\n if (typeof options.defaultRoute === \"function\") {\n ctx.validator?.options.validateResolvedDefaultRoute(\n route,\n ctx.routeGetStore(),\n );\n }\n\n return { route, params, search };\n },\n startTransition: (toState, fromState) => {\n ns.eventBus.sendNavigate(toState, fromState);\n },\n cancelNavigation: (reason) => {\n ns.eventBus.sendCancelIfPossible(ns.state.get(), reason);\n },\n sendTransitionDone: (state, fromState, opts) => {\n ns.eventBus.sendComplete(state, fromState, opts);\n },\n sendTransitionFail: (toState, fromState, error) => {\n ns.eventBus.sendFail(toState, fromState, error);\n },\n emitTransitionError: (toState, fromState, error) => {\n ns.eventBus.sendFailSafe(toState, fromState, error);\n },\n emitTransitionSuccess: (toState, fromState, opts) => {\n ns.eventBus.emitTransitionSuccess(toState, fromState, opts);\n },\n sendLeaveApprove: (toState, fromState) => {\n ns.eventBus.sendLeaveApprove(toState, fromState);\n },\n canNavigate: () => ns.eventBus.canBeginTransition(),\n getLifecycleFunctions: () => ns.routeLifecycle.getFunctions(),\n isActive: () => ns.router.isActive(),\n isTransitioning: () => ns.eventBus.isTransitioning(),\n // Post-leave auto-cleanup unregisters only the EXTERNAL (component-managed)\n // guard; a route-config (definition) guard survives for re-entry (#1171).\n clearCanDeactivate: (name: string) => {\n ns.routeLifecycle.clearCanDeactivate(name, \"external\");\n },\n hasLeaveListeners: () => ns.eventBus.hasLeaveListeners(),\n hasPreCommitListeners: () => ns.eventBus.hasPreCommitListeners(),\n awaitLeaveListeners: (toState, fromState, signal) =>\n ns.eventBus.awaitLeaveListeners(toState, fromState, signal),\n };\n\n ns.navigation.setDependencies(deps);\n}\n\nfunction wireRouterLifecycle<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n): void {\n const deps: RouterLifecycleDependencies = {\n getOptions: () => ns.options.get(),\n navigateToState: (state, opts) =>\n ns.navigation.navigateToState(state, opts),\n navigateToNotFound: (path) => ns.navigation.navigateToNotFound(path),\n clearState: () => {\n ns.state.set(undefined);\n },\n matchPath: (path) => ns.routes.matchPath(path, ns.options.get()),\n completeStart: () => {\n ns.eventBus.sendStarted();\n },\n isIdle: () => ns.eventBus.isIdle(),\n emitTransitionError: (toState, fromState, error) => {\n ns.eventBus.sendFail(toState, fromState, error);\n },\n };\n\n ns.lifecycle.setDependencies(deps);\n}\n\nfunction wireState<Dependencies extends DefaultDependencies>(\n ns: NamespaceBag<Dependencies>,\n port: RouteResolver,\n): void {\n ns.state.setDependencies({\n // `makeState` is `canonicalize`'s literal form since Phase 4, so the port is\n // all it needs. The seven members that used to live here — both default\n // maps, `getQueryParams`, `hasRoute`, `admitsUndeclaredQuery`,\n // `getDropReporter`, `buildPath` — existed only to feed a second copy of\n // stage ③ and the mode gate, and left with it.\n port: () => port,\n getUrlParams: (name) => ns.routes.getUrlParams(name),\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{c as e,d as t,f as n,h as r,l as i,m as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"./buildParamMeta-D8td47fL.mjs";function p(e,t,n){if(e===void 0||n.length===0)return e;let r,i=!1;for(let[a,o]of Object.entries(e)){if(Object.hasOwn(t,a)&&t[a]!==void 0&&n.includes(a)){i=!0;continue}r??={},r[a]=o}return i?r:e}function m(e,t,n){for(let[r,i]of Object.entries(e))c(n,r,i,t(r),"this route's `defaultParams`","Move it to `defaultSearch`")}const h=Object.freeze({ROUTER_NOT_STARTED:`NOT_STARTED`,NO_START_PATH_OR_STATE:`NO_START_PATH_OR_STATE`,ROUTER_ALREADY_STARTED:`ALREADY_STARTED`,ROUTE_NOT_FOUND:`ROUTE_NOT_FOUND`,SAME_STATES:`SAME_STATES`,CANNOT_DEACTIVATE:`CANNOT_DEACTIVATE`,CANNOT_ACTIVATE:`CANNOT_ACTIVATE`,TRANSITION_ERR:`TRANSITION_ERR`,TRANSITION_CANCELLED:`CANCELLED`,ROUTER_DISPOSED:`DISPOSED`,PLUGIN_CONFLICT:`PLUGIN_CONFLICT`,CONTEXT_NAMESPACE_ALREADY_CLAIMED:`CONTEXT_NAMESPACE_ALREADY_CLAIMED`,REENTRANT_NAVIGATION:`REENTRANT_NAVIGATION`,REENTRANT_TREE_MUTATION:`REENTRANT_TREE_MUTATION`,WRONG_CHANNEL:`WRONG_CHANNEL`}),ee=`@@router/UNKNOWN_ROUTE`,g={UNKNOWN_ROUTE:ee},_={ROUTER_START:`onStart`,ROUTER_STOP:`onStop`,TRANSITION_START:`onTransitionStart`,TRANSITION_LEAVE_APPROVE:`onTransitionLeaveApprove`,TRANSITION_CANCEL:`onTransitionCancel`,TRANSITION_SUCCESS:`onTransitionSuccess`,TRANSITION_ERROR:`onTransitionError`},v={ROUTER_START:`$start`,ROUTER_STOP:`$stop`,TRANSITION_START:`$$start`,TRANSITION_LEAVE_APPROVE:`$$leaveApprove`,TRANSITION_CANCEL:`$$cancel`,TRANSITION_SUCCESS:`$$success`,TRANSITION_ERROR:`$$error`},y={maxDependencies:100,maxPlugins:50,maxListeners:1e4,warnListeners:1e3,maxLifecycleHandlers:200},b=Object.freeze({}),x=Object.freeze({}),te=Object.freeze({deactivated:Object.freeze([]),activated:Object.freeze([]),intersection:``}),ne=Object.freeze({phase:`activating`,reason:`success`,segments:te});function re(e,t,n){let r,i=!1;for(let[a,o]of Object.entries(e))t.includes(a)?(r??={},r[a]=o):(i=!0,n?.(a));return i?Object.freeze(r??x):e}function ie(e){if(!e||typeof e!=`object`||e.constructor!==Object)throw TypeError(`dependencies must be a plain object`);for(let t in e)if(Object.getOwnPropertyDescriptor(e,t)?.get)throw TypeError(`dependencies cannot contain getters: "${t}"`)}function S(e,t){for(let n of e){let e=n;if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`route must be a non-array object`);t?.routes.guardRouteCallbacks(n),t?.routes.guardNoAsyncCallbacks(n);let r=n.children;r&&S(r,t)}}const ae=new Set([`all`,`warn-error`,`error-only`,`none`]);function oe(e){return typeof e==`string`&&ae.has(e)}function se(e){return typeof e==`string`?`"${e}"`:typeof e==`object`?JSON.stringify(e):String(e)}function ce(e){if(typeof e!=`object`)throw TypeError(`Logger config must be an object`);let t=e;for(let e of Object.keys(t))if(e!==`level`&&e!==`callback`&&e!==`callbackIgnoresLevel`)throw TypeError(`Unknown logger config property: "${e}"`);if(`level`in t&&t.level!==void 0&&!oe(t.level))throw TypeError(`Invalid logger level: ${se(t.level)}. Expected: "all" | "warn-error" | "error-only" | "none"`);if(`callback`in t&&t.callback!==void 0&&typeof t.callback!=`function`)throw TypeError(`Logger callback must be a function, got ${typeof t.callback}`);if(`callbackIgnoresLevel`in t&&t.callbackIgnoresLevel!==void 0&&typeof t.callbackIgnoresLevel!=`boolean`)throw TypeError(`Logger callbackIgnoresLevel must be a boolean, got ${typeof t.callbackIgnoresLevel}`)}function C(e,t){if(e===void 0)return le(t);let n={};for(let t in e)Object.hasOwn(e,t)&&e[t]!==void 0&&(n[t]=e[t]);if(t!==void 0)for(let e in t)Object.hasOwn(t,e)&&t[e]!==void 0&&(n[e]=t[e]);return n}function le(e){if(e===void 0)return;let t;for(let n in e)Object.hasOwn(e,n)&&e[n]===void 0&&(t??={...e},delete t[n]);return t??e}const ue=new Set([`string`,`number`,`boolean`]);function de(e){return ue.has(typeof e)}function w(e,t){if(e===t)return!0;if(Array.isArray(e)){if(!Array.isArray(t))return e.length===1&&w(e[0],t);if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!w(e[n],t[n]))return!1;return!0}return Array.isArray(t)?t.length===1&&w(e,t[0]):de(e)&&de(t)&&String(e)===String(t)}function fe(e){return Object.freeze(e)}function pe(e,t,n,r=!1){if(e!==void 0)return Object.freeze(C(e,t));if(t===void 0||t===n)return n;if(r)return Object.freeze(t);let i=C(void 0,t);return Object.freeze(i===t?{...t}:i)}function me(e){if(e===void 0)return e;let t;for(let n in e){if(!Object.hasOwn(e,n))continue;let r=e[n];r!==void 0&&(t??={},t[n]=r)}return t??b}function he(e={}){return{...y,...e}}function ge(e={}){let t=Object.create(null);for(let n in e)e[n]!==void 0&&(t[n]=e[n]);return{dependencies:t,limits:y}}function T(e,t){let n=e.path,r=n.startsWith(`~`),i=r?n.slice(1):n,a=i!==``&&!i.startsWith(`/`)&&!i.startsWith(`?`)?`/${i}`:i,o={name:e.name,path:a,absolute:r,children:[],parent:t};if(e.children)for(let t of e.children){let e=T(t,o);o.children.push(e)}return o}function _e(e,t,n){let r=T({name:e,path:t},null);for(let e of n){let t=T(e,r);r.children.push(t)}return r}const ve=/[^\w!$'()*+,.:;|~-]/gu,ye=/[^\w!$'()*+,.:;|~-]/u,be=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,E=e=>t=>{try{return e(t)}catch{return e(t.replaceAll(be,`�`))}},xe=E(e=>e.replaceAll(ve,e=>encodeURIComponent(e))),Se={default:e=>ye.test(e)?xe(e):e,uri:E(encodeURI),uriComponent:E(encodeURIComponent),none:e=>e},Ce={default:decodeURIComponent,uri:decodeURI,uriComponent:decodeURIComponent,none:e=>e},we=(e,t)=>{let n=Se[t],r=String(e).split(`/`),i=n(r[0]);for(let e=1;e<r.length;e++)i+=`/`+n(r[e]);return i},Te=Object.freeze(Object.create(null));function D(){return{staticChildren:Te,hasChildren:!1,paramChild:void 0,splatChild:void 0,route:void 0,slashChildRoute:void 0}}function O(e){return e.length>1&&e.endsWith(`/`)?e.slice(0,-1):e}function Ee(e,t){return e===``?t:t===``?e:e+t}function De(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Oe(e){let t=0;for(;t<e.length;)if(e.codePointAt(t)===37){if(t+2>=e.length)return!1;let n=e.codePointAt(t+1)??0,r=e.codePointAt(t+2)??0;if(!De(n)||!De(r))return!1;t+=3}else t++;return!0}const ke=Object.freeze([]),Ae=Object.freeze(new Set),je=Object.freeze([]),Me=Object.freeze({}),Ne=Object.freeze({}),Pe=Object.freeze({});function Fe(e,t,n){let r=t.has(e.name);return{paramName:e.name,encoder:r?e=>we(e,n):Se[n]}}function Ie(e,t,n,r){let i=new Set(r),a=new Set;for(let e of t){for(let t of e.paramMeta.urlParams)i.add(t);for(let t of e.paramMeta.spatParams)a.add(t)}if(i.size===0)return{buildStaticParts:[e],buildParamSlots:je};let o=[],c=[],l=``,d=u(e),f=d.length-1;for(let[e,t]of d.entries()){let r=s(t);if(!(!(`error`in r)&&r.kind===`splat`&&e!==f)){if(e>0&&(l+=`/`),`error`in r||r.kind===`static`){l+=t;continue}o.push(l),l=``,c.push(Fe(r,a,n))}}return o.push(l),{buildStaticParts:o,buildParamSlots:c}}function Le(e,t,n){throw Error(`[SegmentMatcher.registerTree] Parameter name conflict at the same path position: '${n}${e}' and '${n}${t}'. A parametric URL segment binds to a single name across every route that shares that position — the value cannot be captured under two names. Rename one so both routes agree (e.g. use '${n}${e}' in both).`)}function Re(){throw Error(`[SegmentMatcher.registerTree] Empty parameter name: a parameter marker (':' or '*') must be followed by a name (e.g. ':id', '*rest'). A name-less marker, or a trailing '?' with no parameter name, would capture under an empty key at match but emit a literal at build — the two disagree, so it is rejected.`)}function ze(e){throw Error(`[SegmentMatcher.registerTree] Fused parameter marker in segment "${e}": a ':'/'*' marker must begin a segment (e.g. 'a/:b', not 'a:b'). build extracts it as a param while the trie treats the segment as a literal — the two disagree.`)}function Be(e){throw Error(`[SegmentMatcher.registerTree] Trailing parameter marker in segment "${e}": a param name cannot end in a bare ':' or '*' (e.g. ':y*' — the name is 'y' plus a stray marker). build/meta would capture the marker into the name while the gate rejects it as name-less — the two disagree, so it is rejected.`)}function Ve(e){throw Error(`[SegmentMatcher.registerTree] Optional params are not supported: "${e}" — declare two sibling routes instead (one with the segment, one without). The route hierarchy already expresses optionality.`)}function He(e){throw Error(`[SegmentMatcher.registerTree] Regex constraints are not supported: "<"/">" are reserved in path segments ("${e}"). Match the segment as a plain string and validate the value in a guard (canActivate) or app code.`)}function Ue(e){throw Error(`[SegmentMatcher.registerTree] Non-ASCII static segment "${e}": match rejects non-ASCII input and compares static keys raw, so this route would never match. Percent-encode it (e.g. "/caf%C3%A9") or use a param.`)}function We(e,t){switch(e){case`name-less`:return Re();case`trailing-marker`:return Be(t);case`fused-marker`:return ze(t);case`optional-removed`:return Ve(t);case`constraint-removed`:return He(t)}}function Ge(e,t){let n=new Set,r=``;for(let e of t){if(n.has(e)){r=e;break}n.add(e)}throw Error(`[SegmentMatcher.registerTree] Duplicate parameter name ':${r}' in route "${e}": a param name must be unique within a route — two positions cannot both bind ':${r}' (the second silently overwrites the first). Rename one.`)}function Ke(e,t){throw Error(`[SegmentMatcher.registerTree] Invalid query-param declaration "${t}" in route "${e}": a query-param name cannot contain '<' or '>' — it would never round-trip. Rename the query param.`)}function qe(e,t){throw Error(`[SegmentMatcher.registerTree] Duplicate route path: routes "${e}" and "${t}" resolve to the same URL. The later registration would silently shadow the earlier (its deep link would resolve to the other route). Give them distinct paths.`)}function Je(e,t){throw Error(`[SegmentMatcher.registerTree] Index route "${e}" (path "/") under the splat parent "${t}" is not supported: the index sits on the splat node, which the wildcard match never reaches, so it is unreachable. Give the index a distinct path, or make the parent static.`)}function Ye(e){let t=s(e);return(`error`in t||t.kind===`static`)&&Re(),t.name}function Xe(e,t){return e.paramChild?e.paramChild.name!==t&&Le(e.paramChild.name,t,`:`):e.paramChild={node:D(),name:t},e.paramChild.node}function Ze(e,t){return e.splatChild?e.splatChild.name!==t&&Le(e.splatChild.name,t,`*`):e.splatChild={node:D(),name:t},e.splatChild.node}function Qe(e,t){e.route!==void 0&&e.route!==t&&qe(e.route.name,t.name),e.route=t}function $e(e){for(let t=0;t<e.length;t++)if(e.charCodeAt(t)>=128)return!0;return!1}function et(e,t,n){let r=O(n);if(r===`/`){Qe(e.root,t);return}tt(e,e.root,r,1,t)}function tt(e,t,n,r,i){let a=n.length;for(;r<=a;){let i=n.indexOf(`/`,r),o=i===-1?a:i,s=n.slice(r,o);t=at(e,t,s),r=o+1}Qe(t,i)}function nt(e,t,n){n.slice(n.lastIndexOf(`/`)+1).startsWith(`*`)&&Je(t.name,n);let r=rt(e,n);r.slashChildRoute=t}function rt(e,t){return it(e,e.root,t)}function it(e,t,n){let r=O(n);if(r===`/`||r===``)return t;let i=t,a=1,o=r.length;for(;a<=o;){let t=r.indexOf(`/`,a),n=t===-1?o:t;if(n<=a)break;let s=r.slice(a,n);i=at(e,i,s),a=n+1}return i}function at(e,t,n){if(n.startsWith(`*`)){let e=Ze(t,Ye(n));return t.hasChildren=!0,e}if(n.startsWith(`:`)){let e=Xe(t,Ye(n));return t.hasChildren=!0,e}$e(n)&&Ue(n);let r=e.options.caseSensitive?n:n.toLowerCase();return r in t.staticChildren||(t.staticChildren===Te&&(t.staticChildren=Object.create(null)),t.staticChildren[r]=D(),t.hasChildren=!0),t.staticChildren[r]}function ot(e,t,n,r,i){let a=t.fullName===``;a||r.push(t);let o=t.absolute,c=t.paramMeta===d?t.path:t.paramMeta.pathPattern,l=o&&c.startsWith(`~`)?c.slice(1):c,f=o?l:c;for(let e of u(f)){let t=s(e);`error`in t&&We(t.error,e)}let p=f,m=o?p:Ee(n,p),h=a?i:st(e,t,m,o?``:n,r,i);for(let n of t.children.values())ot(e,n,m,r,h);a||r.pop()}function st(e,t,n,r,i,a){let o=ft(n,r),s=Object.freeze([...i]),c=ct(s),l=O(n),u=pt(e.rootQueryParams,i),{buildStaticParts:d,buildParamSlots:f}=Ie(o?O(r):l,o?i.slice(0,-1):i,e.options.urlParamsEncoding,e.rootUrlParams),p=f.map(e=>e.paramName),m=p.length===0?Ae:new Set(p);m.size!==p.length&&Ge(t.fullName,p),mt(t.fullName,u);let h={name:t.fullName,parent:a,matchSegments:s,meta:c,declaredQueryParams:u,declaredQueryParamsSet:u.length===0?Ae:new Set(u),hasTrailingSlash:n.length>1&&n.endsWith(`/`),buildStaticParts:d,buildParamSlots:f,buildParamNamesSet:m,cachedResult:void 0};return t.paramMeta.urlParams.length===0&&(h.cachedResult=Object.freeze({segments:h.matchSegments,params:Me,search:Ne,meta:h.meta})),e.routesByName.set(t.fullName,h),o?ut(e,h,r):dt(e,h,n,l,t),h}function ct(e){let t;for(let n of e)lt(n.paramTypeMap)&&(t??={},t[n.fullName]=n.paramTypeMap);return t===void 0?Pe:Object.freeze(t)}function lt(e){for(let t in e)if(Object.hasOwn(e,t))return!0;return!1}function ut(e,t,n){nt(e,t,n);let r=O(n),i=e.options.caseSensitive?r:r.toLowerCase();e.staticCache.has(i)&&e.staticCache.set(i,t)}function dt(e,t,n,r,i){if(et(e,t,n),i.paramMeta.urlParams.length===0){let n=e.options.caseSensitive?r:r.toLowerCase();e.staticCache.set(n,t)}}function ft(e,t){return O(e)===O(t)}function pt(e,t){let n=[];e.length>0&&n.push(...e);for(let e of t)e.paramMeta.queryParams.length>0&&n.push(...e.paramMeta.queryParams);return n.length===0?ke:n}function mt(e,t){for(let n of t)o.test(n)&&Ke(e,n)}function ht(e){return typeof e==`string`?e:typeof e==`object`?JSON.stringify(e):String(e)}const gt=Object.freeze({});var _t=class{get options(){return this.#e}#e;#t=D();#n=new Map;#r=new Map;#i={cleanPath:``,normalized:``,queryString:void 0};#a=[];#o=``;#s;#c;constructor(e){this.#e={caseSensitive:e.caseSensitive??!0,strictTrailingSlash:e.strictTrailingSlash??!1,strictQueryParams:e.strictQueryParams??!1,urlParamsEncoding:e.urlParamsEncoding??`default`,parseQueryString:e.parseQueryString,buildQueryString:e.buildQueryString},this.#s=this.#e.caseSensitive,this.#c=this.#e.urlParamsEncoding===`none`?null:Ce[this.#e.urlParamsEncoding]}registerTree(e){this.#a=e.paramMeta.queryParams,ot({root:this.#t,options:this.#e,routesByName:this.#n,staticCache:this.#r,rootQueryParams:this.#a,rootUrlParams:e.paramMeta.urlParams},e,``,[],null)}match(e){if(!this.#f(e))return;let{cleanPath:t,normalized:n,queryString:r}=this.#i,i=this.#s?n:n.toLowerCase(),a=this.#r.get(i);if(a)return this.#e.strictTrailingSlash&&!this.#g(t,a)?void 0:r===void 0&&a.cachedResult?a.cachedResult:this.#m(a,{},r);let o={},s=this.#_(n,o);if(s&&!(this.#e.strictTrailingSlash&&!this.#g(t,s))&&this.#b(o))return this.#m(s,o,r)}buildPath(e,t,n,r){let i=this.#n.get(e);if(!i)throw Error(`[SegmentMatcher.buildPath] '${e}' is not defined`);let a=this.#l(i,t),o=this.#u(a,r?.trailingSlash),s=this.#d(i,n??t,r?.queryParamsMode);return o+(s?`?${s}`:``)}getSegmentsByName(e){return this.#n.get(e)?.matchSegments}getMetaByName(e){return this.#n.get(e)?.meta}getDeclaredQueryParams(e){return this.#n.get(e)?.declaredQueryParams}hasRoute(e){return this.#n.has(e)}#l(e,t){let n=e.buildStaticParts,r=e.buildParamSlots;if(r.length===0)return n[0];let i=n[0];for(let[e,a]of r.entries()){let r=t?.[a.paramName];if(r==null)throw Error(`[SegmentMatcher.buildPath] Missing required param '${a.paramName}'`);if(r===``)throw Error(`[SegmentMatcher.buildPath] Missing required param '${a.paramName}' (empty string)`);let o=a.encoder(ht(r));i+=o+n[e+1]}return i}#u(e,t){return t===`always`&&!e.endsWith(`/`)?`${e}/`:t===`never`&&e!==`/`&&e.endsWith(`/`)?e.slice(0,-1):e}#d(e,t,n){if(!t||e.declaredQueryParams.length===0&&n!==`loose`)return``;let r={},i=!1;for(let n of e.declaredQueryParams)n in t&&(r[n]=t[n],i=!0);if(n===`loose`)for(let n in t)!Object.hasOwn(t,n)||e.declaredQueryParamsSet.has(n)||e.buildParamNamesSet.has(n)||(r[n]=t[n],i=!0);return i?this.#e.buildQueryString(r):``}#f(e){if(e===``&&(e=`/`),e.codePointAt(0)!==47)return!1;let t=this.#p(e);if(t===-2)return!1;t===-3&&(e=this.#o);let n=t>=0?e.slice(0,t):e,r=t>=0?e.slice(t+1):void 0;if(r!==void 0){let e=r.indexOf(`#`);e!==-1&&(r=r.slice(0,e))}let i=O(n);return this.#i.cleanPath=n,this.#i.normalized=i,this.#i.queryString=r,!0}#p(e){let t=!1;for(let n=0;n<e.length;n++){let r=e.codePointAt(n);if(r===35)return this.#o=e.slice(0,n),-3;if(r===63)return n;if(r>=128)return-2;if(r===47){if(t)return-2;t=!0}else t=!1}return-1}#m(e,t,n){let r=gt;if(n!==void 0){let t=this.#h(e,n);if(t===void 0)return;r=t}return{segments:e.matchSegments,params:t,search:r,meta:e.meta}}#h(e,t){let n;try{n=this.#e.parseQueryString(t)}catch{return}if(this.#e.strictQueryParams){let t=e.declaredQueryParamsSet;for(let e in n)if(!t.has(e))return}return n}#g(e,t){return(e.length>1&&e.endsWith(`/`))===t.hasTrailingSlash}#_(e,t){return e.length===1?this.#t.slashChildRoute??this.#t.route:this.#v(this.#t,e,1,t)}#v(e,t,n,r){let i=e,a=t.length,o=this.#s;for(;n<=a;){let e=t.indexOf(`/`,n),s=e===-1?a:e,c=t.slice(n,s),l=o?c:c.toLowerCase(),u;if(l in i.staticChildren)u=i.staticChildren[l];else if(i.paramChild){let e=i.paramChild;if(i.splatChild!==void 0){let a={[e.name]:c},o=this.#v(e.node,t,s+1,a);return o===void 0?this.#y(i.splatChild,t,n,r):(Object.assign(r,a),o)}u=e.node,r[e.name]=c}else if(i.splatChild)return this.#y(i.splatChild,t,n,r);else return;i=u,n=s+1}return i.slashChildRoute??i.route}#y(e,t,n,r){let i=e.node;if(!i.hasChildren)return r[e.name]=t.slice(n),i.route;let a={},o=this.#v(i,t,n,a);return o?(Object.assign(r,a),o):(r[e.name]=t.slice(n),i.route)}#b(e){let t=this.#c;if(!t)return!0;for(let n in e){let r=e[n];if(r.includes(`%`)){if(!Oe(r))return!1;try{e[n]=t(r)}catch{return!1}}}return!0}};const vt=Object.freeze(new Map),yt=Object.freeze([]);function bt(e){return e.parent?.name?`${e.parent.fullName}.${e.name}`:e.name}function xt(e){let t=new Map;for(let n of e)t.set(n.name,n);return t}function St(e,t){let n=[],r=[];for(let i of e){let e=Ct(i,t);n.push(e),e.absolute||r.push(e)}return{childrenMap:xt(n),nonAbsoluteChildren:r}}function Ct(e,t){let n=l(e.path),r=n.urlParams.length===0&&n.queryParams.length===0&&n.spatParams.length===0&&n.pathPattern===e.path?d:n,i=r.paramTypeMap,a={name:e.name,path:e.path,absolute:e.absolute,parent:t,children:void 0,paramMeta:r,nonAbsoluteChildren:void 0,fullName:``,paramTypeMap:i};if(a.fullName=bt(a),e.children.length===0)a.children=vt,a.nonAbsoluteChildren=yt;else{let{childrenMap:t,nonAbsoluteChildren:n}=St(e.children,a);a.children=t,a.nonAbsoluteChildren=n,Object.freeze(a.nonAbsoluteChildren),Object.freeze(a.children)}return Object.freeze(i),Object.freeze(r.urlParams),Object.freeze(r.queryParams),Object.freeze(r.spatParams),Object.freeze(r),Object.freeze(a),a}function wt(e){return Ct(e,null)}function Tt(e,t,n){return wt(_e(e,t,n))}function Et(e){let t=e.absolute?`~${e.path}`:e.path,n={name:e.name,path:t};return e.children.size>0&&(n.children=Array.from(e.children.values(),Et)),n}function Dt(e){return Array.from(e.children.values(),Et)}const Ot=e=>{let t=e.indexOf(`%`),n=e.indexOf(`+`);if(t===-1&&n===-1)return e;let r=n===-1?e:e.replaceAll(`+`,` `);return t===-1?r:decodeURIComponent(r)},kt=(e,t)=>{if(e===void 0)return t.boolean.decodeUndefined();let n=t.boolean.decodeRaw(e);if(n!==null)return n;let r=Ot(e),i=t.number.decode(r);return i===null?t.boolean.decodeValue(r):i},At=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,jt=e=>{try{return encodeURIComponent(e)}catch(t){if(!(t instanceof URIError))throw t;return encodeURIComponent(String(e).replaceAll(At,`�`))}},k=e=>{let t=typeof e;if(t!==`string`&&t!==`number`&&t!==`boolean`)throw TypeError(`[search-params] Array element must be a string, number, or boolean — received ${t}`);return jt(e)},Mt=(e,t,n,r)=>{let i=`${e}${n}`,a=[];for(let e of t)if(e===null){let e=r.encode(i);e&&a.push(e)}else a.push(`${i}=${k(e)}`);return a.join(`&`)},Nt={none:{encodeArray:(e,t,n)=>Mt(e,t,``,n)},brackets:{encodeArray:(e,t,n)=>Mt(e,t,`[]`,n)},index:{encodeArray:(e,t,n)=>{let r=[];for(let[i,a]of t.entries()){let t=`${e}[${i}]`;if(a===null){let e=n.encode(t);e&&r.push(e)}else r.push(`${t}=${k(a)}`)}return r.join(`&`)},indexed:!0},comma:{encodeArray:(e,t)=>{let n=[];for(let e of t)e!==null&&n.push(k(e));return n.length===0?``:`${e}=${n.join(`,`)}`},decodeValue:e=>e.includes(`,`)?e.split(`,`):null}},Pt={none:{encode:(e,t)=>`${e}=${t}`,decodeUndefined:()=>null,decodeRaw:()=>null,decodeValue:e=>e},auto:{encode:(e,t)=>`${e}=${t}`,decodeUndefined:()=>null,decodeRaw:e=>e===`true`||e!==`false`&&null,decodeValue:e=>e},"empty-true":{encode:(e,t)=>t?e:`${e}=false`,decodeUndefined:()=>!0,decodeRaw:e=>e===`true`||e!==`false`&&null,decodeValue:e=>e}},Ft={default:{encode:e=>e},hidden:{encode:()=>``}},It={auto:{decode:e=>{let t=e.length;if(t===0)return null;let n=+(e.codePointAt(0)===45);if(n===t||t-n>1&&e.codePointAt(n)===48&&e.codePointAt(n+1)!==46)return null;let r=!1;for(let i=n;i<t;i++){let a=e.codePointAt(i);if(!(a!==void 0&&a>=48&&a<=57)){if(a===46&&!r&&i!==n&&i!==t-1){r=!0;continue}return null}}let i=Number(e);return String(i)!==e||!Number.isSafeInteger(i)&&!r?null:i}},none:{decode:()=>null}},A=(e,t,n,r)=>{if(e===void 0)throw TypeError(`[search-params] Unknown ${t} "${n}" — expected ${r}`);return e},Lt=(e,t,n,r)=>({boolean:A(Pt[t],`booleanFormat`,t,`"none" | "auto" | "empty-true"`),null:A(Ft[n],`nullFormat`,n,`"default" | "hidden"`),number:A(It[r],`numberFormat`,r,`"none" | "auto"`),array:A(Nt[e],`arrayFormat`,e,`"none" | "brackets" | "index" | "comma"`)}),Rt={boolean:Pt.auto,null:Ft.default,number:It.auto,array:Nt.none},j={arrayFormat:`none`,booleanFormat:`auto`,nullFormat:`default`,numberFormat:`auto`},zt={...j,strategies:Rt},Bt=e=>{if(!e||e.arrayFormat===void 0&&e.booleanFormat===void 0&&e.nullFormat===void 0&&e.numberFormat===void 0)return zt;let t=e.arrayFormat??j.arrayFormat,n=e.booleanFormat??j.booleanFormat,r=e.nullFormat??j.nullFormat,i=e.numberFormat??j.numberFormat;return{arrayFormat:t,booleanFormat:n,nullFormat:r,numberFormat:i,strategies:Lt(t,n,r,i)}},M=e=>jt(e),Vt=(e,t,n)=>{let r=M(e);switch(typeof t){case`string`:case`number`:return`${r}=${M(t)}`;case`boolean`:return n.strategies.boolean.encode(r,t);case`object`:return t===null?n.strategies.null.encode(r):Array.isArray(t)?n.strategies.array.encodeArray(r,t,n.strategies.null):`${r}=${M(t)}`;default:return`${r}=${M(t)}`}};function N(e,t,n){t===`__proto__`?Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0}):e[t]=n}function Ht(e,t,n,r){if(!Object.hasOwn(e,t)){N(e,t,r?[n]:n);return}let i=e[t];Array.isArray(i)?i.push(n):N(e,t,[i,n])}function Ut(e,t,n,r,i){return kt(r?e.slice(t+1,n):void 0,i)}function Wt(e,t,n){let r=t+1,i=0,a=!1;for(;r<n;){let t=e.codePointAt(r);if(t===93)return a?i:null;if(t!==void 0&&t>=48&&t<=57){i=i*10+(t-48),a=!0,r++;continue}return null}return null}function Gt(e,t,n){let{searchPart:r,nameEnd:i,nameSourceEnd:a,eqPos:o,end:s,hasValue:c,decodedName:l}=e,u=Wt(r,i,a);if(u===null)return!1;let d=Ut(r,o,s,c,t),f=n.get(l);return f===void 0?n.set(l,[[u,d]]):f.push([u,d]),!0}function Kt(e,t,n,r,i,a,o){let s=a!==-1&&a<n,c=s?a:n,l=c,u=!1;for(let n=t;n<c;n++)if(e.codePointAt(n)===91){l=n,u=!0;break}let d=Ot(e.slice(t,l));if(!(o!==void 0&&u&&Gt({searchPart:e,nameEnd:l,nameSourceEnd:c,eqPos:a,end:n,hasValue:s,decodedName:d},i,o))){if(!u&&s&&i.array.decodeValue){let t=e.slice(a+1,n),o=i.array.decodeValue(t);if(o){for(let e of o)Ht(r,d,kt(e,i),!0);return}}Ht(r,d,Ut(e,a,n,s,i),u)}}const qt=(e,t)=>{if(e===``||e===`?`)return{};let n={};return Jt(e,n,Bt(t).strategies),n};function Jt(e,t,n){let r=n.array.indexed?new Map:void 0,i=0,a=e.length,o=-2;for(;i<a;){let s=e.indexOf(`&`,i);s===-1&&(s=a),s>i&&(o!==-1&&o<i&&(o=e.indexOf(`=`,i)),Kt(e,i,s,t,n,o,r)),i=s+1}if(r!==void 0)for(let[e,n]of r)n.sort((e,t)=>e[0]-t[0]),N(t,e,n.map(e=>e[1]))}const Yt=(e,t)=>{let n=Object.keys(e);if(n.length===0)return``;let r=Bt(t),i=[];for(let t of n){let n=e[t];if(n===void 0)continue;let a=Vt(t,n,r);a&&i.push(a)}return i.join(`&`)};function Xt(e){let t=e?.queryParams;return new _t({...e?.caseSensitive!==void 0&&{caseSensitive:e.caseSensitive},...e?.strictTrailingSlash!==void 0&&{strictTrailingSlash:e.strictTrailingSlash},...e?.strictQueryParams!==void 0&&{strictQueryParams:e.strictQueryParams},...e?.urlParamsEncoding!==void 0&&{urlParamsEncoding:e.urlParamsEncoding},parseQueryString:e=>qt(e,t),buildQueryString:e=>Yt(e,t)})}const Zt={defaultRoute:``,defaultParams:{},defaultSearch:{},trailingSlash:`preserve`,caseSensitive:!0,queryParamsMode:`loose`,queryParams:j,urlParamsEncoding:`default`,allowNotFound:!0,rewritePathOnMatch:!0};function Qt(e){Object.freeze(e);for(let t of Object.values(e))t&&typeof t==`object`&&t.constructor===Object&&Qt(t);return e}function P(e,t){return typeof e==`function`?e(t):e}function $t(e){if(!e||typeof e!=`object`||Array.isArray(e))throw TypeError(`[router.constructor] options must be a plain object`)}var en=class{#e;constructor(e={}){this.#e=Qt({...Zt,...e})}static validateOptionsIsObject(e){$t(e)}get(){return this.#e}};function tn(e,t,n,r,i){let a=e.pathNames(t);if(a!==void 0)for(let e of Object.keys(n))!r.includes(e)&&!a.includes(e)&&i(t,e)}function F(e,t,n,r,i){let a=i?.resolveForward===!1?{name:t,params:n,search:r}:e.resolveForward(t,n,r),o=a.name,s=me(a.params),c=e.queryNames(o),l=i?.diagnoseUndeclared===!0?e.reportUndeclaredParamKey:void 0;l&&tn(e,o,s,c,l);let u=e.defaultParams(o),d=e.defaultSearch(o);if(u===void 0&&d===void 0&&c.length===0&&(a.search===void 0||a.search===x))return{name:o,path:Object.freeze(s),query:x};let f=e.reportDroppedQueryKey,m=pe(i?.resolveForward===!1?p(d,s,c):d,a.search,x);return{name:o,path:pe(u,s,b,!0),query:e.admitsUndeclaredQuery()?m:re(m,c,t=>{f!==void 0&&e.pathNames(o)!==void 0&&f(o,t)})}}function I(e,t){return t.buildPath(e.name,e.path,e.query)}function L(e,t){let n={name:e.name,params:e.path,search:e.query,path:t.path,context:{},...!t.skipFreeze&&{transition:ne}};return t.skipFreeze?n:fe(n)}var nn=class{#e=void 0;#t=void 0;#n;get(){return this.#e}set(e){this.#t=this.#e,this.#e=e?fe(e):void 0}getPrevious(){return this.#t}reset(){this.#e=void 0,this.#t=void 0}setDependencies(e){this.#n=e}makeState(e,t,n,r){let i=this.#n.port(),a=F(i,e,t??b,n,{resolveForward:!1});return L(a,{path:r??I(a,i)})}areStatesEqual(e,t,n=!0){if(!e||!t)return!!e==!!t;if(e.name!==t.name)return!1;if(n){let n=this.#n.getUrlParams(e.name);for(let r of n)if(!w(e.params[r],t.params[r]))return!1;return!0}return rn(e.params,t.params)&&rn(e.search,t.search)}};function rn(e,t){let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(let r of n)if(!(r in t)||!w(e[r],t[r]))return!1;return!0}const an={[_.ROUTER_START]:v.ROUTER_START,[_.ROUTER_STOP]:v.ROUTER_STOP,[_.TRANSITION_SUCCESS]:v.TRANSITION_SUCCESS,[_.TRANSITION_START]:v.TRANSITION_START,[_.TRANSITION_LEAVE_APPROVE]:v.TRANSITION_LEAVE_APPROVE,[_.TRANSITION_ERROR]:v.TRANSITION_ERROR,[_.TRANSITION_CANCEL]:v.TRANSITION_CANCEL},on=Object.keys(an),R=`router.usePlugin`;function sn(e){if(!(e&&typeof e==`object`)||Array.isArray(e))throw TypeError(`[router.usePlugin] Plugin factory must return an object, got ${typeof e}`);if(typeof e.then==`function`)throw TypeError(`[router.usePlugin] Async plugin factories are not supported. Factory returned a Promise instead of a plugin object.`)}var cn=class e{#e=new Set;#t=new Set;#n;static validatePlugin(e){sn(e)}setDependencies(e){this.#n=e}count(){return this.#e.size}use(...e){if(this.#n.getValidator()?.plugins.validateCountThresholds(this.#e.size+e.length),e.length===1){let t=e[0],n=this.#i(t);this.#e.add(t);let r=!1,i=()=>{if(!r){r=!0,this.#e.delete(t),this.#t.delete(i);try{n()}catch(e){this.#n.logger.error(R,`Error during cleanup:`,e)}}};return this.#t.add(i),i}let t=this.#r(e),n=[];try{for(let e of t){let t=this.#i(e);n.push({factory:e,cleanup:t})}}catch(e){for(let{cleanup:e}of n)try{e()}catch(e){this.#n.logger.error(R,`Cleanup error:`,e)}throw e}for(let{factory:e}of n)this.#e.add(e);let r=!1,i=()=>{if(!r){r=!0,this.#t.delete(i);for(let{factory:e}of n)this.#e.delete(e);for(let{cleanup:e}of n)try{e()}catch(e){this.#n.logger.error(R,`Error during cleanup:`,e)}}};return this.#t.add(i),i}getAll(){return[...this.#e]}has(e){return this.#e.has(e)}disposeAll(){for(let e of this.#t)e();this.#e.clear(),this.#t.clear()}#r(e){let t=new Set;for(let n of e)t.has(n)?this.#n.getValidator()?.plugins.warnBatchDuplicates(e):t.add(n);return t}#i(t){let n=this.#n.compileFactory(t);e.validatePlugin(n),this.#n.getValidator()?.plugins.validatePluginKeys(n),Object.freeze(n);let r=[];for(let e of on)e in n&&(typeof n[e]==`function`?(r.push(this.#n.addEventListener(an[e],n[e])),e===`onStart`&&this.#n.canNavigate()&&this.#n.getValidator()?.plugins.warnPluginAfterStart(e)):this.#n.getValidator()?.plugins.warnPluginMethodType(e));return()=>{for(let e of r)e();typeof n.teardown==`function`&&n.teardown()}}};const ln=()=>!0,un=()=>!1,dn=()=>ln,fn=()=>un;function pn(e){return e?dn:fn}var mn=class{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i=new Map;#a=new Map;#o=[this.#i,this.#a];#s;setDependencies(e){this.#s=e}getHandlerCount(e){let t=e===`activate`?this.#e:this.#n,n=e===`activate`?this.#t:this.#r;if(t.size===0)return n.size;if(n.size===0)return t.size;let r=new Set(t.keys());for(let e of n.keys())r.add(e);return r.size}preflightHandlerLimit(e,t,n){let r=this.#s.getValidator();if(!r)return;let i=(e,t,i)=>{let{definition:a,external:o}=this.#d(e),s=0;for(let e of t)(n?o.has(e):a.has(e)||o.has(e))||s++;if(s===0)return;let c=n?o.size:this.getHandlerCount(e);r.lifecycle.validateHandlerLimit(c+s-1,i)};i(`activate`,e,`canActivate`),i(`deactivate`,t,`canDeactivate`)}addCanActivate(e,t,n=!1,r){this.#c(`activate`,e,t,n,`canActivate`,r)}addCanDeactivate(e,t,n=!1,r){this.#c(`deactivate`,e,t,n,`canDeactivate`,r)}clearCanActivate(e,t){this.#l(`activate`,e,t)}clearCanDeactivate(e,t){this.#l(`deactivate`,e,t)}clearAll(){this.#e.clear(),this.#t.clear(),this.#n.clear(),this.#r.clear(),this.#a.clear(),this.#i.clear()}clearDefinitionGuards(){for(let e of this.#e.keys())this.#t.has(e)?this.#u(`activate`,e):this.#a.delete(e);for(let e of this.#n.keys())this.#r.has(e)?this.#u(`deactivate`,e):this.#i.delete(e);this.#e.clear(),this.#n.clear()}getFactories(){let e={},t={};for(let[t,n]of this.#n)e[t]=n;for(let[t,n]of this.#r)e[t]=n;for(let[e,n]of this.#e)t[e]=n;for(let[e,n]of this.#t)t[e]=n;return[e,t]}getFactoriesByOrigin(){let e={},t={},n={},r={};for(let[t,n]of this.#n)e[t]=n;for(let[e,n]of this.#e)t[e]=n;for(let[e,t]of this.#r)n[e]=t;for(let[e,t]of this.#t)r[e]=t;return{definition:[e,t],external:[n,r]}}getFunctions(){return this.#o}canNavigateTo(e,t,n,r){for(let t of e)if(!this.#f(this.#i,t,n,r,`canNavigateTo`))return!1;for(let e of t)if(!this.#f(this.#a,e,n,r,`canNavigateTo`))return!1;return!0}compileGuardFactory(e,t){let n=typeof e==`boolean`?pn(e):e,r=this.#s.compileFactory(n);if(typeof r!=`function`)throw TypeError(`[router.${t}] Factory must return a function, got ${typeof r}`);return r}#c(e,t,n,r,i,a){let o=this.#d(e),s=e===`activate`?this.#a:this.#i,c=r?o.definition:o.external,l=r?o.external:o.definition;if(c.has(t)||l.has(t))this.#s.getValidator()?.lifecycle.warnOverwrite(t,e,i);else{let t=this.#s.getValidator();if(t){let n=this.getHandlerCount(e);t.lifecycle.validateHandlerLimit(n,i),t.lifecycle.validateCountThresholds(n+1,i)}}let u=typeof n==`boolean`?pn(n):n,d=c.get(t);c.set(t,u);let f=r&&l.has(t);try{let e=a??this.compileGuardFactory(u,i);f||s.set(t,e)}catch(n){throw d===void 0?c.delete(t):c.set(t,d),this.#u(e,t),n}}#l(e,t,n){let{definition:r,external:i}=this.#d(e),a=n!==`external`&&r.delete(t),o=n!==`definition`&&i.delete(t);(a||o)&&this.#u(e,t)}#u(e,t){let n=this.#d(e),r=e===`activate`?this.#a:this.#i,i=n.external.get(t)??n.definition.get(t);if(!i){r.delete(t);return}try{let e=this.#s.compileFactory(i);if(typeof e!=`function`){r.delete(t);return}r.set(t,e)}catch{r.delete(t)}}#d(e){return e===`activate`?{definition:this.#e,external:this.#t}:{definition:this.#n,external:this.#r}}#f(e,t,n,r,i){let a=e.get(t);if(!a)return!0;try{let e=a(n,r);return typeof e==`boolean`?e:(this.#s.getValidator()?.lifecycle.warnAsyncGuardSync(t,i),!1)}catch(e){return this.#s.logger.warn(`router.${i}`,`Guard for "${t}" threw — treated as navigation-blocking (returned false)`,e),!1}}};const hn=new Set([`name`,`path`,`children`,`canActivate`,`canDeactivate`,`forwardTo`,`encodeParams`,`decodeParams`,`defaultParams`]);function z(){return{decoders:Object.create(null),encoders:Object.create(null),defaultParams:Object.create(null),defaultSearch:Object.create(null),forwardMap:Object.create(null),forwardFnMap:Object.create(null)}}function gn(e,t){for(let n of Object.keys(t))Object.assign(e[n],t[n])}function _n(e,t){for(let n in e)if(!w(e[n],t[n]))return!1;return!0}function B(e){let t={name:e.name,path:e.path};return e.children&&(t.children=e.children.map(e=>B(e))),t}function vn(e,t,n=``){for(let r=0;r<e.length;r++){let i=e[r],a=n?`${n}.${i.name}`:i.name;if(a===t)return e.splice(r,1),!0;if(i.children&&t.startsWith(`${a}.`)&&vn(i.children,t,a))return!0}return!1}function yn(e,t){for(let n of Object.keys(e))t(n)&&delete e[n]}function bn(e,t){let n=t.search(/[?#]/),r=n===-1?t:t.slice(0,n);if(r===`/`||r.endsWith(`/`))return t;let i=e.search(/[?#]/),a=i===-1?e:e.slice(0,i);return a.length>1&&a.endsWith(`/`)?`${r}/${n===-1?``:t.slice(n)}`:t}function xn(e){let t=[];for(let n of e)for(let e of n.paramMeta.urlParams)t.push(e);return t}function Sn(e,t,n){let r=n.get(t);if(r!==void 0)return r;let i=e.getSegmentsByName(t),a=i?xn(i):[];return n.set(t,a),a}function Cn(e,t){return Sn(e.matcher,t,e.urlParamsCache)}function wn(e,t,n,r){let i=r.get(t);if(i!==void 0)return i;let a=e.getDeclaredQueryParams(t),o=[];if(a){let r=Sn(e,t,n);o=a.filter(e=>!r.includes(e))}return r.set(t,o),o}function Tn(e,t){return wn(e.matcher,t,e.urlParamsCache,e.queryParamsCache)}function En(e,t,n){let r=new Map,i=new Map;m(t.defaultParams,t=>wn(e,t,r,i),n)}function Dn(e,t,n=100){let r=new Set,i=[e],a=e;for(;t[a];){let e=t[a];if(r.has(e)){let t=i.indexOf(e),n=[...i.slice(t),e];throw Error(`Circular forwardTo: ${n.join(` → `)}`)}if(r.add(a),i.push(e),a=e,i.length>n)throw Error(`forwardTo chain exceeds maximum depth (${n}): ${i.join(` → `)}`)}return a}function On(e,t,n){let r=Tt(``,t,e),i=Xt(n);return i.registerTree(r),{tree:r,matcher:i}}function kn(e,t=e.definitions){let n=On(t,e.rootPath,e.matcherOptions);e.tree=n.tree,e.matcher=n.matcher,e.urlParamsCache.clear(),e.queryParamsCache.clear()}function An(e,t){let n=On(e.definitions,t,e.matcherOptions);En(n.matcher,e.config,`setRootPath`),e.rootPath=t,e.tree=n.tree,e.matcher=n.matcher,e.urlParamsCache.clear(),e.queryParamsCache.clear()}function jn(e,t){kn(e,t),e.resolvedForwardMap=Pn(e.config)}function Mn(e){Nn(e),kn(e,[])}function Nn(e){Object.assign(e.config,z()),e.resolvedForwardMap=Object.create(null),e.routeCustomFields=Object.create(null)}function Pn(e){let t=Object.create(null);for(let n of Object.keys(e.forwardMap))t[n]=Dn(n,e.forwardMap);return t}function Fn(e,t){if(typeof e!=`function`)return;let n=e.constructor.name===`AsyncFunction`,r=e.toString().includes(`__awaiter`);if(n||r)throw TypeError(`forwardTo callback cannot be async for route "${t}". Async functions break matchPath/buildPath.`)}function In(e,t,n,r){if(e.canActivate){let n=typeof e.forwardTo==`string`?e.forwardTo:`[dynamic]`;r.warn(`real-router`,`Route "${t}" has both forwardTo and canActivate. canActivate will be ignored because forwardTo creates a redirect (industry standard). Move canActivate to the target route "${n}".`)}if(e.canDeactivate){let n=typeof e.forwardTo==`string`?e.forwardTo:`[dynamic]`;r.warn(`real-router`,`Route "${t}" has both forwardTo and canDeactivate. canDeactivate will be ignored because forwardTo creates a redirect (industry standard). Move canDeactivate to the target route "${n}".`)}Fn(e.forwardTo,t),typeof e.forwardTo==`string`?n.forwardMap[t]=e.forwardTo:n.forwardFnMap[t]=e.forwardTo}function Ln(e,t,n,r,i,a,o){let s=Object.fromEntries(Object.entries(e).filter(([e])=>!hn.has(e)));if(Object.keys(s).length>0&&(r[t]=s),e.canActivate&&i.set(t,e.canActivate),e.canDeactivate&&a.set(t,e.canDeactivate),e.forwardTo&&In(e,t,n,o),e.decodeParams){let r=e.decodeParams;n.decoders[t]=e=>r(e)??e}if(e.encodeParams){let r=e.encodeParams;n.encoders[t]=e=>r(e)??e}e.defaultParams&&(n.defaultParams[t]=e.defaultParams),e.defaultSearch&&(n.defaultSearch[t]=e.defaultSearch)}function Rn(e,t,n,r,i,a,o=``){for(let s of e){let e=o?`${o}.${s.name}`:s.name;Ln(s,e,t,n,r,i,a),s.children&&Rn(s.children,t,n,r,i,a,e)}}function zn(e){let t=z();return gn(t,e),t}function Bn(e,t,n){if(n.length===0)return[...e,...t];let[r,...i]=n;return e.map(e=>{if(e.name!==r)return e;let n=e.children??[];return{...e,children:i.length===0?[...n,...t]:Bn(n,t,i)}})}function Vn(e,t,n){for(let r of e){let e=t?`${t}.${r.name}`:r.name;n(e),r.children&&Vn(r.children,e,n)}}function Hn(e,t,n){let r=new Set;Vn(e,t,e=>{if(r.has(e))throw Error(`[router.${n}] Duplicate route "${e}" in batch`);r.add(e)})}function Un(e,t){if(e.startsWith(`@@`))throw Error(`[router.${t}] Route name "${e}" uses the reserved "@@" prefix. Routes with this prefix are internal and cannot be modified through the public API.`)}function V(e,t){for(let n of e)Un(n.name,t),n.children&&V(n.children,t)}function Wn(e,t,n){let r=new Map,i=(e,t)=>{for(let a of e){let e=r.get(t);if(e?.has(a.path))throw Error(`[router.${n}] Path "${a.path}" is already defined`);e?e.add(a.path):r.set(t,new Set([a.path])),a.children&&i(a.children,t?`${t}.${a.name}`:a.name)}};i(e,t)}function Gn(e,t,n){if(V(t,`addRoute`),n!==void 0&&!e.matcher.hasRoute(n))throw Error(`[router.addRoute] Parent route "${n}" does not exist`);Vn(t,n??``,t=>{if(e.matcher.hasRoute(t))throw Error(`[router.addRoute] Route "${t}" already exists`)}),Hn(t,n??``,`addRoute`),Wn(t,n??``,`addRoute`)}function Kn({definitions:e,routesForHandlers:t,config:n,routeCustomFields:r,handlerParentName:i,rootPath:a,matcherOptions:o,logger:s}){let c=new Map,l=new Map;Rn(t,n,r,c,l,s,i);let u=Pn(n),{tree:d,matcher:f}=On(e,a,o);return{config:n,routeCustomFields:r,pendingCanActivate:c,pendingCanDeactivate:l,tree:d,matcher:f,resolvedForwardMap:u}}function qn(e,t,n,r){return Kn({definitions:Bn(e.definitions,t.map(e=>B(e)),n===void 0?[]:n.split(`.`)),routesForHandlers:t,config:zn(e.config),routeCustomFields:Object.assign(Object.create(null),e.routeCustomFields),handlerParentName:n??``,rootPath:e.rootPath,matcherOptions:e.matcherOptions,logger:r})}function Jn(e,t,n,r){return Kn({definitions:e.map(e=>B(e)),routesForHandlers:e,config:z(),routeCustomFields:Object.create(null),handlerParentName:``,rootPath:t,matcherOptions:n,logger:r})}function Yn(e,t,n){let r=[];for(let[i,a]of e)r.push([i,a,t(a,n)]);return r}function Xn(e,t){return{activate:Yn(e.pendingCanActivate,t.compileGuard,`canActivate`),deactivate:Yn(e.pendingCanDeactivate,t.compileGuard,`canDeactivate`)}}function Zn(e,t,n){let r=e.depsStore,{activate:i,deactivate:a}=n??Xn(t,r);Object.assign(e.config,t.config),e.routeCustomFields=t.routeCustomFields,e.tree=t.tree,e.matcher=t.matcher,e.urlParamsCache.clear(),e.queryParamsCache.clear(),e.resolvedForwardMap=t.resolvedForwardMap;for(let[e,t,n]of i)r.addActivateGuard(e,t,n);for(let[e,t,n]of a)r.addDeactivateGuard(e,t,n)}function Qn(e,t,n,r){let{forwardTo:i,defaultParams:a,defaultSearch:o,decodeParams:s,encodeParams:l,canActivate:u,canDeactivate:d}=r;a!=null&&c(`updateRoute`,n,a,Tn(e,n),"this route's `defaultParams`","Move it to `defaultSearch`");let f=i===void 0?void 0:$n(n,i,e.config),p=er(e,n,r),m=u==null?void 0:t.compileGuardFactory(u,`canActivate`),h=d==null?void 0:t.compileGuardFactory(d,`canDeactivate`);return t.preflightHandlerLimit(m===void 0?[]:[n],h===void 0?[]:[n],!1),p!==void 0&&(Object.keys(p).length>0?e.routeCustomFields[n]=p:delete e.routeCustomFields[n]),f!==void 0&&(e.config.forwardMap=f.forwardMap,e.config.forwardFnMap=f.forwardFnMap,e.resolvedForwardMap=f.resolved),nr(e,n,{defaultParams:a,defaultSearch:o,decodeParams:s,encodeParams:l}),rr(t,`activate`,n,u,m),rr(t,`deactivate`,n,d,h),{forwardTo:i,defaultParams:a,defaultSearch:o,decodeParams:s,encodeParams:l}}function $n(e,t,n){Fn(t,e);let r=Object.assign(Object.create(null),n.forwardMap),i=Object.assign(Object.create(null),n.forwardFnMap);return t===null?(delete r[e],delete i[e]):typeof t==`string`?(delete i[e],r[e]=t):(delete r[e],i[e]=t),{forwardMap:r,forwardFnMap:i,resolved:Pn({...n,forwardMap:r})}}function er(e,t,n){let r;for(let i of Object.keys(n)){if(hn.has(i))continue;let a=n[i];a!==void 0&&(r??={...e.routeCustomFields[t]},a===null?delete r[i]:r[i]=a)}return r}function tr(e,t,n){n!==void 0&&(n===null?delete e[t]:e[t]=n)}function nr(e,t,n){if(tr(e.config.defaultParams,t,n.defaultParams),tr(e.config.defaultSearch,t,n.defaultSearch),n.decodeParams!==void 0)if(n.decodeParams===null)delete e.config.decoders[t];else{let r=n.decodeParams;e.config.decoders[t]=e=>r(e)??e}if(n.encodeParams!==void 0)if(n.encodeParams===null)delete e.config.encoders[t];else{let r=n.encodeParams;e.config.encoders[t]=e=>r(e)??e}}function rr(e,t,n,r,i){r!==void 0&&(t===`activate`?r===null?e.clearCanActivate(n,`definition`):e.addCanActivate(n,r,!0,i):r===null?e.clearCanDeactivate(n,`definition`):e.addCanDeactivate(n,r,!0,i))}function ir(e,t,n){V(e,`addRoute`),Hn(e,``,`addRoute`);let r=Jn(e,``,t,n),i={get definitions(){return Dt(i.tree)},config:r.config,tree:r.tree,matcher:r.matcher,urlParamsCache:new Map,queryParamsCache:new Map,resolvedForwardMap:r.resolvedForwardMap,routeCustomFields:r.routeCustomFields,rootPath:``,matcherOptions:t,depsStore:void 0,lifecycleNamespace:void 0,pendingCanActivate:r.pendingCanActivate,pendingCanDeactivate:r.pendingCanDeactivate};return En(i.matcher,i.config,`addRoute`),i}const ar=[];Object.freeze(ar);function or(e){let t=e.split(`.`),n=t.length,r=[t[0]],i=t[0].length;for(let a=1;a<n-1;a++)i+=1+t[a].length,r.push(e.slice(0,i));return r.push(e),r}const sr=new Set([`string`,`number`,`boolean`]);function cr(e){return sr.has(typeof e)}function lr(e,t,n,r){let i=t[e];if(!i||typeof i!=`object`)return!0;for(let e of Object.keys(i)){let t=n.params[e],i=r.params[e];if(cr(t)&&cr(i)&&String(t)!==String(i))return!1}return!0}function ur(e,t,n,r,i,a){for(let o=0;o<a;o++){let a=r[o];if(a!==i[o]||!lr(a,e,t,n))return o}return a}const dr=new Map;function H(e){let t=dr.get(e);if(t)return t;let n=fr(e);return Object.freeze(n),dr.set(e,n),n}function fr(e){if(!e)return[``];let t=e.indexOf(`.`);if(t===-1)return[e];let n=e.indexOf(`.`,t+1);if(n===-1)return[e.slice(0,t),e];let r=e.indexOf(`.`,n+1);return r===-1?[e.slice(0,t),e.slice(0,n),e]:e.indexOf(`.`,r+1)===-1?[e.slice(0,t),e.slice(0,n),e.slice(0,r),e]:or(e)}let pr,mr,U=null,hr,gr,_r=null;function vr(e,t,n){if(!t)return{intersection:``,toActivate:H(e.name),toDeactivate:ar};let r=n(e.name),i=n(t.name);if(!r&&!i)return{intersection:``,toActivate:H(e.name),toDeactivate:H(t.name)};let a=H(e.name),o=H(t.name),s=Math.min(o.length,a.length),c=ur(r??i,e,t,a,o,s),l;if(c>=o.length)l=ar;else if(c===0&&o.length===1)l=o;else{l=[];for(let e=o.length-1;e>=c;e--)l.push(o[e])}let u=c===0?a:a.slice(c);return{intersection:c>0?o[c-1]:``,toDeactivate:l,toActivate:u}}function W(e,t,n){if(U!==null&&e===pr&&t===mr)return U;if(_r!==null&&e===hr&&t===gr)return _r;let r=vr(e,t,n);return hr=pr,gr=mr,_r=U,pr=e,mr=t,U=r,r}function yr(e,t){return{name:t??e.segments.at(-1).fullName,params:e.params,search:e.search,meta:e.meta}}var br=class{#e;#t;#n;get#r(){return this.#e.depsStore}constructor(e,t,n){this.#e=ir(e,t,n)}static shouldUpdateNode(e,t){return(n,r)=>{if(!(n&&typeof n==`object`&&`name`in n))throw TypeError(`[router.shouldUpdateNode] toState must be valid State object`);if(n.transition.reload||e===``)return!0;let{intersection:i,toActivate:a,toDeactivate:o}=W(n,r,t);return e===i||a.includes(e)?!0:o.includes(e)}}setDependencies(e){this.#e.depsStore=e}flushPendingGuards(){let e=this.#r;for(let[t,n]of this.#e.pendingCanActivate)e.addActivateGuard(t,n);this.#e.pendingCanActivate.clear();for(let[t,n]of this.#e.pendingCanDeactivate)e.addDeactivateGuard(t,n);this.#e.pendingCanDeactivate.clear()}setLifecycleNamespace(e){this.#e.lifecycleNamespace=e}setRootPath(e){An(this.#e,e)}hasRoute(e){return this.#e.matcher.hasRoute(e)}clearRoutes(){Mn(this.#e)}buildPath(e,t,n,r){if(e===g.UNKNOWN_ROUTE)return typeof t.path==`string`?t.path:``;let i=F(this.#r.port,e,t,n,{resolveForward:!1});if(typeof this.#e.config.encoders[e]==`function`){let t=this.#e.config.encoders[e]({params:{...i.path},search:{...i.query}});return this.#e.matcher.buildPath(e,t.params,t.search,this.#c(r))}return this.#e.matcher.buildPath(e,i.path,i.query,this.#c(r))}matchPath(e,t){let n=t,r=this.#e.matcher.match(e);if(!r)return;let i=yr(r),{name:a,params:o}=i,s=i.search,l=this.#e.config.decoders[a],u;typeof l==`function`?(u=l({params:o,search:s}),this.#r.getValidator()?.routes.validateStateBuilderArgs(a,u.params,`matchPath`),c(`matchPath`,a,u.params,this.getQueryParams(a),"the `params` returned by this route's `decodeParams`")):u={params:o,search:s};let d=F(this.#r.port,a,u.params,u.search),f=d.name,p=d.path,m=d.query,h=e;if(n.rewritePathOnMatch){let t=typeof this.#e.config.encoders[f]==`function`?this.#e.config.encoders[f]({params:p,search:m}):{params:p,search:m},r=n.trailingSlash;try{h=this.#e.matcher.buildPath(f,t.params,t.search,{trailingSlash:r===`never`||r===`always`?r:void 0,queryParamsMode:n.queryParamsMode}),r===`preserve`&&(h=bn(e,h))}catch{h=e}}return L(d,{path:h})}forwardState(e,t,n){let r=n??x;if(Object.hasOwn(this.#e.config.forwardFnMap,e)){let n=this.#e.config.forwardFnMap[e],{target:i,chain:a}=this.#l(e,n,t);return this.#s(i,a,t,r)}let i=this.#e.resolvedForwardMap[e]??e;if(i!==e&&Object.hasOwn(this.#e.config.forwardFnMap,i)){let n=this.#e.config.forwardFnMap[i],{target:a,chain:o}=this.#l(i,n,t);return this.#s(a,[...this.#o(e),...o],t,r)}return i===e?{name:e,params:t,search:r}:this.#s(i,this.#o(e),t,r)}buildStateResolved(e,t){let n=this.#e.matcher.getSegmentsByName(e);if(n)return yr({segments:n,params:t,search:{},meta:this.#e.matcher.getMetaByName(e)},e)}isActiveRoute(e,t=b,n=x,r=!1,i=!0){if(this.#i(e,t,n,r,i))return!0;if(!Object.hasOwn(this.#e.config.forwardMap,e)&&!Object.hasOwn(this.#e.config.forwardFnMap,e))return!1;let a;try{a=this.forwardState(e,t,n)}catch(t){return this.#r.logger.warn(`router.isActiveRoute`,`Dynamic forwardTo of route "${e}" threw while resolving the active-link destination; treating the link as inactive.`,t),!1}return this.#i(a.name,a.params,a.search,r,i)}getMetaForState(e){return this.#e.matcher.hasRoute(e)?this.#e.matcher.getMetaByName(e):void 0}getUrlParams(e){return Cn(this.#e,e)}getQueryParams(e){return Tn(this.#e,e)}getStore(){return this.#e}getPort(){return this.#r.port}#i(e,t,n,r,i){try{return this.#a(e,t,n,r,i)}catch(t){return this.#r.logger.warn(`router.isActiveRoute`,`Reading the arguments for route "${e}" threw while resolving the active-link state; treating the link as inactive.`,t),!1}}#a(e,t,n,r,i){let a=this.#r.getState();if(!a)return!1;let o=a.name;if(o!==e&&!o.startsWith(`${e}.`)&&!e.startsWith(`${o}.`))return!1;let s=F(this.#r.port,e,t,n,{resolveForward:!1});return r||o===e?this.#r.areStatesEqual(L(s,{path:``,skipFreeze:!0}),a,i):!(!o.startsWith(`${e}.`)||!_n(s.path,a.params)||!i&&!_n(s.query,a.search))}#o(e){let t=[],n=e;for(;Object.hasOwn(this.#e.config.forwardMap,n);)t.push(n),n=this.#e.config.forwardMap[n];return t}#s(e,t,n,r){let i,a;for(let e of t)i=C(this.#e.config.defaultParams[e],i),a=C(this.#e.config.defaultSearch[e],a);return{name:e,params:C(i,n),search:C(a,r)}}#c(e){if(this.#t)return e!==this.#n&&this.#r.logger.warn(`router.buildPath`,"`options` differs from the cached source reference; router options are immutable per router instance, so the first-cached buildPath options are reused (#957)."),this.#t;this.#n=e;let t=e?.trailingSlash;return this.#t=Object.freeze({trailingSlash:t===`never`||t===`always`?t:void 0,queryParamsMode:e?.queryParamsMode}),this.#t}#l(e,t,n){let r=new Set([e]),i=[e],a=t(this.#r.getDependency,n),o=0;if(typeof a!=`string`)throw TypeError(`forwardTo callback must return a string, got ${typeof a}`);for(;o<100;){if(this.#e.matcher.getSegmentsByName(a)===void 0)throw Error(`Route "${a}" does not exist`);if(r.has(a)){let e=[...r,a].join(` → `);throw Error(`Circular forwardTo: ${e}`)}if(r.add(a),Object.hasOwn(this.#e.config.forwardFnMap,a)){let e=this.#e.config.forwardFnMap[a];i.push(a),a=e(this.#r.getDependency,n),o++;continue}let e=this.#e.config.forwardMap[a];if(e!==void 0){i.push(a),a=e,o++;continue}return{target:a,chain:i}}throw Error(`forwardTo exceeds maximum depth of 100`)}};const xr=new Set(Object.values(h)),Sr=new Set([`code`,`segment`,`path`]),Cr=new Set([`setCode`,`setErrorInstance`,`setAdditionalFields`,`hasField`,`getField`,`toJSON`]);var G=class extends Error{segment;path;code;constructor(e,{message:t,segment:n,path:r,...i}={}){super(t??e),this.name=`RouterError`,this.code=e,this.segment=n,this.path=r;for(let[e,t]of Object.entries(i)){if(Sr.has(e))throw TypeError(`[RouterError] Cannot set reserved property "${e}"`);Cr.has(e)||(this[e]=t)}}setCode(e){this.code=e,xr.has(this.message)&&(this.message=e)}setErrorInstance(e){if(!e)throw TypeError(`[RouterError.setErrorInstance] err parameter is required and must be an Error instance`);this.message=e.message,this.cause=e.cause,this.stack=e.stack??``}setAdditionalFields(e){for(let[t,n]of Object.entries(e)){if(Sr.has(t))throw TypeError(`[RouterError.setAdditionalFields] Cannot set reserved property "${t}"`);Cr.has(t)||(this[t]=n)}}hasField(e){return e in this}getField(e){return this[e]}toJSON(){let e={code:this.code,message:this.message};this.segment!==void 0&&(e.segment=this.segment),this.path!==void 0&&(e.path=this.path);let t=new Set([`code`,`message`,`segment`,`path`,`stack`,`name`]);for(let n in this)Object.hasOwn(this,n)&&!t.has(n)&&(e[n]=this[n]);return e}};const wr=new G(h.ROUTER_NOT_STARTED),Tr=new G(h.ROUTE_NOT_FOUND),Er=new G(h.SAME_STATES),Dr=Promise.reject(wr),Or=Promise.reject(Tr),kr=Promise.reject(Er);Dr.catch(()=>{}),Or.catch(()=>{}),kr.catch(()=>{});function Ar(e,t,n,r,i){Object.freeze(n),Object.freeze(r);let a={phase:`activating`,reason:`success`,segments:Object.freeze({deactivated:n,activated:r,intersection:i})};return e?.name!==void 0&&(a.from=e.name),t.reload!==void 0&&(a.reload=t.reload),t.replace!==void 0&&(a.replace=t.replace),t.redirected!==void 0&&(a.redirected=t.redirected),Object.freeze(a)}function jr({signal:e,...t}){return t}function Mr(e,t){let{toState:n,fromState:r,opts:i,toDeactivate:a,toActivate:o,intersection:s}=t;if(n.name!==g.UNKNOWN_ROUTE&&!e.hasRoute(n.name)){let t=new G(h.ROUTE_NOT_FOUND,{routeName:n.name});throw e.sendTransitionFail(n,r,t),t}if(r)for(let n of a)!o.includes(n)&&t.canDeactivateFunctions.has(n)&&e.clearCanDeactivate(n);n.transition=Ar(r,i,a,o,s);let c=Object.freeze(n);e.setState(c);let l=i.signal===void 0?i:jr(i);return e.sendTransitionDone(c,r,l),c}function Nr(e,t,n,r){let i=t;i.code!==h.TRANSITION_CANCELLED&&i.code!==h.ROUTE_NOT_FOUND&&e.sendTransitionFail(n,r,i)}function Pr(e,t,n){if(e instanceof DOMException&&e.name===`AbortError`)throw new G(h.TRANSITION_CANCELLED);if(e instanceof G&&e.code===h.TRANSITION_CANCELLED)throw e;Fr(e,t,n)}function Fr(e,t,n){throw e instanceof G?(e.setCode(t),e):new G(t,Lr(e,n))}const Ir=new Set([`code`,`segment`,`path`,`then`]);function Lr(e,t){let n={segment:t};if(e instanceof Error)return{...n,message:e.message,stack:e.stack,...`cause`in e&&e.cause!==void 0&&{cause:e.cause}};if(e&&typeof e==`object`){let t={};for(let[n,r]of Object.entries(e))Ir.has(n)||(t[n]=r);return{...n,...t}}return n}async function Rr(e,t,n){let r;try{r=await e}catch(e){Pr(e,t,n);return}if(!r)throw new G(t,{segment:n})}async function zr(e,t,n,r,i,a,o,s,c,l){await Rr(c,n,l);for(let c=s;c<t.length;c++){if(!o())throw new G(h.TRANSITION_CANCELLED);let s=t[c],l=e.get(s);if(!l)continue;let u=!1;try{u=l(r,i,a)}catch(e){Pr(e,n,s)}if(u instanceof Promise){await Rr(u,n,s);continue}if(!u)throw new G(n,{segment:s})}}async function Br(e,t,n,r,i,a,o,s,c){if(await e,!s())throw new G(h.TRANSITION_CANCELLED);let l=c();if(l!==void 0&&(await l,!s()))throw new G(h.TRANSITION_CANCELLED);if(r){let e=K(t,n,h.CANNOT_ACTIVATE,i,a,o,s);if(e!==void 0&&await e,!s())throw new G(h.TRANSITION_CANCELLED)}}function Vr(e,t,n,r,i,a,o,s,c,l,u){if(i){let i=K(e,n,h.CANNOT_DEACTIVATE,o,s,c,l);if(i!==void 0)return Br(i,t,r,a,o,s,c,l,u)}if(!l())throw new G(h.TRANSITION_CANCELLED);let d=u();if(d!==void 0)return Hr(d,a?t:void 0,r,o,s,c,l);if(a)return K(t,r,h.CANNOT_ACTIVATE,o,s,c,l)}async function Hr(e,t,n,r,i,a,o){if(await e,!o())throw new G(h.TRANSITION_CANCELLED);if(t!==void 0){let e=K(t,n,h.CANNOT_ACTIVATE,r,i,a,o);if(e!==void 0&&await e,!o())throw new G(h.TRANSITION_CANCELLED)}}function K(e,t,n,r,i,a,o){for(let[s,c]of t.entries()){if(!o())throw new G(h.TRANSITION_CANCELLED);let l=e.get(c);if(!l)continue;let u=!1;try{u=l(r,i,a)}catch(e){Pr(e,n,c)}if(u instanceof Promise)return zr(e,t,n,r,i,a,o,s+1,u,c);if(!u)throw new G(n,{segment:c})}}const Ur=Object.freeze([g.UNKNOWN_ROUTE]),Wr=Object.freeze({replace:!0});function Gr(e,t){return t?.name===g.UNKNOWN_ROUTE&&!e.replace?{...e,replace:!0}:e}function Kr(e,t,n){return!!e&&!t.reload&&!t.force&&e.path===n.path}var qr=class{lastSyncResolved=!1;lastSyncRejected=!1;#e;#t=null;#n=0;setDependencies(e){this.#e=e}navigate(e,t,n,r){this.lastSyncResolved=!1;let i=this.#e;if(!i.canNavigate())return this.lastSyncRejected=!0,Dr;let a;try{a=i.buildNavigateState(e,t,n)}catch(e){return Promise.reject(e)}return a?this.#r(a,r):(i.emitTransitionError(void 0,i.getState(),Tr),this.lastSyncRejected=!0,Or)}navigateToState(e,t){this.lastSyncResolved=!1;let n=this.#e;if(!n.canNavigate())return this.lastSyncRejected=!0,Dr;if(e.name!==g.UNKNOWN_ROUTE&&!n.hasRoute(e.name)){let t=new G(h.ROUTE_NOT_FOUND,{routeName:e.name});return n.emitTransitionError(void 0,n.getState(),t),Promise.reject(t)}let i=a(e.params,n.getQueryParams(e.name));if(i!==void 0){let t=new G(h.WRONG_CHANNEL,{routeName:e.name,message:`[router.navigateToState] ${r(e.name,i,"`state.params`")}`});return n.emitTransitionError(void 0,n.getState(),t),Promise.reject(t)}let o={name:e.name,params:e.params,search:e.search,path:e.path,context:{...e.context}};return this.#r(o,t)}navigateToDefault(e){this.lastSyncResolved=!1;let t=this.#e;if(!t.getOptions().defaultRoute)return Promise.reject(new G(h.ROUTE_NOT_FOUND,{routeName:`defaultRoute not configured`}));let n,r,i;try{({route:n,params:r,search:i}=t.resolveDefault())}catch(e){return Promise.reject(e)}return n?this.navigate(n,r,i,e):Promise.reject(new G(h.ROUTE_NOT_FOUND,{routeName:`defaultRoute resolved to empty`}))}navigateToNotFound(e){if(!this.#e.isActive())throw new G(h.ROUTER_DISPOSED);this.#c();let t=this.#e.getState(),n=t?H(t.name).toReversed():[];Object.freeze(n);let r={deactivated:n,activated:Ur,intersection:``};Object.freeze(r);let i={phase:`activating`,...t&&{from:t.name},reason:`success`,replace:!0,segments:r};Object.freeze(i);let a={name:g.UNKNOWN_ROUTE,params:b,search:x,path:e,transition:i,context:{}};return Object.freeze(a),this.#e.setState(a),this.#e.emitTransitionSuccess(a,t,Wr),a}abortCurrentController(e){this.#t?.abort(e??new G(h.TRANSITION_CANCELLED)),this.#t=null}#r(e,t){let n=this.#e,r,i=!1,a=null;try{if(r=n.getState(),t=Gr(t,r),Kr(r,t,e))return n.emitTransitionError(e,r,Er),this.lastSyncRejected=!0,kr;this.#c(t.signal);let o=++this.#n,s=t.signal!==void 0||n.hasLeaveListeners()||n.hasPreCommitListeners();n.startTransition(e,r),i=!0;let[c,l]=n.getLifecycleFunctions(),u=e.name===g.UNKNOWN_ROUTE,d=W(e,r,e=>n.getMetaForState(e)),{toDeactivate:f,toActivate:p,intersection:m}=d,ee=r&&!t.forceDeactivate&&f.length>0,_=!u&&p.length>0,v=c.size>0||l.size>0,y=e;if(!v){let e=this.#o(y,r,o,t,d,c);if(e!==void 0)return e}if(v){a=new AbortController,this.#t=a;let i=()=>this.#n===o&&n.isActive(),s=a.signal,u=Vr(c,l,f,p,!!ee,_,e,r,s,i,()=>{if(n.sendLeaveApprove(y,r),n.hasLeaveListeners())return n.awaitLeaveListeners(y,r,s)});if(u!==void 0)return this.#i(u,{toState:e,fromState:r,opts:t,toDeactivate:f,toActivate:p,intersection:m,canDeactivateFunctions:c},a,o);if(!i())throw new G(h.TRANSITION_CANCELLED);this.#s(a,!1)}if(s&&(!n.isActive()||t.signal?.aborted===!0))throw new G(h.TRANSITION_CANCELLED);let b=Mr(n,{toState:e,fromState:r,opts:t,toDeactivate:f,toActivate:p,intersection:m,canDeactivateFunctions:c});return this.lastSyncResolved=!0,Promise.resolve(b)}catch(t){return this.#a(t,a,i,e,r),Promise.reject(t)}}async#i(e,t,n,r){let i=this.#e,a=()=>this.#n===r&&!n.signal.aborted&&i.isActive(),o=t.opts.signal,s,c,l=!1,u,d=new Promise(e=>{if(n.signal.aborted){e();return}c=()=>{e()},n.signal.addEventListener(`abort`,c,{once:!0})});e.catch(()=>{});try{if(o){if(o.aborted)throw new G(h.TRANSITION_CANCELLED,{reason:o.reason});s=()=>{i.cancelNavigation(o.reason)},o.addEventListener(`abort`,s,{once:!0})}if(await Promise.race([e,d]),!a())throw new G(h.TRANSITION_CANCELLED);let n=Mr(i,t);return l=!0,n}catch(e){throw u=e,Nr(i,e,t.toState,t.fromState),e}finally{s&&o?.removeEventListener(`abort`,s),c&&n.signal.removeEventListener(`abort`,c),this.#s(n,!l,u)}}#a(e,t,n,r,i){t&&this.#s(t,!0,e),n&&r&&Nr(this.#e,e,r,i)}#o(e,t,n,r,i,a){let o=this.#e;if(o.sendLeaveApprove(e,t),o.hasLeaveListeners()){let s=new AbortController;this.#t=s;let c;try{c=o.awaitLeaveListeners(e,t,s.signal)}catch(e){throw this.#s(s,!0,e),e}if(c!==void 0)return this.#i(c,{toState:e,fromState:t,opts:r,toDeactivate:i.toDeactivate,toActivate:i.toActivate,intersection:i.intersection,canDeactivateFunctions:a},s,n);this.#s(s,!1);return}}#s(e,t,n){t&&e.abort(n),this.#t===e&&(this.#t=null)}#c(e){if(this.#e.isTransitioning()&&(this.#e.logger.warn(`router.navigate`,`Concurrent navigation detected on shared router instance. For SSR, use cloneRouter() to create isolated instance per request.`),this.#e.cancelNavigation()),e?.aborted)throw new G(h.TRANSITION_CANCELLED,{reason:e.reason})}};const Jr=Object.freeze({replace:!0});var Yr=class{#e;setDependencies(e){this.#e=e}async start(e){let t=this.#e;if(t.isIdle())throw new G(h.TRANSITION_CANCELLED);let n=t.getOptions();if(typeof e!=`string`)throw TypeError(`[router.start] path must be a string, got ${typeof e}`);let r=t.matchPath(e);if(!r&&!n.allowNotFound){let n=new G(h.ROUTE_NOT_FOUND,{path:e});throw t.emitTransitionError(void 0,void 0,n),n}return t.completeStart(),r?t.navigateToState(r,Jr):t.navigateToNotFound(e)}stop(){this.#e.clearState()}};function q(e,t,n){let r=e[t];if(r===void 0)throw Error(`[FSM.${n}] state "${t}" is not declared in config.transitions`);return r}var Xr=class{#e;#t;#n=0;#r=null;#i;#a;#o=[];constructor(e){this.#e=e.initial,this.#i=e.context,this.#a=e.transitions,this.#t=q(e.transitions,e.initial,`constructor`);for(let t of Object.keys(e.transitions)){let n=e.transitions[t];for(let t of Object.keys(n)){let r=n[t];r!==void 0&&q(e.transitions,r,`constructor`)}}}send(e,...t){let n=this.#t[e];if(n===void 0)return this.#e;let r=this.#e;this.#e=n,this.#t=this.#a[n];let i=t[0];if(this.#r!==null){let t=this.#r.get(r)?.get(e);t!==void 0&&t(i)}if(this.#n>0){let t={from:r,to:n,event:e,payload:i};for(let e of this.#o)e!==null&&e(t)}return this.#e}canSend(e){return this.#t[e]!==void 0}getState(){return this.#e}getContext(){return this.#i}on(e,t,n){q(this.#a,e,`on`),this.#r??=new Map;let r=this.#r.get(e);r||(r=new Map,this.#r.set(e,r));let i=n;return r.set(t,i),()=>{let n=this.#r?.get(e);n?.get(t)===i&&n.delete(t)}}onTransition(e){let t=this.#o.indexOf(null),n;t===-1?(n=this.#o.length,this.#o.push(e)):(this.#o[t]=e,n=t),this.#n++;let r=!0;return()=>{r&&(r=!1,this.#o[n]=null,this.#n--)}}};const J={IDLE:`IDLE`,STARTING:`STARTING`,READY:`READY`,TRANSITION_STARTED:`TRANSITION_STARTED`,LEAVE_APPROVED:`LEAVE_APPROVED`,DISPOSED:`DISPOSED`},Y={START:`START`,STARTED:`STARTED`,NAVIGATE:`NAVIGATE`,LEAVE_APPROVE:`LEAVE_APPROVE`,COMPLETE:`COMPLETE`,FAIL:`FAIL`,CANCEL:`CANCEL`,STOP:`STOP`,DISPOSE:`DISPOSE`},Zr={initial:J.IDLE,context:null,transitions:{[J.IDLE]:{[Y.START]:J.STARTING,[Y.DISPOSE]:J.DISPOSED},[J.STARTING]:{[Y.STARTED]:J.READY,[Y.FAIL]:J.IDLE,[Y.STOP]:J.IDLE,[Y.DISPOSE]:J.DISPOSED},[J.READY]:{[Y.NAVIGATE]:J.TRANSITION_STARTED,[Y.FAIL]:J.READY,[Y.STOP]:J.IDLE,[Y.DISPOSE]:J.DISPOSED},[J.TRANSITION_STARTED]:{[Y.NAVIGATE]:J.TRANSITION_STARTED,[Y.LEAVE_APPROVE]:J.LEAVE_APPROVED,[Y.CANCEL]:J.READY,[Y.FAIL]:J.READY,[Y.DISPOSE]:J.DISPOSED},[J.LEAVE_APPROVED]:{[Y.NAVIGATE]:J.TRANSITION_STARTED,[Y.COMPLETE]:J.READY,[Y.CANCEL]:J.READY,[Y.FAIL]:J.READY,[Y.DISPOSE]:J.DISPOSED},[J.DISPOSED]:{}}};function Qr(){return new Xr(Zr)}const X=`TREE_CHANGED`;function $r(e){return e instanceof Error?e:Error(String(e))}function ei(e,t,n){return new Promise((r,i)=>{let a=()=>{let e=n.reason;i(e instanceof G&&e.code===h.TRANSITION_CANCELLED?e:new G(h.TRANSITION_CANCELLED,{reason:e}))};if(n.aborted){a();return}n.addEventListener(`abort`,a,{once:!0}),Promise.allSettled(e).then(e=>{if(n.removeEventListener(`abort`,a),n.aborted)return;if(t!==void 0){i($r(t));return}let o=e.find(e=>e.status===`rejected`);if(o!==void 0){i($r(o.reason));return}r()})})}var ti=class{#e;#t;#n;#r;#i=[];#a=0;#o;#s;#c;#l;#u;constructor(e){this.#e=e.routerFSM,this.#t=e.emitter,this.#n=e.abortController,this.#o=void 0,this.#p()}static validateSubscribeListener(e){if(typeof e!=`function`)throw TypeError(`[router.subscribe] Expected a function. For Observable pattern use observable(router) from @real-router/rx`)}static validateSubscribeLeaveListener(e){if(typeof e!=`function`)throw TypeError(`[router.subscribeLeave] Expected a function`)}emitRouterStart(){this.#t.emit(v.ROUTER_START)}emitRouterStop(){this.#t.emit(v.ROUTER_STOP)}emitTransitionStart(e,t){this.#a++;try{this.#t.emit(v.TRANSITION_START,e,t)}finally{this.#a--}}emitTransitionSuccess(e,t,n){this.#a++;try{this.#t.emit(v.TRANSITION_SUCCESS,e,t,n)}finally{this.#a--}}emitTransitionError(e,t,n){this.#a++;try{this.#t.emit(v.TRANSITION_ERROR,e,t,n)}finally{this.#a--}}emitTransitionCancel(e,t){this.#a++;try{this.#t.emit(v.TRANSITION_CANCEL,e,t)}finally{this.#a--}}emitTransitionLeaveApprove(e,t){this.#a++;try{this.#t.emit(v.TRANSITION_LEAVE_APPROVE,e,t)}finally{this.#a--}}isProcessing(){return this.#a>0}emitTreeChanged(e){this.#t.emit(X,e)}isEmittingTreeChanged(){return this.#t.isDispatching(X)}subscribeTreeChanged(e){if(this.isDisposed())throw new G(h.ROUTER_DISPOSED);return this.#t.on(X,t=>{e(t)})}treeChangedListenerCount(){return this.#t.listenerCount(X)}sendStart(){this.#e.send(Y.START)}sendStop(){this.#e.send(Y.STOP)}sendDispose(){this.#e.send(Y.DISPOSE)}sendStarted(){this.#e.send(Y.STARTED)}sendNavigate(e,t){this.#o=e,this.#e.send(Y.NAVIGATE,{toState:e,fromState:t})}sendComplete(e,t,n={}){this.#e.send(Y.COMPLETE,{toState:e,fromState:t,opts:n}),this.#o=void 0}sendLeaveApprove(e,t){this.#e.send(Y.LEAVE_APPROVE,{toState:e,fromState:t})}sendFail(e,t,n){this.#s=e,this.#c=t,this.#l=n,this.#e.send(Y.FAIL),this.#o=void 0}sendFailSafe(e,t,n){this.isReady()?this.sendFail(e,t,n):this.emitTransitionError(e,t,n)}sendCancel(e,t,n){this.#s=e,this.#c=t,this.#u=n,this.#e.send(Y.CANCEL),this.#o=void 0}canBeginTransition(){return this.#e.canSend(Y.NAVIGATE)}canStart(){return this.#e.canSend(Y.START)}canCancel(){return this.#e.canSend(Y.CANCEL)}isActive(){let e=this.#e.getState();return e!==J.IDLE&&e!==J.DISPOSED}isDisposed(){return this.#e.getState()===J.DISPOSED}isTransitioning(){let e=this.#e.getState();return e===J.TRANSITION_STARTED||e===J.LEAVE_APPROVED}isLeaveApproved(){return this.#e.getState()===J.LEAVE_APPROVED}isReady(){return this.#e.getState()===J.READY}isStarting(){return this.#e.getState()===J.STARTING}isIdle(){return this.#e.getState()===J.IDLE}addEventListener(e,t){return this.#d(e,`addEventListener`),this.#t.on(e,t)}subscribe(e){if(this.isDisposed())throw new G(h.ROUTER_DISPOSED);return this.#d(v.TRANSITION_SUCCESS,`subscribe`),this.#t.on(v.TRANSITION_SUCCESS,(t,n)=>e({route:t,previousRoute:n}))}subscribeLeave(e){if(this.isDisposed())throw new G(h.ROUTER_DISPOSED);this.#i.push(e);let t=!1;return()=>{if(t)return;t=!0;let n=this.#i.indexOf(e);n!==-1&&this.#i.splice(n,1)}}hasLeaveListeners(){return this.#i.length>0}hasPreCommitListeners(){return this.#t.listenerCount(v.TRANSITION_START)>0||this.#t.listenerCount(v.TRANSITION_LEAVE_APPROVE)>0}awaitLeaveListeners(e,t,n){if(t===void 0)return;let r=Object.freeze({route:t,nextRoute:e,signal:n}),i,a,o=[...this.#i];this.#a++;try{for(let e of o)try{let t=e(r);t!==void 0&&typeof t.then==`function`&&(i??=[],i.push(t))}catch(e){a===void 0&&(a=e)}}finally{this.#a--}if(i===void 0){if(a!==void 0)throw $r(a);return}return ei(i,a,n)}clearAll(){this.#t.clearAll(),this.#i.length=0}setLimits(e){this.#t.setLimits(e)}setValidatorAccessor(e){this.#r=e}sendCancelIfPossible(e,t){let n=this.#o;!this.canCancel()||n===void 0||this.sendCancel(n,e,t)}#d(e,t){let n=this.#r?.();n&&n.eventBus.validateCountThresholds(this.#t.listenerCount(e)+1,e,t)}#f(){this.emitTransitionError(this.#s,this.#c,this.#l),this.#s=void 0,this.#c=void 0,this.#l=void 0}#p(){let e=this.#e;e.on(J.STARTING,Y.STARTED,()=>{this.emitRouterStart()}),e.on(J.READY,Y.STOP,()=>{this.emitRouterStop()});let t=e=>{this.emitTransitionStart(e.toState,e.fromState)};e.on(J.READY,Y.NAVIGATE,t),e.on(J.TRANSITION_STARTED,Y.NAVIGATE,t),e.on(J.LEAVE_APPROVED,Y.NAVIGATE,t),e.on(J.TRANSITION_STARTED,Y.LEAVE_APPROVE,e=>{this.emitTransitionLeaveApprove(e.toState,e.fromState)}),e.on(J.LEAVE_APPROVED,Y.COMPLETE,e=>{this.emitTransitionSuccess(e.toState,e.fromState,e.opts)});let n=()=>{let e=this.#s,t=this.#u;this.#u=void 0,this.#n(t),e!==void 0&&this.emitTransitionCancel(e,this.#c)};e.on(J.TRANSITION_STARTED,Y.CANCEL,n),e.on(J.LEAVE_APPROVED,Y.CANCEL,n),e.on(J.LEAVE_APPROVED,Y.FAIL,()=>{this.#f()}),e.on(J.STARTING,Y.FAIL,()=>{this.#f()}),e.on(J.READY,Y.FAIL,()=>{this.#f()}),e.on(J.TRANSITION_STARTED,Y.FAIL,()=>{this.#f()})}};const ni=new G(h.ROUTER_ALREADY_STARTED),ri={maxListeners:0,warnListeners:0};var ii=class{#e=new Map;#t=new Set;#n=null;#r=ri;#i;#a;constructor(e){e?.limits&&(this.#r=e.limits),this.#i=e?.onListenerError??null,this.#a=e?.onListenerWarn??null}static validateCallback(e,t){if(typeof e!=`function`)throw TypeError(`Expected callback to be a function for event ${t}`)}setLimits(e){this.#r=e}on(e,t){let n=this.#e.get(e),r=n?.size??0;if(n?.has(t))throw Error(`Duplicate listener for "${e}"`);let{maxListeners:i,warnListeners:a}=this.#r;if(i!==0&&r>=i)throw Error(`Listener limit (${i}) reached for "${e}"`);a!==0&&r===a&&this.#a!==null&&(this.#n??=new Set,this.#n.has(e)||(this.#a(e,a),this.#n.add(e)));let o=n;return o===void 0&&(o=new Set,this.#e.set(e,o)),o.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.#e.get(e);n&&(n.delete(t),n.size===0&&(this.#e.delete(e),this.#n?.delete(e)))}emit(e,t,n,r,i){let a=this.#e.get(e);if(!a||a.size===0||this.#t.has(e))return;let o=arguments.length-1;this.#t.add(e);try{if(a.size===1){let[s]=a;this.#o(e,s,o,t,n,r,i)}else{let s=[...a];for(let a of s)this.#o(e,a,o,t,n,r,i)}}finally{this.#t.delete(e)}}clearAll(){this.#e.clear(),this.#n=null}listenerCount(e){return this.#e.get(e)?.size??0}isDispatching(e){return this.#t.has(e)}#o(e,t,n,r,i,a,o){try{let s=this.#s(t,n,r,i,a,o);s!=null&&typeof s.then==`function`&&Promise.resolve(s).catch(t=>{this.#i?.(e,t)})}catch(t){this.#i?.(e,t)}}#s(e,t,n,r,i,a){switch(t){case 0:return e();case 1:return e(n);case 2:return e(n,r);case 3:return e(n,r,i);default:return e(n,r,i,a)}}};const ai=Object.freeze({log:0,warn:1,error:2}),Z=Object.freeze({all:0,"warn-error":1,"error-only":2,none:3});var oi=class{#e={level:`all`,callbackIgnoresLevel:!1};#t=0;#n=!1;constructor(e){e&&this.configure(e)}configure(e){let t=e.level;if(t!==void 0){if(!Object.hasOwn(Z,t))throw Error(`Invalid log level: "${t}". Valid levels are: ${Object.keys(Z).join(`, `)}`);this.#e.level=t,this.#t=Z[t]}Object.hasOwn(e,`callback`)&&(this.#e.callback=e.callback);let n=e.callbackIgnoresLevel;n!==void 0&&(this.#e.callbackIgnoresLevel=n)}getConfig(){return{level:this.#e.level,callback:this.#e.callback,callbackIgnoresLevel:this.#e.callbackIgnoresLevel}}log(e,t,...n){this.#r(`log`,e,t,n)}warn(e,t,...n){this.#r(`warn`,e,t,n)}error(e,t,...n){this.#r(`error`,e,t,n)}#r(e,t,n,r){if(this.#e.level===`none`&&!this.#e.callbackIgnoresLevel)return;let i=ai[e]<this.#t;i||this.#i(e,t,n,r),this.#a(e,t,n,i,r)}#i(e,t,n,r){if(typeof console<`u`&&typeof console[e]==`function`){let i=t?`[${t}] ${n}`:n;console[e](i,...r)}}#a(e,t,n,r,i){if(!(!this.#e.callback||!this.#e.callbackIgnoresLevel&&r)&&!this.#n){this.#n=!0;try{let r=this.#e.callback(e,t,n,...i);r!=null&&typeof r.then==`function`&&Promise.resolve(r).catch(e=>{this.#o(`[Logger] Error in async callback:`,e)})}catch(e){this.#o(`[Logger] Error in callback:`,e)}finally{this.#n=!1}}}#o(e,t){typeof console<`u`&&typeof console.error==`function`&&console.error(e,t)}};function si(e){let t=ci(e),n=mi(e),r=()=>f(e.router).validator;li(e),ui(e,r),di(e,t,r),fi(e,n,r),pi(e,t,r),hi(e,n),gi(e),_i(e,n)}function ci(e){let{router:t,dependenciesStore:n}=e,r=e=>n.dependencies[e];return e=>e(t,r)}function li(e){e.dependenciesStore.limits=e.limits,e.eventBus.setLimits({maxListeners:e.limits.maxListeners,warnListeners:e.limits.warnListeners})}function ui(e,t){e.eventBus.setValidatorAccessor(t)}function di(e,t,n){let r={logger:f(e.router).logger,compileFactory:t,getValidator:n};e.routeLifecycle.setDependencies(r)}function fi(e,t,n){let r={logger:f(e.router).logger,getValidator:n,port:t,addActivateGuard:(t,n,r)=>{e.routeLifecycle.addCanActivate(t,n,!0,r)},addDeactivateGuard:(t,n,r)=>{e.routeLifecycle.addCanDeactivate(t,n,!0,r)},compileGuard:(t,n)=>e.routeLifecycle.compileGuardFactory(t,n),getState:()=>e.state.get(),areStatesEqual:(t,n,r)=>e.state.areStatesEqual(t,n,r),getDependency:t=>e.dependenciesStore.dependencies[t]};e.routes.setDependencies(r),e.routes.setLifecycleNamespace(e.routeLifecycle)}function pi(e,t,n){let r={logger:f(e.router).logger,addEventListener:(t,n)=>e.eventBus.addEventListener(t,n),canNavigate:()=>e.eventBus.canBeginTransition(),compileFactory:t,getValidator:n};e.plugins.setDependencies(r)}function mi(e){let t=f(e.router),n=e.routes.getStore(),r=(e,n)=>{t.validator?.state.reportUndeclaredParamKey(e,n)},i=(e,n)=>{t.validator?.state.reportDroppedQueryKey(e,n)};return{resolveForward:(e,n,r)=>t.forwardState(e,n,r),defaultParams:e=>n.config.defaultParams[e],defaultSearch:e=>n.config.defaultSearch[e],buildPath:(e,n,r)=>t.buildPath(e,n,r),queryNames:t=>e.routes.getQueryParams(t),pathNames:t=>e.routes.hasRoute(t)?e.routes.getUrlParams(t):void 0,admitsUndeclaredQuery:()=>e.options.get().queryParamsMode===`loose`,get reportDroppedQueryKey(){return t.validator?i:void 0},get reportUndeclaredParamKey(){return t.validator?r:void 0}}}function hi(e,t){let n={logger:f(e.router).logger,getOptions:()=>e.options.get(),hasRoute:t=>e.routes.hasRoute(t),getQueryParams:t=>e.routes.getQueryParams(t),getMetaForState:t=>e.routes.getMetaForState(t),getState:()=>e.state.get(),setState:t=>{e.state.set(t)},buildNavigateState:(n,r,i)=>{f(e.router).validator?.routes.validateStateBuilderArgs(n,r,`navigate`);let a=F(t,n,r,i,{diagnoseUndeclared:!0});if(e.routes.getMetaForState(a.name)!==void 0)return L(a,{path:I(a,t),skipFreeze:!0})},resolveDefault:()=>{let t=e.options.get(),n=f(e.router),r=P(t.defaultRoute,t=>e.dependenciesStore.dependencies[t]),i=P(t.defaultParams,t=>e.dependenciesStore.dependencies[t]),a=P(t.defaultSearch,t=>e.dependenciesStore.dependencies[t]);return typeof t.defaultRoute==`function`&&n.validator?.options.validateResolvedDefaultRoute(r,n.routeGetStore()),{route:r,params:i,search:a}},startTransition:(t,n)=>{e.eventBus.sendNavigate(t,n)},cancelNavigation:t=>{e.eventBus.sendCancelIfPossible(e.state.get(),t)},sendTransitionDone:(t,n,r)=>{e.eventBus.sendComplete(t,n,r)},sendTransitionFail:(t,n,r)=>{e.eventBus.sendFail(t,n,r)},emitTransitionError:(t,n,r)=>{e.eventBus.sendFailSafe(t,n,r)},emitTransitionSuccess:(t,n,r)=>{e.eventBus.emitTransitionSuccess(t,n,r)},sendLeaveApprove:(t,n)=>{e.eventBus.sendLeaveApprove(t,n)},canNavigate:()=>e.eventBus.canBeginTransition(),getLifecycleFunctions:()=>e.routeLifecycle.getFunctions(),isActive:()=>e.router.isActive(),isTransitioning:()=>e.eventBus.isTransitioning(),clearCanDeactivate:t=>{e.routeLifecycle.clearCanDeactivate(t,`external`)},hasLeaveListeners:()=>e.eventBus.hasLeaveListeners(),hasPreCommitListeners:()=>e.eventBus.hasPreCommitListeners(),awaitLeaveListeners:(t,n,r)=>e.eventBus.awaitLeaveListeners(t,n,r)};e.navigation.setDependencies(n)}function gi(e){e.lifecycle.setDependencies({getOptions:()=>e.options.get(),navigateToState:(t,n)=>e.navigation.navigateToState(t,n),navigateToNotFound:t=>e.navigation.navigateToNotFound(t),clearState:()=>{e.state.set(void 0)},matchPath:t=>e.routes.matchPath(t,e.options.get()),completeStart:()=>{e.eventBus.sendStarted()},isIdle:()=>e.eventBus.isIdle(),emitTransitionError:(t,n,r)=>{e.eventBus.sendFail(t,n,r)}})}function _i(e,t){e.state.setDependencies({port:()=>t,getUrlParams:t=>e.routes.getUrlParams(t)})}const Q=Object.freeze({}),vi=new Set([h.SAME_STATES,h.TRANSITION_CANCELLED,h.ROUTER_NOT_STARTED,h.ROUTE_NOT_FOUND,h.CANNOT_ACTIVATE,h.CANNOT_DEACTIVATE]);var yi=class r{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;constructor(n=[],a={},o={}){let{logger:s,...l}=a;s&&ce(s);let u=new oi(s);this.#u=e=>{r.#f(e)||u.error(`router.navigate`,`Unexpected navigation error`,e)},this.#d=e=>{r.#f(e)||u.error(`router.start`,`Unexpected start error`,e)},en.validateOptionsIsObject(a),ie(o),n.length>0&&S(n),this.#e=new en(l),this.#t=he(l.limits),this.#n=ge(o),this.#r=new nn,this.#i=new br(n,bi(this.#e.get()),u),this.#a=new mn,this.#o=new cn,this.#s=new qr,this.#c=new Yr;let d=Qr(),f=new ii({onListenerError:(e,t)=>{u.error(`Router`,`Error in listener for ${e}:`,t)},onListenerWarn:(e,t)=>{u.warn(`router.addEventListener`,`Event "${e}" has ${t} listeners — possible memory leak`)}});this.#l=new ti({routerFSM:d,emitter:f,abortController:e=>{this.#s.abortCurrentController(e)}});let p=new Map,m=i(`forwardState`,(e,t,n)=>this.#i.forwardState(e,t,n),p);t(this,{logger:u,makeState:(e,t,n,r)=>this.#r.makeState(e,t,n,r),getMetaForState:e=>this.#i.getMetaForState(e),getQueryParams:e=>this.#i.getQueryParams(e),forwardState:((e,t,n)=>{let r=m(e,t,n);return c(`forwardState`,r.name,r.params,this.#i.getQueryParams(r.name),()=>r.name===e?"the `params` bag leaving the forwardState chain":`the \`params\` bag leaving the forwardState chain (forwarded here from "${e}")`),{name:r.name,params:r.params??b,search:r.search}}),buildStateResolved:(e,t)=>this.#i.buildStateResolved(e,t),port:()=>this.#i.getPort(),matchPath:(e,t)=>this.#i.matchPath(e,t),getOptions:()=>this.#e.get(),addEventListener:(e,t)=>this.#l.addEventListener(e,t),treeChanged:{emit:e=>{this.#l.emitTreeChanged(e)},subscribe:e=>this.#l.subscribeTreeChanged(e),listenerCount:()=>this.#l.treeChangedListenerCount(),isEmitting:()=>this.#l.isEmittingTreeChanged()},buildPath:i(`buildPath`,(e,t,n)=>this.#i.buildPath(e,t??b,n,this.#e.get()),p),emitTransitionError:e=>{this.#l.sendFailSafe(void 0,this.#r.get(),e)},emitTransitionSuccess:(e,t,n)=>{this.#l.emitTransitionSuccess(e,t,n)},navigateToNotFound:e=>this.#s.navigateToNotFound(e),start:e(`start`,e=>this.#c.start(e),p),navigateToState:(e,t)=>{this.#m();let n=this.#s.navigateToState(e,t??Q);return this.#s.lastSyncResolved?this.#s.lastSyncResolved=!1:this.#s.lastSyncRejected?this.#s.lastSyncRejected=!1:this.#p(n),n},interceptors:p,setRootPath:e=>{this.#i.setRootPath(e)},getRootPath:()=>this.#i.getStore().rootPath,getTree:()=>this.#i.getStore().tree,isDisposed:()=>this.#l.isDisposed(),validator:null,dependenciesGetStore:()=>this.#n,getCloneState:()=>({options:{...this.#e.get()},dependencies:{...this.#n.dependencies},pluginFactories:this.#o.getAll(),loggerConfig:u.getConfig()}),routeGetStore:()=>this.#i.getStore(),getStateName:()=>this.#r.get()?.name,isTransitioning:()=>this.#l.isTransitioning(),clearState:()=>{this.#r.set(void 0)},setState:e=>{this.#r.set(e)},routerExtensions:[],contextClaimRecords:new Set,hydrationState:null}),si({router:this,options:this.#e,limits:this.#t,dependenciesStore:this.#n,state:this.#r,routes:this.#i,routeLifecycle:this.#a,plugins:this.#o,navigation:this.#s,lifecycle:this.#c,eventBus:this.#l}),this.isActiveRoute=this.isActiveRoute.bind(this),this.buildPath=this.buildPath.bind(this),this.getState=this.getState.bind(this),this.getPreviousState=this.getPreviousState.bind(this),this.areStatesEqual=this.areStatesEqual.bind(this),this.shouldUpdateNode=this.shouldUpdateNode.bind(this),this.isActive=this.isActive.bind(this),this.start=this.start.bind(this),this.stop=this.stop.bind(this),this.dispose=this.dispose.bind(this),this.canNavigateTo=this.canNavigateTo.bind(this),this.usePlugin=this.usePlugin.bind(this),this.navigate=this.navigate.bind(this),this.navigateToDefault=this.navigateToDefault.bind(this),this.navigateToNotFound=this.navigateToNotFound.bind(this),this.subscribe=this.subscribe.bind(this),this.subscribeLeave=this.subscribeLeave.bind(this),this.isLeaveApproved=this.isLeaveApproved.bind(this);try{this.#i.flushPendingGuards()}catch(e){throw this.dispose(),e}}isActiveRoute(e,t,n,r,i){return f(this).validator?.routes.validateIsActiveRouteArgs(e,t,r,i),f(this).validator?.routes.validateRouteName(e,`isActiveRoute`),e===``?(f(this).logger.warn(`real-router`,`isActiveRoute("") called with empty string. Root node is not considered a parent of any route.`),!1):this.#i.isActiveRoute(e,t,n,r,i)}buildPath(e,t,n){let r=f(this);return r.validator?.routes.validateBuildPathArgs(e),r.validator?.navigation.validateParams(t,`buildPath`),r.buildPath(e,me(t),n)}getState(){return this.#r.get()}getPreviousState(){return this.#r.getPrevious()}areStatesEqual(e,t,n=!0){return f(this).validator?.state.validateAreStatesEqualArgs(e,t,n),this.#r.areStatesEqual(e,t,n)}shouldUpdateNode(e){return f(this).validator?.routes.validateShouldUpdateNodeArgs(e),br.shouldUpdateNode(e,e=>this.#i.getMetaForState(e))}isActive(){return this.#l.isActive()}start(e){if(!this.#l.canStart())return Promise.reject(ni);f(this).validator?.navigation.validateStartArgs(e),this.#l.sendStart();let t;try{let n=f(this).start(e);t=typeof n?.then==`function`?n:Promise.reject(TypeError("[router.start] a `start` interceptor returned without calling next(). Every start interceptor must return `next(path)`."))}catch(e){t=Promise.reject(e)}let n=t.catch(e=>this.#h(e));return this.#p(n,this.#d),n}stop(){return this.#l.sendCancelIfPossible(this.#r.get()),!this.#l.isReady()&&!this.#l.isTransitioning()&&!this.#l.isStarting()?this:(this.#c.stop(),this.#l.sendStop(),this)}dispose(){if(this.#l.isDisposed())return;this.#l.sendCancelIfPossible(this.#r.get()),(this.#l.isReady()||this.#l.isTransitioning())&&(this.#c.stop(),this.#l.sendStop()),this.#l.sendDispose(),this.#l.clearAll(),this.#o.disposeAll();let e=f(this);for(let t of e.routerExtensions)for(let e of t.keys)delete this[e];e.routerExtensions.length=0,e.contextClaimRecords.clear(),e.interceptors.clear(),this.#i.clearRoutes(),this.#a.clearAll(),this.#r.reset(),this.#n.dependencies=Object.create(null),this.#g()}canNavigateTo(e,t,n){let r=f(this);if(r.validator?.routes.validateRouteName(e,`canNavigateTo`),r.validator?.navigation.validateParams(t,`canNavigateTo`),!this.#i.hasRoute(e)||a(t,this.#i.getQueryParams(e))!==void 0)return!1;let i=this.#i.getPort(),o;try{o=F(i,e,t??b,n)}catch(t){return r.logger.warn(`router.canNavigateTo`,`Resolving route "${e}" threw while answering the predicate; treating the route as unreachable.`,t),!1}let s;try{s=L(o,{path:I(o,i),skipFreeze:!0})}catch{return!1}let c=this.#r.get(),{toDeactivate:l,toActivate:u}=W(s,c,e=>this.#i.getMetaForState(e));return this.#a.canNavigateTo(l,u,s,c)}usePlugin(...e){if(this.#l.isDisposed())throw new G(h.ROUTER_DISPOSED);let t=e.filter(Boolean);if(t.length===0)return()=>{};let n=f(this);n.validator?.plugins.validatePluginLimit(this.#o.count(),this.#t);for(let e of t)n.validator?.plugins.validateNoDuplicatePlugins(e,this.#o.getAll());return this.#o.use(...t)}subscribe(e){return ti.validateSubscribeListener(e),this.#l.subscribe(e)}subscribeLeave(e){return ti.validateSubscribeLeaveListener(e),this.#l.subscribeLeave(e)}isLeaveApproved(){return this.#l.isLeaveApproved()}navigate(e,t,r,i){this.#m();let a=f(this),o,s,c,l;typeof e==`object`&&e?(o=e.name,s=e.params,c=e.search,l=t??Q):(o=e,s=t,c=r,l=i??Q),n(a,`navigate`,o,s),a.validator?.navigation.validateNavigateArgs(o),a.validator?.navigation.validateParams(s,`navigate`),a.validator?.navigation.validateNavigationOptions(l,`navigate`);let u=this.#s.navigate(o,s??b,c,l);return this.#s.lastSyncResolved?this.#s.lastSyncResolved=!1:this.#s.lastSyncRejected?this.#s.lastSyncRejected=!1:this.#p(u),u}navigateToDefault(e){this.#m();let t=f(this);t.validator?.navigation.validateNavigateToDefaultArgs(e);let n=e??Q;t.validator?.navigation.validateNavigationOptions(n,`navigateToDefault`);let r=this.#s.navigateToDefault(n);return this.#s.lastSyncResolved?this.#s.lastSyncResolved=!1:this.#s.lastSyncRejected?this.#s.lastSyncRejected=!1:this.#p(r),r}navigateToNotFound(e){if(this.#m(),!this.#l.isActive())throw new G(h.ROUTER_NOT_STARTED);if(e!==void 0&&typeof e!=`string`)throw TypeError(`[router.navigateToNotFound] path must be a string, got ${typeof e}`);if(e!==void 0)return this.#s.navigateToNotFound(e);let t=this.#r.get();if(t===void 0)throw new G(h.ROUTER_NOT_STARTED,{message:`[router.navigateToNotFound] cannot derive the path before the start navigation commits — pass an explicit path`});return this.#s.navigateToNotFound(t.path)}static#f(e){return e instanceof G&&vi.has(e.code)}#p(e,t=this.#u){e.catch(t)}#m(){if(this.#l.isProcessing())throw new G(h.REENTRANT_NAVIGATION)}#h(e){throw this.#l.isReady()&&this.#r.get()===void 0?(this.#c.stop(),this.#l.sendStop()):this.#l.isStarting()&&this.#l.sendFail(void 0,void 0,e),e}#g(){this.navigate=$,this.navigateToDefault=$,this.navigateToNotFound=$,this.start=$,this.stop=$,this.usePlugin=$,this.subscribe=$,this.subscribeLeave=$,this.canNavigateTo=$}};function $(){throw new G(h.ROUTER_DISPOSED)}function bi(e){return{strictTrailingSlash:e.trailingSlash===`strict`,caseSensitive:e.caseSensitive,strictQueryParams:e.queryParamsMode===`strict`,urlParamsEncoding:e.urlParamsEncoding,queryParams:e.queryParams}}export{v as A,F as C,ee as D,S as E,g as O,I as S,Dt as T,En as _,Gn as a,vn as b,V as c,Jn as d,Qn as f,Dn as g,Mn as h,Zn as i,h as k,Un as l,Xn as m,G as n,Hn as o,jn as p,W as r,Wn as s,yi as t,qn as u,gn as v,Et as w,L as x,yn as y};
|
|
2
|
+
//# sourceMappingURL=Router-DEpNuwBW.mjs.map
|