mobx-route 2.0.0 → 2.1.1

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/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const mobxLocationHistory = require("mobx-location-history");
4
- const virtualRoute = require("./virtual-route-DCnOqDz5.cjs");
4
+ const virtualRoute = require("./virtual-route-BB_GnH90.cjs");
5
5
  const isRouteEntity = (route) => route && "isOpened" in route;
6
6
  exports.Route = virtualRoute.Route;
7
7
  exports.RouteGroup = virtualRoute.RouteGroup;
package/index.d.ts CHANGED
@@ -398,7 +398,15 @@ declare class Route<TPath extends string, TInputParams extends InputPathParams<T
398
398
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)
399
399
  */
400
400
  get params(): TOutputParams | null;
401
- protected get isPathMatched(): boolean;
401
+ protected get isConfigPathMatched(): boolean;
402
+ /**
403
+ * Whether the current URL path includes this route's path pattern.
404
+ * Uses prefix matching (`end: false`), so `/users` matches `/users/123`.
405
+ * Useful for navigation menu highlighting.
406
+ *
407
+ * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ispathmatched)
408
+ */
409
+ get isPathMatched(): boolean;
402
410
  /**
403
411
  * Defines the "open" state for this route.
404
412
  *
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "mobx-location-history";
2
- import { R, a, b, V, c, d, e, g, r } from "./virtual-route-C21P-S6I.js";
2
+ import { R, a, b, V, c, d, e, g, r } from "./virtual-route-C3nG6mQb.js";
3
3
  const isRouteEntity = (route) => route && "isOpened" in route;
4
4
  export {
5
5
  R as Route,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx-route",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "keywords": [
5
5
  "mobx",
6
6
  "react",
@@ -22,7 +22,7 @@
22
22
  "url": "https://github.com/js2me/mobx-route"
23
23
  },
24
24
  "dependencies": {
25
- "mobx-location-history": "^9.4.1",
25
+ "mobx-location-history": "^9.4.2",
26
26
  "path-to-regexp": "^8.4.2",
27
27
  "yummies": "^7.20.1"
28
28
  },
@@ -67,13 +67,13 @@
67
67
  "require": "./view-model.cjs",
68
68
  "default": "./view-model.js"
69
69
  },
70
- "./virtual-route-C21P-S6I": {
71
- "import": "./virtual-route-C21P-S6I.js",
72
- "default": "./virtual-route-C21P-S6I.js"
70
+ "./virtual-route-BB_GnH90": {
71
+ "require": "./virtual-route-BB_GnH90.cjs",
72
+ "default": "./virtual-route-BB_GnH90.cjs"
73
73
  },
74
- "./virtual-route-DCnOqDz5": {
75
- "require": "./virtual-route-DCnOqDz5.cjs",
76
- "default": "./virtual-route-DCnOqDz5.cjs"
74
+ "./virtual-route-C3nG6mQb": {
75
+ "import": "./virtual-route-C3nG6mQb.js",
76
+ "default": "./virtual-route-C3nG6mQb.js"
77
77
  }
78
78
  },
79
79
  "files": [
package/view-model.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const mobx = require("mobx");
4
4
  const mobxViewModel = require("mobx-view-model");
5
- const virtualRoute = require("./virtual-route-DCnOqDz5.cjs");
5
+ const virtualRoute = require("./virtual-route-BB_GnH90.cjs");
6
6
  const annotations = [
7
7
  [mobx.computed.struct, "pathParams"],
8
8
  [mobx.computed, "query"]
package/view-model.d.ts CHANGED
@@ -227,7 +227,15 @@ declare class Route<TPath extends string, TInputParams extends InputPathParams<T
227
227
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)
228
228
  */
229
229
  get params(): TOutputParams | null;
230
- protected get isPathMatched(): boolean;
230
+ protected get isConfigPathMatched(): boolean;
231
+ /**
232
+ * Whether the current URL path includes this route's path pattern.
233
+ * Uses prefix matching (`end: false`), so `/users` matches `/users/123`.
234
+ * Useful for navigation menu highlighting.
235
+ *
236
+ * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ispathmatched)
237
+ */
238
+ get isPathMatched(): boolean;
231
239
  /**
232
240
  * Defines the "open" state for this route.
233
241
  *
package/view-model.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { computed } from "mobx";
2
2
  import { ViewModelBase, applyObservable } from "mobx-view-model";
3
- import { r as routeConfig } from "./virtual-route-C21P-S6I.js";
3
+ import { r as routeConfig } from "./virtual-route-C3nG6mQb.js";
4
4
  const annotations = [
5
5
  [computed.struct, "pathParams"],
6
6
  [computed, "query"]
@@ -33,6 +33,7 @@ const routeConfig = complex.createGlobalDynamicConfig(
33
33
  const annotations$3 = [
34
34
  [
35
35
  mobx.computed,
36
+ "isConfigPathMatched",
36
37
  "isPathMatched",
37
38
  "isOpened",
38
39
  "isOpening",
@@ -61,9 +62,13 @@ class Route {
61
62
  if (this.config.abortSignal?.aborted) {
62
63
  this.isDestroyed = true;
63
64
  } else {
64
- this.disposer = mobx.reaction(() => this.isPathMatched, this.checkPathMatch, {
65
- fireImmediately: true
66
- });
65
+ this.disposer = mobx.reaction(
66
+ () => this.isConfigPathMatched,
67
+ this.checkPathMatch,
68
+ {
69
+ fireImmediately: true
70
+ }
71
+ );
67
72
  this.updateDisposer = mobx.reaction(
68
73
  () => {
69
74
  if (this.status !== "open-confirmed") return void 0;
@@ -180,7 +185,7 @@ class Route {
180
185
  if (this.status === "opening") {
181
186
  return true;
182
187
  }
183
- if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
188
+ if (this.isDestroyed || !this.isConfigPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
184
189
  return false;
185
190
  }
186
191
  return this.status === "closed" || this.status === "unknown";
@@ -223,16 +228,38 @@ class Route {
223
228
  }
224
229
  return this.parsedPathData?.params ?? null;
225
230
  }
226
- get isPathMatched() {
231
+ get isConfigPathMatched() {
227
232
  return this.parsedPathData !== null;
228
233
  }
234
+ /**
235
+ * Whether the current URL path includes this route's path pattern.
236
+ * Uses prefix matching (`end: false`), so `/users` matches `/users/123`.
237
+ * Useful for navigation menu highlighting.
238
+ *
239
+ * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ispathmatched)
240
+ */
241
+ get isPathMatched() {
242
+ let pathname = this.isHash ? this.history.location.hash.slice(1) : this.history.location.pathname;
243
+ if (this.baseUrl) {
244
+ if (!pathname.startsWith(this.baseUrl)) return false;
245
+ pathname = pathname.replace(this.baseUrl, "");
246
+ }
247
+ if (this.pathDeclaration === "" || this.pathDeclaration === "/") {
248
+ return pathname === "/" || pathname === "" || pathname.startsWith("/");
249
+ }
250
+ const matcher = pathToRegexp.match(this.tokenData, {
251
+ end: false,
252
+ ...this.config.matchOptions
253
+ });
254
+ return matcher(pathname) !== false;
255
+ }
229
256
  /**
230
257
  * Defines the "open" state for this route.
231
258
  *
232
259
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)
233
260
  */
234
261
  get isOpened() {
235
- if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status !== "open-confirmed") {
262
+ if (this.isDestroyed || !this.isConfigPathMatched || this.params === null || this.status !== "open-confirmed") {
236
263
  return false;
237
264
  }
238
265
  return (
@@ -340,7 +367,7 @@ class Route {
340
367
  const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;
341
368
  const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;
342
369
  const params = typeof args[0] === "string" ? void 0 : args[0];
343
- const url = typeof args[0] === "string" ? args[0] : this.createUrl(args[0], query);
370
+ const url = typeof args[0] === "string" ? args[0] : this.createUrl(args[0], query, false);
344
371
  const trx = {
345
372
  url,
346
373
  params,
@@ -407,7 +434,8 @@ class Route {
407
434
  }
408
435
  const newUrl = this.createUrl(
409
436
  trx.params,
410
- trx.query
437
+ trx.query,
438
+ false
411
439
  );
412
440
  if (newUrl !== trx.url) {
413
441
  trx.url = newUrl;
@@ -428,7 +456,7 @@ class Route {
428
456
  this.history.push(trx.url, trx.state);
429
457
  }
430
458
  }
431
- if (this.isPathMatched) {
459
+ if (this.isConfigPathMatched) {
432
460
  const wasAlreadyConfirmed = this.status === "open-confirmed";
433
461
  mobx.runInAction(() => {
434
462
  this.status = "open-confirmed";
@@ -820,4 +848,4 @@ exports.createRouter = createRouter;
820
848
  exports.createVirtualRoute = createVirtualRoute;
821
849
  exports.groupRoutes = groupRoutes;
822
850
  exports.routeConfig = routeConfig;
823
- //# sourceMappingURL=virtual-route-DCnOqDz5.cjs.map
851
+ //# sourceMappingURL=virtual-route-BB_GnH90.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-route-BB_GnH90.cjs","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { comparer, computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isConfigPathMatched',\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: AnyRoute | null;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n private isUpdate = false;\n private updateDisposer?: VoidFunction;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TQueryParams\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? null;\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.isConfigPathMatched,\n this.checkPathMatch,\n {\n fireImmediately: true,\n },\n );\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'open-confirmed') return undefined;\n return [this.parsedPathData, this.query.data] as const;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n if (!this.parsedPathData) return;\n this.config.afterUpdate?.(this.parsedPathData, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n *\n * Also true in the short gap after history already matches this route but\n * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every\n * route looks closed for one tick and RouteViewGroup unmounts the page.\n */\n get isOpening() {\n if (this.status === 'opening') {\n return true;\n }\n\n if (\n this.isDestroyed ||\n !this.isConfigPathMatched ||\n this.params === null ||\n this.status === 'open-confirmed' ||\n this.status === 'open-rejected'\n ) {\n return false;\n }\n\n return this.status === 'closed' || this.status === 'unknown';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n return result || null;\n }\n\n return (\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null\n );\n }\n\n protected get isConfigPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Whether the current URL path includes this route's path pattern.\n * Uses prefix matching (`end: false`), so `/users` matches `/users/123`.\n * Useful for navigation menu highlighting.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ispathmatched)\n */\n get isPathMatched(): boolean {\n let pathname = this.isHash\n ? this.history.location.hash.slice(1)\n : this.history.location.pathname;\n\n if (this.baseUrl) {\n if (!pathname.startsWith(this.baseUrl)) return false;\n pathname = pathname.replace(this.baseUrl, '');\n }\n\n // Root route always matches any path (prefix of everything)\n if (this.pathDeclaration === '' || this.pathDeclaration === '/') {\n return pathname === '/' || pathname === '' || pathname.startsWith('/');\n }\n\n const matcher = match(this.tokenData, {\n end: false,\n ...this.config.matchOptions,\n });\n return matcher(pathname) !== false;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isConfigPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedQueryParams extends Record<string, any> = TQueryParams,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n const result: ParamData = {};\n for (const [key, value] of Object.entries(params)) {\n if (value != null) {\n result[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n }\n return result;\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? ({ ...this.query.data, ...rawQuery } as Partial<TQueryParams>)\n : ((rawQuery ?? {}) as Partial<TQueryParams>);\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n : [\n params: TInputParams,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n ): Promise<void>;\n open(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({\n replace: args[1],\n query: args[2],\n } as RouteNavigateParams<TQueryParams>)\n : ((args[1] ?? {}) as RouteNavigateParams<TQueryParams>);\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = (\n mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery\n ) as Partial<TQueryParams> | undefined;\n\n const params = typeof args[0] === 'string' ? undefined : args[0];\n const url =\n typeof args[0] === 'string'\n ? args[0]\n : this.createUrl(args[0], query, false);\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url,\n params: params as TInputParams,\n replace,\n state: rawState ?? null,\n query,\n };\n\n this.isUpdate = this.status === 'open-confirmed';\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n this.isUpdate = false;\n }\n }\n\n /**\n * Updates the current route if it is already open.\n * Unlike `open`, this is a no-op if the route is not open,\n * defaults to `replace: true` instead of push,\n * and defaults to `mergeQuery: true` when no query params are provided.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#update)\n */\n update(\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n update(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async update(...args: any[]) {\n if (this.status !== 'open-confirmed') {\n return;\n }\n\n // Reuse current path params when omitted\n if (args[0] == null) {\n args[0] = this.parsedPathData?.params;\n }\n\n const secondArg = args[1];\n const isObjectParams = typeof secondArg === 'object' && secondArg !== null;\n\n if (isObjectParams) {\n args[1] = {\n replace: true,\n ...('query' in secondArg ? {} : { mergeQuery: true }),\n ...secondArg,\n };\n } else if (typeof secondArg === 'boolean') {\n if (args[2] === undefined) {\n args[1] = { replace: secondArg, mergeQuery: true };\n args.length = 2;\n }\n } else if (args.length === 1) {\n args[1] = { replace: true, mergeQuery: true };\n }\n\n return (this.open as (...args: any[]) => Promise<void>)(...args);\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(\n trx: NavigationTrx<TInputParams, TQueryParams>,\n ) {\n if (!this.isUpdate) {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n // Rebuild URL if beforeOpen mutated trx.params\n const newUrl = this.createUrl(\n trx.params as TInputParams,\n trx.query as AnyObject,\n false,\n );\n if (newUrl !== trx.url) {\n trx.url = newUrl;\n skipHistoryUpdate = false;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isConfigPathMatched) {\n const wasAlreadyConfirmed = this.status === 'open-confirmed';\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n if (this.isUpdate) {\n this.isUpdate = false;\n // afterUpdate handled by updateDisposer reaction\n } else if (!wasAlreadyConfirmed) {\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.parsedPathData, this);\n } else {\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n }\n // update() delegates to confirmOpening\n return;\n }\n\n // Set opening sync to avoid isOpened/isOpening flicker\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n // already confirmed\n if (this.status === 'open-confirmed') {\n return;\n }\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url: `${this.parsedPathData!.path}${buildSearchString(this.query.data)}`,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data as Partial<TQueryParams>,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n this.updateDisposer?.();\n this.updateDisposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TQueryParams>,\n) => new Route<TPath, TInputParams, TOutputParams, TQueryParams>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute', 'canNavigate'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * `true` if `open()` has a target to navigate to —\n * either an own index route or a nested `RouteGroup` that itself can navigate.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)\n */\n get canNavigate(): boolean {\n if (this.indexRoute) return true;\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n route.open(...args);\n return;\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import {\n action,\n comparer,\n computed,\n observable,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n> implements AbstractVirtualRoute<TParams, TQueryParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n private isUpdate = false;\n\n private updateDisposer?: VoidFunction;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'opened') return undefined;\n return this.query.data;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n this.config.afterUpdate?.(this.params, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [\n params?: Maybe<TParams>,\n extraParams?: VirtualOpenExtraParams<TQueryParams>,\n ]\n : [params: TParams, extraParams?: VirtualOpenExtraParams<TQueryParams>]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.isUpdate = this.status === 'opened';\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.params!, this);\n } else {\n this.config.afterOpen?.(this.params!, this);\n }\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n this.config.afterClose?.();\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n this.updateDisposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams, TQueryParams>(config);\n"],"names":["createGlobalDynamicConfig","isObservableHistory","createBrowserHistory","createQueryParams","annotations","computed","observable","applyObservable","reaction","comparer","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":"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"}
@@ -32,6 +32,7 @@ const routeConfig = createGlobalDynamicConfig(
32
32
  const annotations$3 = [
33
33
  [
34
34
  computed,
35
+ "isConfigPathMatched",
35
36
  "isPathMatched",
36
37
  "isOpened",
37
38
  "isOpening",
@@ -60,9 +61,13 @@ class Route {
60
61
  if (this.config.abortSignal?.aborted) {
61
62
  this.isDestroyed = true;
62
63
  } else {
63
- this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {
64
- fireImmediately: true
65
- });
64
+ this.disposer = reaction(
65
+ () => this.isConfigPathMatched,
66
+ this.checkPathMatch,
67
+ {
68
+ fireImmediately: true
69
+ }
70
+ );
66
71
  this.updateDisposer = reaction(
67
72
  () => {
68
73
  if (this.status !== "open-confirmed") return void 0;
@@ -179,7 +184,7 @@ class Route {
179
184
  if (this.status === "opening") {
180
185
  return true;
181
186
  }
182
- if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
187
+ if (this.isDestroyed || !this.isConfigPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
183
188
  return false;
184
189
  }
185
190
  return this.status === "closed" || this.status === "unknown";
@@ -222,16 +227,38 @@ class Route {
222
227
  }
223
228
  return this.parsedPathData?.params ?? null;
224
229
  }
225
- get isPathMatched() {
230
+ get isConfigPathMatched() {
226
231
  return this.parsedPathData !== null;
227
232
  }
233
+ /**
234
+ * Whether the current URL path includes this route's path pattern.
235
+ * Uses prefix matching (`end: false`), so `/users` matches `/users/123`.
236
+ * Useful for navigation menu highlighting.
237
+ *
238
+ * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ispathmatched)
239
+ */
240
+ get isPathMatched() {
241
+ let pathname = this.isHash ? this.history.location.hash.slice(1) : this.history.location.pathname;
242
+ if (this.baseUrl) {
243
+ if (!pathname.startsWith(this.baseUrl)) return false;
244
+ pathname = pathname.replace(this.baseUrl, "");
245
+ }
246
+ if (this.pathDeclaration === "" || this.pathDeclaration === "/") {
247
+ return pathname === "/" || pathname === "" || pathname.startsWith("/");
248
+ }
249
+ const matcher = match(this.tokenData, {
250
+ end: false,
251
+ ...this.config.matchOptions
252
+ });
253
+ return matcher(pathname) !== false;
254
+ }
228
255
  /**
229
256
  * Defines the "open" state for this route.
230
257
  *
231
258
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)
232
259
  */
233
260
  get isOpened() {
234
- if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status !== "open-confirmed") {
261
+ if (this.isDestroyed || !this.isConfigPathMatched || this.params === null || this.status !== "open-confirmed") {
235
262
  return false;
236
263
  }
237
264
  return (
@@ -339,7 +366,7 @@ class Route {
339
366
  const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;
340
367
  const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;
341
368
  const params = typeof args[0] === "string" ? void 0 : args[0];
342
- const url = typeof args[0] === "string" ? args[0] : this.createUrl(args[0], query);
369
+ const url = typeof args[0] === "string" ? args[0] : this.createUrl(args[0], query, false);
343
370
  const trx = {
344
371
  url,
345
372
  params,
@@ -406,7 +433,8 @@ class Route {
406
433
  }
407
434
  const newUrl = this.createUrl(
408
435
  trx.params,
409
- trx.query
436
+ trx.query,
437
+ false
410
438
  );
411
439
  if (newUrl !== trx.url) {
412
440
  trx.url = newUrl;
@@ -427,7 +455,7 @@ class Route {
427
455
  this.history.push(trx.url, trx.state);
428
456
  }
429
457
  }
430
- if (this.isPathMatched) {
458
+ if (this.isConfigPathMatched) {
431
459
  const wasAlreadyConfirmed = this.status === "open-confirmed";
432
460
  runInAction(() => {
433
461
  this.status = "open-confirmed";
@@ -821,4 +849,4 @@ export {
821
849
  groupRoutes as g,
822
850
  routeConfig as r
823
851
  };
824
- //# sourceMappingURL=virtual-route-C21P-S6I.js.map
852
+ //# sourceMappingURL=virtual-route-C3nG6mQb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-route-C3nG6mQb.js","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { comparer, computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isConfigPathMatched',\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: AnyRoute | null;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n private isUpdate = false;\n private updateDisposer?: VoidFunction;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TQueryParams\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? null;\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.isConfigPathMatched,\n this.checkPathMatch,\n {\n fireImmediately: true,\n },\n );\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'open-confirmed') return undefined;\n return [this.parsedPathData, this.query.data] as const;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n if (!this.parsedPathData) return;\n this.config.afterUpdate?.(this.parsedPathData, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n *\n * Also true in the short gap after history already matches this route but\n * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every\n * route looks closed for one tick and RouteViewGroup unmounts the page.\n */\n get isOpening() {\n if (this.status === 'opening') {\n return true;\n }\n\n if (\n this.isDestroyed ||\n !this.isConfigPathMatched ||\n this.params === null ||\n this.status === 'open-confirmed' ||\n this.status === 'open-rejected'\n ) {\n return false;\n }\n\n return this.status === 'closed' || this.status === 'unknown';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n return result || null;\n }\n\n return (\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null\n );\n }\n\n protected get isConfigPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Whether the current URL path includes this route's path pattern.\n * Uses prefix matching (`end: false`), so `/users` matches `/users/123`.\n * Useful for navigation menu highlighting.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ispathmatched)\n */\n get isPathMatched(): boolean {\n let pathname = this.isHash\n ? this.history.location.hash.slice(1)\n : this.history.location.pathname;\n\n if (this.baseUrl) {\n if (!pathname.startsWith(this.baseUrl)) return false;\n pathname = pathname.replace(this.baseUrl, '');\n }\n\n // Root route always matches any path (prefix of everything)\n if (this.pathDeclaration === '' || this.pathDeclaration === '/') {\n return pathname === '/' || pathname === '' || pathname.startsWith('/');\n }\n\n const matcher = match(this.tokenData, {\n end: false,\n ...this.config.matchOptions,\n });\n return matcher(pathname) !== false;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isConfigPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedQueryParams extends Record<string, any> = TQueryParams,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n const result: ParamData = {};\n for (const [key, value] of Object.entries(params)) {\n if (value != null) {\n result[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n }\n return result;\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? ({ ...this.query.data, ...rawQuery } as Partial<TQueryParams>)\n : ((rawQuery ?? {}) as Partial<TQueryParams>);\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n : [\n params: TInputParams,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n ): Promise<void>;\n open(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({\n replace: args[1],\n query: args[2],\n } as RouteNavigateParams<TQueryParams>)\n : ((args[1] ?? {}) as RouteNavigateParams<TQueryParams>);\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = (\n mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery\n ) as Partial<TQueryParams> | undefined;\n\n const params = typeof args[0] === 'string' ? undefined : args[0];\n const url =\n typeof args[0] === 'string'\n ? args[0]\n : this.createUrl(args[0], query, false);\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url,\n params: params as TInputParams,\n replace,\n state: rawState ?? null,\n query,\n };\n\n this.isUpdate = this.status === 'open-confirmed';\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n this.isUpdate = false;\n }\n }\n\n /**\n * Updates the current route if it is already open.\n * Unlike `open`, this is a no-op if the route is not open,\n * defaults to `replace: true` instead of push,\n * and defaults to `mergeQuery: true` when no query params are provided.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#update)\n */\n update(\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n update(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async update(...args: any[]) {\n if (this.status !== 'open-confirmed') {\n return;\n }\n\n // Reuse current path params when omitted\n if (args[0] == null) {\n args[0] = this.parsedPathData?.params;\n }\n\n const secondArg = args[1];\n const isObjectParams = typeof secondArg === 'object' && secondArg !== null;\n\n if (isObjectParams) {\n args[1] = {\n replace: true,\n ...('query' in secondArg ? {} : { mergeQuery: true }),\n ...secondArg,\n };\n } else if (typeof secondArg === 'boolean') {\n if (args[2] === undefined) {\n args[1] = { replace: secondArg, mergeQuery: true };\n args.length = 2;\n }\n } else if (args.length === 1) {\n args[1] = { replace: true, mergeQuery: true };\n }\n\n return (this.open as (...args: any[]) => Promise<void>)(...args);\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(\n trx: NavigationTrx<TInputParams, TQueryParams>,\n ) {\n if (!this.isUpdate) {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n // Rebuild URL if beforeOpen mutated trx.params\n const newUrl = this.createUrl(\n trx.params as TInputParams,\n trx.query as AnyObject,\n false,\n );\n if (newUrl !== trx.url) {\n trx.url = newUrl;\n skipHistoryUpdate = false;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isConfigPathMatched) {\n const wasAlreadyConfirmed = this.status === 'open-confirmed';\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n if (this.isUpdate) {\n this.isUpdate = false;\n // afterUpdate handled by updateDisposer reaction\n } else if (!wasAlreadyConfirmed) {\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.parsedPathData, this);\n } else {\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n }\n // update() delegates to confirmOpening\n return;\n }\n\n // Set opening sync to avoid isOpened/isOpening flicker\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n // already confirmed\n if (this.status === 'open-confirmed') {\n return;\n }\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url: `${this.parsedPathData!.path}${buildSearchString(this.query.data)}`,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data as Partial<TQueryParams>,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n this.updateDisposer?.();\n this.updateDisposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TQueryParams>,\n) => new Route<TPath, TInputParams, TOutputParams, TQueryParams>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute', 'canNavigate'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * `true` if `open()` has a target to navigate to —\n * either an own index route or a nested `RouteGroup` that itself can navigate.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)\n */\n get canNavigate(): boolean {\n if (this.indexRoute) return true;\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n route.open(...args);\n return;\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import {\n action,\n comparer,\n computed,\n observable,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n> implements AbstractVirtualRoute<TParams, TQueryParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n private isUpdate = false;\n\n private updateDisposer?: VoidFunction;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'opened') return undefined;\n return this.query.data;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n this.config.afterUpdate?.(this.params, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [\n params?: Maybe<TParams>,\n extraParams?: VirtualOpenExtraParams<TQueryParams>,\n ]\n : [params: TParams, extraParams?: VirtualOpenExtraParams<TQueryParams>]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.isUpdate = this.status === 'opened';\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.params!, this);\n } else {\n this.config.afterOpen?.(this.params!, this);\n }\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n this.config.afterClose?.();\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n this.updateDisposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams, TQueryParams>(config);\n"],"names":["annotations"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"virtual-route-C21P-S6I.js","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { comparer, computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: AnyRoute | null;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n private isUpdate = false;\n private updateDisposer?: VoidFunction;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TQueryParams\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? null;\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {\n fireImmediately: true,\n });\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'open-confirmed') return undefined;\n return [this.parsedPathData, this.query.data] as const;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n if (!this.parsedPathData) return;\n this.config.afterUpdate?.(this.parsedPathData, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n *\n * Also true in the short gap after history already matches this route but\n * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every\n * route looks closed for one tick and RouteViewGroup unmounts the page.\n */\n get isOpening() {\n if (this.status === 'opening') {\n return true;\n }\n\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status === 'open-confirmed' ||\n this.status === 'open-rejected'\n ) {\n return false;\n }\n\n return this.status === 'closed' || this.status === 'unknown';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n return result || null;\n }\n\n return (\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null\n );\n }\n\n protected get isPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedQueryParams extends Record<string, any> = TQueryParams,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n const result: ParamData = {};\n for (const [key, value] of Object.entries(params)) {\n if (value != null) {\n result[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n }\n return result;\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? ({ ...this.query.data, ...rawQuery } as Partial<TQueryParams>)\n : ((rawQuery ?? {}) as Partial<TQueryParams>);\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n : [\n params: TInputParams,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n ): Promise<void>;\n open(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({\n replace: args[1],\n query: args[2],\n } as RouteNavigateParams<TQueryParams>)\n : ((args[1] ?? {}) as RouteNavigateParams<TQueryParams>);\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = (\n mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery\n ) as Partial<TQueryParams> | undefined;\n\n const params = typeof args[0] === 'string' ? undefined : args[0];\n const url =\n typeof args[0] === 'string' ? args[0] : this.createUrl(args[0], query);\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url,\n params: params as TInputParams,\n replace,\n state: rawState ?? null,\n query,\n };\n\n this.isUpdate = this.status === 'open-confirmed';\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n this.isUpdate = false;\n }\n }\n\n /**\n * Updates the current route if it is already open.\n * Unlike `open`, this is a no-op if the route is not open,\n * defaults to `replace: true` instead of push,\n * and defaults to `mergeQuery: true` when no query params are provided.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#update)\n */\n update(\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n update(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async update(...args: any[]) {\n if (this.status !== 'open-confirmed') {\n return;\n }\n\n // Reuse current path params when omitted\n if (args[0] == null) {\n args[0] = this.parsedPathData?.params;\n }\n\n const secondArg = args[1];\n const isObjectParams = typeof secondArg === 'object' && secondArg !== null;\n\n if (isObjectParams) {\n args[1] = {\n replace: true,\n ...('query' in secondArg ? {} : { mergeQuery: true }),\n ...secondArg,\n };\n } else if (typeof secondArg === 'boolean') {\n if (args[2] === undefined) {\n args[1] = { replace: secondArg, mergeQuery: true };\n args.length = 2;\n }\n } else if (args.length === 1) {\n args[1] = { replace: true, mergeQuery: true };\n }\n\n return (this.open as (...args: any[]) => Promise<void>)(...args);\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(\n trx: NavigationTrx<TInputParams, TQueryParams>,\n ) {\n if (!this.isUpdate) {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n // Rebuild URL if beforeOpen mutated trx.params\n const newUrl = this.createUrl(\n trx.params as TInputParams,\n trx.query as AnyObject,\n );\n if (newUrl !== trx.url) {\n trx.url = newUrl;\n skipHistoryUpdate = false;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isPathMatched) {\n const wasAlreadyConfirmed = this.status === 'open-confirmed';\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n if (this.isUpdate) {\n this.isUpdate = false;\n // afterUpdate handled by updateDisposer reaction\n } else if (!wasAlreadyConfirmed) {\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.parsedPathData, this);\n } else {\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n }\n // update() delegates to confirmOpening\n return;\n }\n\n // Set opening sync to avoid isOpened/isOpening flicker\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n // already confirmed\n if (this.status === 'open-confirmed') {\n return;\n }\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url: `${this.parsedPathData!.path}${buildSearchString(this.query.data)}`,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data as Partial<TQueryParams>,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n this.updateDisposer?.();\n this.updateDisposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TQueryParams>,\n) => new Route<TPath, TInputParams, TOutputParams, TQueryParams>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute', 'canNavigate'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * `true` if `open()` has a target to navigate to —\n * either an own index route or a nested `RouteGroup` that itself can navigate.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)\n */\n get canNavigate(): boolean {\n if (this.indexRoute) return true;\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n route.open(...args);\n return;\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import {\n action,\n comparer,\n computed,\n observable,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n> implements AbstractVirtualRoute<TParams, TQueryParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n private isUpdate = false;\n\n private updateDisposer?: VoidFunction;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'opened') return undefined;\n return this.query.data;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n this.config.afterUpdate?.(this.params, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [\n params?: Maybe<TParams>,\n extraParams?: VirtualOpenExtraParams<TQueryParams>,\n ]\n : [params: TParams, extraParams?: VirtualOpenExtraParams<TQueryParams>]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.isUpdate = this.status === 'opened';\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.params!, this);\n } else {\n this.config.afterOpen?.(this.params!, this);\n }\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n this.config.afterClose?.();\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n this.updateDisposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams, TQueryParams>(config);\n"],"names":["annotations"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"virtual-route-DCnOqDz5.cjs","sources":["../src/core/config/config.ts","../src/core/route/route.ts","../src/core/route-group/route-group.ts","../src/core/router/router.ts","../src/core/virtual-route/virtual-route.ts"],"sourcesContent":["import {\n createBrowserHistory,\n createQueryParams,\n type History,\n type IQueryParams,\n isObservableHistory,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update, current) => {\n let history: History;\n let queryParams: IQueryParams | undefined;\n\n if (update?.history) {\n history = update.history;\n queryParams = update.queryParams;\n\n if (current?.history && isObservableHistory(current.history)) {\n current.history.destroy();\n }\n } else if (current?.history) {\n history = current.history;\n queryParams = update?.queryParams ?? current.queryParams;\n } else {\n history = createBrowserHistory();\n }\n\n queryParams ??= createQueryParams({ history });\n\n return {\n ...update,\n history,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { comparer, computed, observable, reaction, runInAction } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport {\n compile,\n match,\n type ParamData,\n parse,\n type TokenData,\n} from 'path-to-regexp';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\n 'absolutePath',\n 'hasOpenedChildren',\n 'isAbleToMergeQuery',\n 'baseUrl',\n ],\n [computed.struct, 'parsedPathData', 'params'],\n [observable, 'children'],\n [observable.ref, 'parent', 'status'],\n];\n\n/**\n * Class for creating path based route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html)\n */\nexport class Route<\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n> {\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n protected history: History;\n\n /**\n * Parent route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#parent)\n */\n parent: AnyRoute | null;\n\n query: IQueryParams;\n\n private _tokenData: TokenData | undefined;\n private _matcher?: ReturnType<typeof match>;\n private _compiler?: ReturnType<typeof compile>;\n private ignoreOpenByPathMatch = false;\n private isUpdate = false;\n private updateDisposer?: VoidFunction;\n\n protected status:\n | 'opening'\n | 'closed'\n | 'open-rejected'\n | 'open-confirmed'\n | 'unknown';\n\n meta?: AnyObject;\n\n /**\n * Route path pattern declaration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#pathdeclaration)\n */\n pathDeclaration: TPath;\n\n /**\n * Indicates if this route is an index route. Index routes activate when parent route path matches exactly.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isindex)\n */\n isIndex: boolean;\n\n /**\n * Indicates if this route is an hash route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#ishash)\n */\n isHash: boolean;\n\n /**\n * Array of child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#children)\n */\n children: AnyRoute[] = [];\n\n constructor(\n pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TQueryParams\n > = {},\n ) {\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.pathDeclaration = pathDeclaration;\n this.isIndex = !!this.config.index;\n this.isHash = !!this.config.hash;\n this.meta = this.config.meta;\n this.status = 'unknown';\n this.parent = config.parent ?? null;\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(() => this.isPathMatched, this.checkPathMatch, {\n fireImmediately: true,\n });\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'open-confirmed') return undefined;\n return [this.parsedPathData, this.query.data] as const;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n if (!this.parsedPathData) return;\n this.config.afterUpdate?.(this.parsedPathData, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n this.config.abortSignal?.addEventListener('abort', () => this.destroy(), {\n once: true,\n });\n }\n }\n\n protected get baseUrl() {\n const baseUrl = this.config.baseUrl ?? routeConfig.get().baseUrl;\n return baseUrl?.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n }\n\n /**\n * Checks whether current route matches provided path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#matchpath)\n */\n matchPath(path?: Maybe<string>): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n if (path != null) {\n pathnameToCheck = path;\n } else if (this.isHash) {\n pathnameToCheck = this.history.location.hash.slice(1);\n } else {\n pathnameToCheck = this.history.location.pathname;\n }\n\n if (this.baseUrl) {\n if (!pathnameToCheck.startsWith(this.baseUrl)) {\n return null;\n }\n\n pathnameToCheck = pathnameToCheck.replace(this.baseUrl, '');\n }\n\n if (\n (this.pathDeclaration === '' || this.pathDeclaration === '/') &&\n (pathnameToCheck === '/' || pathnameToCheck === '')\n ) {\n return { params: {} as any, path: pathnameToCheck };\n }\n\n this._matcher ??= match(this.tokenData, {\n end: this.config.exact ?? false,\n ...this.config.matchOptions,\n });\n const parsed = this._matcher(pathnameToCheck);\n\n if (parsed === false) {\n return null;\n }\n\n return parsed as ParsedPathData<TPath>;\n }\n\n protected get parsedPathData(): ParsedPathData<TPath> | null {\n return this.matchPath();\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)\n *\n * Also true in the short gap after history already matches this route but\n * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every\n * route looks closed for one tick and RouteViewGroup unmounts the page.\n */\n get isOpening() {\n if (this.status === 'opening') {\n return true;\n }\n\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status === 'open-confirmed' ||\n this.status === 'open-rejected'\n ) {\n return false;\n }\n\n return this.status === 'closed' || this.status === 'unknown';\n }\n\n /**\n * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#path)\n */\n get path(): string | null {\n return this.parsedPathData?.path ?? null;\n }\n\n /**\n * Matched path segment for current URL with base URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#absolutepath)\n */\n get absolutePath(): string | null {\n const path = this.path;\n\n if (path === null) {\n return null;\n }\n\n return `${this.baseUrl || ''}${path}`;\n }\n\n /**\n * Current parsed path parameters.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#params)\n */\n get params(): TOutputParams | null {\n if (!this.parsedPathData?.params) {\n return null;\n }\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n return result || null;\n }\n\n return (\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null\n );\n }\n\n protected get isPathMatched() {\n return this.parsedPathData !== null;\n }\n\n /**\n * Defines the \"open\" state for this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopened)\n */\n get isOpened() {\n if (\n this.isDestroyed ||\n !this.isPathMatched ||\n this.params === null ||\n this.status !== 'open-confirmed'\n ) {\n return false;\n }\n\n return (\n // this.parsedPathData is defined because this.params !== null\n !this.config.checkOpened || this.config.checkOpened(this.parsedPathData!)\n );\n }\n\n /**\n * Allows to create child route based on this route with merging this route path and extending path.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend)\n */\n extend<\n TExtendedPath extends string,\n TExtendedInputParams extends\n InputPathParams<`${TPath}${TExtendedPath}`> = InputPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedOutputParams extends AnyObject = TInputParams &\n ParsedPathParams<`${TPath}${TExtendedPath}`>,\n TExtendedQueryParams extends Record<string, any> = TQueryParams,\n >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n TExtendedQueryParams\n >(`${this.pathDeclaration}${pathDeclaration}`, {\n ...configFromCurrentRoute,\n ...config,\n parent: this,\n } as any);\n\n this.addChildren(extendedChild as any);\n\n return extendedChild;\n }\n\n /**\n * Manually add child routes.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#addchildren)\n */\n addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\n\n /**\n * Remove specified routes from children.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#removechildren)\n */\n removeChildren(...routes: AnyRoute[]) {\n this.children = this.children.filter((child) => !routes.includes(child));\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren)\n */\n get hasOpenedChildren(): boolean {\n return this.children.some(\n (child) => child.isOpened || child.hasOpenedChildren,\n );\n }\n\n protected processParams(\n params?: TInputParams | null | undefined,\n ): ParamData | undefined {\n if (params == null) return undefined;\n\n const result: ParamData = {};\n for (const [key, value] of Object.entries(params)) {\n if (value != null) {\n result[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n }\n return result;\n }\n\n /**\n * Generates full route URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#createurl)\n */\n createUrl(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: Maybe<TInputParams>,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<Partial<TQueryParams>>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n ) {\n const params = args[0];\n const rawQuery = args[1];\n const mergeQueryOrOutputParams = args[2] ?? this.isAbleToMergeQuery;\n const outputParams: Maybe<CreatedUrlOutputParams> =\n typeof mergeQueryOrOutputParams === 'boolean'\n ? { mergeQuery: mergeQueryOrOutputParams }\n : mergeQueryOrOutputParams;\n\n const query = outputParams?.mergeQuery\n ? ({ ...this.query.data, ...rawQuery } as Partial<TQueryParams>)\n : ((rawQuery ?? {}) as Partial<TQueryParams>);\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams, TQueryParams> =\n this.config.createUrl?.(defaultUrlCreateParams, this.query.data) ??\n routeConfig.get().createUrl?.(defaultUrlCreateParams, this.query.data) ??\n defaultUrlCreateParams;\n\n let path: string;\n\n try {\n path = this._compiler(this.processParams(urlCreateParams.params));\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n 'Error #1: Route path compilation failed\\n' +\n 'The path pattern could not be built into a URL (often missing or invalid params for a `:param` segment). Using fallbackPath or \"/\".\\n' +\n 'See docs: https://js2me.github.io/mobx-route/errors/1',\n e,\n );\n } else {\n console.error('minified error #1;see mobx-route docs', e);\n }\n path = this.config.fallbackPath ?? routeConfig.get().fallbackPath ?? '/';\n }\n\n const url = `${urlCreateParams.baseUrl || ''}${this.isHash ? '#' : ''}${path}`;\n\n if (outputParams?.omitQuery) {\n return url;\n }\n\n return `${url}${buildSearchString(urlCreateParams.query)}`;\n }\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\n */\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n : [\n params: TInputParams,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ]\n ): Promise<void>;\n open(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async open(...args: any[]) {\n const {\n replace,\n state: rawState,\n query: rawQuery,\n mergeQuery: rawMergeQuery,\n } = typeof args[1] === 'boolean' || args.length > 2\n ? ({\n replace: args[1],\n query: args[2],\n } as RouteNavigateParams<TQueryParams>)\n : ((args[1] ?? {}) as RouteNavigateParams<TQueryParams>);\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = (\n mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery\n ) as Partial<TQueryParams> | undefined;\n\n const params = typeof args[0] === 'string' ? undefined : args[0];\n const url =\n typeof args[0] === 'string' ? args[0] : this.createUrl(args[0], query);\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url,\n params: params as TInputParams,\n replace,\n state: rawState ?? null,\n query,\n };\n\n this.isUpdate = this.status === 'open-confirmed';\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n this.isUpdate = false;\n }\n }\n\n /**\n * Updates the current route if it is already open.\n * Unlike `open`, this is a no-op if the route is not open,\n * defaults to `replace: true` instead of push,\n * and defaults to `mergeQuery: true` when no query params are provided.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#update)\n */\n update(\n params?: TInputParams | null | undefined,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n update(\n url: string,\n navigateParams?: RouteNavigateParams<TQueryParams>,\n ): Promise<void>;\n update(\n url: string,\n replace?: RouteNavigateParams<TQueryParams>['replace'],\n query?: RouteNavigateParams<TQueryParams>['query'],\n ): Promise<void>;\n\n async update(...args: any[]) {\n if (this.status !== 'open-confirmed') {\n return;\n }\n\n // Reuse current path params when omitted\n if (args[0] == null) {\n args[0] = this.parsedPathData?.params;\n }\n\n const secondArg = args[1];\n const isObjectParams = typeof secondArg === 'object' && secondArg !== null;\n\n if (isObjectParams) {\n args[1] = {\n replace: true,\n ...('query' in secondArg ? {} : { mergeQuery: true }),\n ...secondArg,\n };\n } else if (typeof secondArg === 'boolean') {\n if (args[2] === undefined) {\n args[1] = { replace: secondArg, mergeQuery: true };\n args.length = 2;\n }\n } else if (args.length === 1) {\n args[1] = { replace: true, mergeQuery: true };\n }\n\n return (this.open as (...args: any[]) => Promise<void>)(...args);\n }\n\n protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.pathDeclaration, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(\n trx: NavigationTrx<TInputParams, TQueryParams>,\n ) {\n if (!this.isUpdate) {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n let skipHistoryUpdate = !!trx.preferSkipHistoryUpdate;\n\n if (skipHistoryUpdate) {\n this.ignoreOpenByPathMatch = false;\n }\n\n if (this.config.beforeOpen) {\n const feedback = await this.config.beforeOpen(trx);\n\n if (feedback === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n });\n\n return;\n }\n\n // Rebuild URL if beforeOpen mutated trx.params\n const newUrl = this.createUrl(\n trx.params as TInputParams,\n trx.query as AnyObject,\n );\n if (newUrl !== trx.url) {\n trx.url = newUrl;\n skipHistoryUpdate = false;\n }\n\n if (typeof feedback === 'object') {\n skipHistoryUpdate = false;\n Object.assign(trx, feedback);\n }\n }\n\n if (this.isDestroyed) {\n return;\n }\n\n if (!skipHistoryUpdate) {\n if (trx.replace) {\n this.history.replace(trx.url, trx.state);\n } else {\n this.history.push(trx.url, trx.state);\n }\n }\n\n if (this.isPathMatched) {\n const wasAlreadyConfirmed = this.status === 'open-confirmed';\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n if (this.isUpdate) {\n this.isUpdate = false;\n // afterUpdate handled by updateDisposer reaction\n } else if (!wasAlreadyConfirmed) {\n this.config.afterOpen?.(this.parsedPathData!, this);\n }\n }\n\n return true;\n }\n\n protected confirmClosing() {\n runInAction(() => {\n this.status = 'closed';\n });\n return true;\n }\n\n private firstPathMatchingRun = true;\n\n private checkPathMatch = async (isPathMathched: boolean) => {\n if (this.firstPathMatchingRun) {\n this.firstPathMatchingRun = false;\n // ignore first 'afterClose' callback call\n if (!isPathMathched) {\n return;\n }\n }\n\n if (isPathMathched) {\n // after manual open call\n if (this.ignoreOpenByPathMatch) {\n this.ignoreOpenByPathMatch = false;\n if (this.status === 'opening' && this.parsedPathData) {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.parsedPathData, this);\n } else {\n this.config.afterOpen?.(this.parsedPathData, this);\n }\n }\n // update() delegates to confirmOpening\n return;\n }\n\n // Set opening sync to avoid isOpened/isOpening flicker\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n // already confirmed\n if (this.status === 'open-confirmed') {\n return;\n }\n\n const trx: NavigationTrx<TInputParams, TQueryParams> = {\n url: `${this.parsedPathData!.path}${buildSearchString(this.query.data)}`,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data as Partial<TQueryParams>,\n preferSkipHistoryUpdate: true,\n };\n\n await this.confirmOpening(trx);\n } else {\n this.ignoreOpenByPathMatch = false;\n\n const isConfirmed = this.confirmClosing();\n\n if (isConfirmed) {\n this.config.afterClose?.();\n }\n }\n };\n\n private get isAbleToMergeQuery() {\n return this.config.mergeQuery ?? routeConfig.get().mergeQuery;\n }\n\n /**\n * Destroys route subscriptions and reactions.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#destroy)\n */\n destroy() {\n this.isDestroyed = true;\n this.disposer?.();\n this.disposer = undefined;\n this.updateDisposer?.();\n this.updateDisposer = undefined;\n }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TQueryParams>,\n) => new Route<TPath, TInputParams, TOutputParams, TQueryParams>(path, config);\n","import { computed, observable } from 'mobx';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst annotations: ObservableAnnotationsArray<RouteGroup<any>> = [\n [computed, 'isOpened', 'indexRoute', 'canNavigate'],\n [observable.shallow, 'routes'],\n];\n\n/**\n * Class for grouping related routes and managing their state.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport class RouteGroup<TRoutesCollection extends RoutesCollection>\n implements AbstractRouteGroup<TRoutesCollection>\n{\n routes: TRoutesCollection;\n\n constructor(\n routes: TRoutesCollection,\n private _indexRoute?: AnyRouteEntity,\n ) {\n this.routes = routes;\n\n applyObservable(this, annotations);\n }\n\n /**\n * Returns true if at least one route in the group is open.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)\n */\n get isOpened(): boolean {\n const routes = Object.values(this.routes);\n return routes.some(\n (route) =>\n route.isOpened ||\n ('hasOpenedChildren' in route && route.hasOpenedChildren),\n );\n }\n\n /**\n * First found index route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)\n */\n get indexRoute(): AnyRouteEntity | undefined {\n return (this._indexRoute ??\n Object.values(this.routes).find(\n (route) => 'isIndex' in route && route.isIndex,\n )) as unknown as AnyRouteEntity;\n }\n\n /**\n * `true` if `open()` has a target to navigate to —\n * either an own index route or a nested `RouteGroup` that itself can navigate.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#cannavigate)\n */\n get canNavigate(): boolean {\n if (this.indexRoute) return true;\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)\n */\n open(...args: any[]) {\n if (this.indexRoute && 'open' in this.indexRoute) {\n this.indexRoute.open(...args);\n return;\n }\n\n for (const routeName in this.routes) {\n const route = this.routes[routeName];\n if (route instanceof RouteGroup && route.canNavigate) {\n route.open(...args);\n return;\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Warning #1: RouteGroup.open() cannot navigate\\n' +\n 'This group has no index route (`index: true` or `groupRoutes(routes, indexRoute)`) and no navigable nested RouteGroup, so open() does nothing.\\n' +\n 'See docs: https://js2me.github.io/mobx-route/warnings/1',\n );\n } else {\n console.warn('minified warning #1;see mobx-route docs');\n }\n }\n}\n\n/**\n * Helper for creating route groups.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)\n */\nexport const groupRoutes = <TRoutesCollection extends RoutesCollection>(\n routes: TRoutesCollection,\n indexRoute?: AnyRouteEntity,\n) => new RouteGroup<TRoutesCollection>(routes, indexRoute);\n","import { computed } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\n\nconst annotations: ObservableAnnotationsArray<Router<any>> = [\n [computed.struct, 'location'],\n];\n\n/**\n * Class for centralized routing management.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Router.html)\n */\nexport class Router<TRoutesCollection extends RoutesCollection> {\n routes: TRoutesCollection;\n history: History;\n query: IQueryParams;\n\n constructor(config: RouterConfiguration<TRoutesCollection>) {\n this.routes = config.routes;\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n\n applyObservable(this, annotations);\n }\n\n get location() {\n return this.history.location;\n }\n\n navigate(url: string, options?: RouterNavigateOptions) {\n const query =\n (options?.mergeQuery ?? routeConfig.get().mergeQuery)\n ? { ...this.query.data, ...options?.query }\n : { ...options?.query };\n\n const searchString = buildSearchString(query);\n const navigationUrl = `${url}${searchString}`;\n\n if (options?.replace) {\n this.history.replace(navigationUrl, options?.state);\n } else {\n this.history.push(navigationUrl, options?.state);\n }\n }\n}\n\nexport const createRouter = <TRoutesCollection extends RoutesCollection>(\n config: RouterConfiguration<TRoutesCollection>,\n) => new Router(config);\n","import {\n action,\n comparer,\n computed,\n observable,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport { applyObservable, type ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n VirtualRouteTrx,\n} from './virtual-route.types.js';\n\nconst annotations: ObservableAnnotationsArray<VirtualRoute<any>> = [\n [observable, 'params'],\n [observable.ref, 'status', 'trx', 'openChecker', 'isOuterOpened'],\n [computed, 'isOpened', 'isOpening', 'isClosing'],\n [action, 'setOpenChecker', 'open', 'close', 'destroy'],\n];\n\n/**\n * Class for creating routes with custom activation logic\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html)\n */\nexport class VirtualRoute<\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n> implements AbstractVirtualRoute<TParams, TQueryParams>\n{\n private isDestroyed?: boolean;\n private disposer?: VoidFunction;\n\n query: IQueryParams;\n params: TParams | null;\n\n protected status:\n | 'opening'\n | 'open-rejected'\n | 'opened'\n | 'closing'\n | 'closed'\n | 'unknown';\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n\n private trx: Maybe<VirtualRouteTrx>;\n\n private skipAutoOpenClose: boolean;\n\n private isUpdate = false;\n\n private updateDisposer?: VoidFunction;\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isouteropened)\n */\n isOuterOpened: boolean | undefined;\n\n constructor(protected config: VirtualRouteConfiguration<TParams> = {}) {\n this.query = config.queryParams ?? routeConfig.get().queryParams;\n this.params = callFunction(config.initialParams, this) ?? null;\n this.openChecker = config.checkOpened;\n this.skipAutoOpenClose = false;\n this.isOuterOpened = this.openChecker?.(this);\n this.status = this.isOuterOpened ? 'opened' : 'unknown';\n\n applyObservable(this, annotations);\n\n if (this.config.abortSignal?.aborted) {\n this.isDestroyed = true;\n } else {\n this.disposer = reaction(\n () => this.openChecker?.(this),\n action((isOuterOpened) => {\n this.isOuterOpened = isOuterOpened;\n\n if (\n this.skipAutoOpenClose ||\n this.status === 'closing' ||\n this.status === 'opening'\n ) {\n return;\n }\n\n if (this.isOuterOpened) {\n if (this.status === 'opened') {\n return;\n }\n void this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutoOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n void this.confirmClosing();\n }\n }),\n { signal: this.config.abortSignal, fireImmediately: true },\n );\n this.updateDisposer = reaction(\n () => {\n if (this.status !== 'opened') return undefined;\n return this.query.data;\n },\n (value, prevValue) => {\n if (prevValue === undefined) return;\n if (value === undefined) return;\n this.config.afterUpdate?.(this.params, this);\n },\n {\n fireImmediately: false,\n signal: this.config.abortSignal,\n equals: comparer.structural,\n },\n );\n }\n\n if (this.status === 'opened') {\n this.config.afterOpen?.(this.params, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened)\n */\n get isOpened() {\n return (\n !this.isDestroyed &&\n this.status === 'opened' &&\n this.isOuterOpened !== false\n );\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopening)\n */\n get isOpening() {\n return this.status === 'opening';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isclosing)\n */\n get isClosing() {\n return this.status === 'closing';\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker)\n */\n setOpenChecker(\n openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>,\n ) {\n this.openChecker = openChecker;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)\n */\n open(\n ...args: IsPartial<TParams> extends true\n ? [\n params?: Maybe<TParams>,\n extraParams?: VirtualOpenExtraParams<TQueryParams>,\n ]\n : [params: TParams, extraParams?: VirtualOpenExtraParams<TQueryParams>]\n ): Promise<void>;\n async open(...args: any[]) {\n const params = (args[0] ?? null) as unknown as TParams;\n const extra: Maybe<VirtualOpenExtraParams> = args[1];\n\n this.isUpdate = this.status === 'opened';\n this.skipAutoOpenClose = true;\n\n this.trx = {\n params,\n extra,\n manual: true,\n };\n\n await this.confirmOpening(this.trx);\n\n this.skipAutoOpenClose = false;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close)\n */\n async close() {\n this.skipAutoOpenClose = true;\n const result = await this.confirmClosing();\n this.skipAutoOpenClose = false;\n return result;\n }\n\n private async confirmOpening(trx: VirtualRouteTrx) {\n runInAction(() => {\n this.trx = undefined;\n this.status = 'opening';\n });\n\n if ((await this.config.beforeOpen?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n if ((await this.config.open?.(trx.params, this)) === false) {\n runInAction(() => {\n this.status = 'open-rejected';\n this.trx = undefined;\n });\n return;\n }\n\n runInAction(() => {\n if (trx.extra?.query) {\n this.query.update(trx.extra.query, trx.extra.replace);\n }\n\n this.trx = undefined;\n this.params = trx.params;\n this.status = 'opened';\n\n if (this.isUpdate) {\n this.isUpdate = false;\n this.config.afterUpdate?.(this.params!, this);\n } else {\n this.config.afterOpen?.(this.params!, this);\n }\n });\n\n return true;\n }\n\n private async confirmClosing() {\n if (this.status === 'closed') {\n return true;\n }\n\n const lastStatus = this.status;\n\n runInAction(() => {\n this.status = 'closing';\n });\n\n if ((await this.config.beforeClose?.()) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n if (this.config.close?.(this) === false) {\n runInAction(() => {\n this.status = lastStatus;\n });\n return;\n }\n\n runInAction(() => {\n this.status = 'closed';\n this.params = null;\n });\n\n this.config.afterClose?.();\n\n return true;\n }\n\n destroy() {\n this.isDestroyed = true;\n this.status = 'unknown';\n this.disposer?.();\n this.updateDisposer?.();\n }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n TQueryParams extends Record<string, any> = AnyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams, TQueryParams>(config);\n"],"names":["createGlobalDynamicConfig","isObservableHistory","createBrowserHistory","createQueryParams","annotations","computed","observable","applyObservable","reaction","comparer","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":"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"}