mobx-route 1.2.0 → 1.2.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
@@ -153,9 +153,19 @@ class Route {
153
153
  }
154
154
  /**
155
155
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)
156
+ *
157
+ * Also true in the short gap after history already matches this route but
158
+ * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every
159
+ * route looks closed for one tick and RouteViewGroup unmounts the page.
156
160
  */
157
161
  get isOpening() {
158
- return this.status === "opening";
162
+ if (this.status === "opening") {
163
+ return true;
164
+ }
165
+ if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
166
+ return false;
167
+ }
168
+ return this.status === "closed" || this.status === "unknown";
159
169
  }
160
170
  /**
161
171
  * Matched path segment for current URL.
@@ -409,6 +419,11 @@ class Route {
409
419
  }
410
420
  return;
411
421
  }
422
+ if (this.status !== "opening" && this.status !== "open-confirmed") {
423
+ mobx.runInAction(() => {
424
+ this.status = "opening";
425
+ });
426
+ }
412
427
  const trx = {
413
428
  url: this.parsedPathData.path,
414
429
  params: this.parsedPathData.params,
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.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/utils/is-route-entity.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 { 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 TParentRoute extends Route<any, any, any, any> | null = null,\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: TParentRoute;\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\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 TParentRoute\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 as unknown as TParentRoute);\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.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 get isOpening() {\n return this.status === 'opening';\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 let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\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 >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\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 return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\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<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\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 }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\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,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\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 ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\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(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\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 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 runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\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 this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\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 }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(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 type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } 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<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\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 /**\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 }\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 ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\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.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 this.config.afterOpen?.(this.params!, this);\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 }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["createGlobalDynamicConfig","isObservableHistory","createBrowserHistory","createQueryParams","annotations","computed","observable","applyObservable","reaction","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":"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"}
1
+ {"version":3,"file":"index.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/utils/is-route-entity.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 { 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 TParentRoute extends Route<any, any, any, any> | null = null,\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: TParentRoute;\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\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 TParentRoute\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 as unknown as TParentRoute);\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.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 let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\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 >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\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 return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\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<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\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 }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\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,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\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 ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\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(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\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 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 runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\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 this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n // Sync before any await — closes the Back gap where isOpened/isOpening\n // were both false until confirmOpening's first runInAction ran.\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\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 }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(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 type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } 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<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\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 /**\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 }\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 ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\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.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 this.config.afterOpen?.(this.params!, this);\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 }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["createGlobalDynamicConfig","isObservableHistory","createBrowserHistory","createQueryParams","annotations","computed","observable","applyObservable","reaction","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":";;;;;;;;AAWO,MAAM,cAAcA,QAAAA;AAAAA,EACzB,CAAC,QAAQ,YAAY;AACnB,QAAI;AACJ,QAAI;AAEJ,QAAI,QAAQ,SAAS;AACnB,gBAAU,OAAO;AACjB,oBAAc,OAAO;AAErB,UAAI,SAAS,WAAWC,oBAAAA,oBAAoB,QAAQ,OAAO,GAAG;AAC5D,gBAAQ,QAAQ,QAAA;AAAA,MAClB;AAAA,IACF,WAAW,SAAS,SAAS;AAC3B,gBAAU,QAAQ;AAClB,oBAAc,QAAQ,eAAe,QAAQ;AAAA,IAC/C,OAAO;AACL,gBAAUC,oBAAAA,qBAAA;AAAA,IACZ;AAEA,oBAAgBC,oBAAAA,kBAAkB,EAAE,SAAS;AAE7C,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EACA,uBAAO,IAAI,mBAAmB;AAChC;ACTA,MAAMC,gBAAqE;AAAA,EACzE;AAAA,IACEC,KAAAA;AAAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,CAACA,cAAS,QAAQ,kBAAkB,QAAQ;AAAA,EAC5C,CAACC,KAAAA,YAAY,UAAU;AAAA,EACvB,CAACA,KAAAA,WAAW,KAAK,UAAU,QAAQ;AACrC;AAOO,MAAM,MAKX;AAAA,EAyDA,YACE,iBACU,SAKN,IACJ;AANU,SAAA,SAAA;AAOV,SAAK,UAAU,OAAO,WAAW,YAAY,MAAM;AACnD,SAAK,QAAQ,OAAO,eAAe,YAAY,MAAM;AACrD,SAAK,kBAAkB;AACvB,SAAK,UAAU,CAAC,CAAC,KAAK,OAAO;AAC7B,SAAK,SAAS,CAAC,CAAC,KAAK,OAAO;AAC5B,SAAK,OAAO,KAAK,OAAO;AACxB,SAAK,SAAS;AACd,SAAK,SAAS,OAAO,UAAW;AAEhCC,WAAAA,gBAAgB,MAAMH,aAAW;AAEjC,QAAI,KAAK,OAAO,aAAa,SAAS;AACpC,WAAK,cAAc;AAAA,IACrB,OAAO;AACL,WAAK,WAAWI,cAAS,MAAM,KAAK,eAAe,KAAK,gBAAgB;AAAA,QACtE,iBAAiB;AAAA,MAAA,CAClB;AACD,WAAK,OAAO,aAAa,iBAAiB,SAAS,MAAM,KAAK,WAAW;AAAA,QACvE,MAAM;AAAA,MAAA,CACP;AAAA,IACH;AAAA,EACF;AAAA,EA5BY;AAAA,EA1DJ;AAAA,EACA;AAAA,EAEE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV;AAAA,EAEA;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA,wBAAwB;AAAA,EAEtB;AAAA,EAOV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAuB,CAAA;AAAA,EAkCvB,IAAc,UAAU;AACtB,UAAM,UAAU,KAAK,OAAO,WAAW,YAAY,MAAM;AACzD,WAAO,SAAS,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,MAAoD;AAC5D,QAAI;AAEJ,QAAI,QAAQ,MAAM;AAChB,wBAAkB;AAAA,IACpB,WAAW,KAAK,QAAQ;AACtB,wBAAkB,KAAK,QAAQ,SAAS,KAAK,MAAM,CAAC;AAAA,IACtD,OAAO;AACL,wBAAkB,KAAK,QAAQ,SAAS;AAAA,IAC1C;AAEA,QAAI,KAAK,SAAS;AAChB,UAAI,CAAC,gBAAgB,WAAW,KAAK,OAAO,GAAG;AAC7C,eAAO;AAAA,MACT;AAEA,wBAAkB,gBAAgB,QAAQ,KAAK,SAAS,EAAE;AAAA,IAC5D;AAEA,SACG,KAAK,oBAAoB,MAAM,KAAK,oBAAoB,SACxD,oBAAoB,OAAO,oBAAoB,KAChD;AACA,aAAO,EAAE,QAAQ,IAAW,MAAM,gBAAA;AAAA,IACpC;AAEA,SAAK,aAAaC,mBAAM,KAAK,WAAW;AAAA,MACtC,KAAK,KAAK,OAAO,SAAS;AAAA,MAC1B,GAAG,KAAK,OAAO;AAAA,IAAA,CAChB;AACD,UAAM,SAAS,KAAK,SAAS,eAAe;AAE5C,QAAI,WAAW,OAAO;AACpB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,IAAc,iBAA+C;AAC3D,WAAO,KAAK,UAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,YAAY;AACd,QAAI,KAAK,WAAW,WAAW;AAC7B,aAAO;AAAA,IACT;AAEA,QACE,KAAK,eACL,CAAC,KAAK,iBACN,KAAK,WAAW,QAChB,KAAK,WAAW,oBAChB,KAAK,WAAW,iBAChB;AACA,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,WAAW,YAAY,KAAK,WAAW;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAAsB;AACxB,WAAO,KAAK,gBAAgB,QAAQ;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,eAA8B;AAChC,UAAM,OAAO,KAAK;AAElB,QAAI,SAAS,MAAM;AACjB,aAAO;AAAA,IACT;AAEA,WAAO,GAAG,KAAK,WAAW,EAAE,GAAG,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,SAA+B;AACjC,QAAI,CAAC,KAAK,gBAAgB,QAAQ;AAChC,aAAO;AAAA,IACT;AAEA,QAAI,SACD,KAAK,gBAAgB,UAA8C;AAEtE,QAAI,KAAK,OAAO,QAAQ;AACtB,YAAM,SAAS,KAAK,OAAO;AAAA,QACzB,KAAK,eAAe;AAAA,QACpB,KAAK,OAAO;AAAA,MAAA;AAEd,UAAI,QAAQ;AACV,iBAAS;AAAA,MACX,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,IAAc,gBAAgB;AAC5B,WAAO,KAAK,mBAAmB;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,WAAW;AACb,QACE,KAAK,eACL,CAAC,KAAK,iBACN,KAAK,WAAW,QAChB,KAAK,WAAW,kBAChB;AACA,aAAO;AAAA,IACT;AAEA;AAAA;AAAA,MAEE,CAAC,KAAK,OAAO,eAAe,KAAK,OAAO,YAAY,KAAK,cAAe;AAAA;AAAA,EAE5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAOE,iBACA,QASA;AAGA,UAAM,EAAE,OAAO,QAAQ,OAAO,GAAG,uBAAA,IAA2B,KAAK;AAEjE,UAAM,gBAAgB,IAAI,MAKxB,GAAG,KAAK,eAAe,GAAG,eAAe,IAAI;AAAA,MAC7C,GAAG;AAAA,MACH,GAAG;AAAA,MACH,QAAQ;AAAA,IAAA,CACF;AAER,SAAK,YAAY,aAAoB;AAErC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,QAAoB;AACjC,SAAK,SAAS,KAAK,GAAG,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAAkB,QAAoB;AACpC,SAAK,WAAW,KAAK,SAAS,OAAO,CAAC,UAAU,CAAC,OAAO,SAAS,KAAK,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,oBAA6B;AAC/B,WAAO,KAAK,SAAS;AAAA,MACnB,CAAC,UAAU,MAAM,YAAY,MAAM;AAAA,IAAA;AAAA,EAEvC;AAAA,EAEU,cACR,QACuB;AACvB,QAAI,UAAU,KAAM,QAAO;AAE3B,WAAO,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AAC1D,UAAI,SAAS,MAAM;AACjB,YAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,KAAK;AAAA,MACpE;AACA,aAAO;AAAA,IACT,GAAG,CAAA,CAAe;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aACK,MAWH;AACA,UAAM,SAAS,KAAK,CAAC;AACrB,UAAM,WAAW,KAAK,CAAC;AACvB,UAAM,2BAA2B,KAAK,CAAC,KAAK,KAAK;AACjD,UAAM,eACJ,OAAO,6BAA6B,YAChC,EAAE,YAAY,6BACd;AAEN,UAAM,QAAQ,cAAc,aACxB,EAAE,GAAG,KAAK,MAAM,MAAM,GAAG,SAAA,IACxB,YAAY,CAAA;AAEjB,SAAK,cAAcC,qBAAQ,KAAK,SAAS;AAEzC,UAAM,yBAAwD;AAAA,MAC5D,SAAS,KAAK;AAAA,MACd;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,kBACJ,KAAK,OAAO,YAAY,wBAAwB,KAAK,MAAM,IAAI,KAC/D,YAAY,MAAM,YAAY,wBAAwB,KAAK,MAAM,IAAI,KACrE;AAEF,QAAI;AAEJ,QAAI;AACF,aAAO,KAAK,UAAU,KAAK,cAAc,gBAAgB,MAAM,CAAC;AAAA,IAClE,SAAS,GAAG;AACV,UAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,gBAAQ;AAAA,UACN;AAAA,UAGA;AAAA,QAAA;AAAA,MAEJ,OAAO;AACL,gBAAQ,MAAM,yCAAyC,CAAC;AAAA,MAC1D;AACA,aAAO,KAAK,OAAO,gBAAgB,YAAY,IAAA,EAAM,gBAAgB;AAAA,IACvE;AAEA,UAAM,MAAM,GAAG,gBAAgB,WAAW,EAAE,GAAG,KAAK,SAAS,MAAM,EAAE,GAAG,IAAI;AAE5E,QAAI,cAAc,WAAW;AAC3B,aAAO;AAAA,IACT;AAEA,WAAO,GAAG,GAAG,GAAGC,oBAAAA,kBAAkB,gBAAgB,KAAK,CAAC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwCA,MAAM,QAAQ,MAAa;AACzB,UAAM;AAAA,MACJ;AAAA,MACA,OAAO;AAAA,MACP,OAAO;AAAA,MACP,YAAY;AAAA,IAAA,IACV,OAAO,KAAK,CAAC,MAAM,aAAa,KAAK,SAAS,IAC7C,EAAE,SAAS,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,MAChC,KAAK,CAAC,KAAK,CAAA;AACjB,QAAI;AACJ,QAAI;AAEJ,UAAM,aAAa,iBAAiB,KAAK;AACzC,UAAM,QAAQ,aAAa,EAAE,GAAG,KAAK,MAAM,MAAM,GAAG,SAAA,IAAa;AAEjE,QAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,YAAM,KAAK,CAAC;AAAA,IACd,OAAO;AACL,eAAS,KAAK,CAAC;AACf,YAAM,KAAK,UAAU,KAAK,CAAC,GAAG,KAAK;AAAA,IACrC;AAEA,UAAM,QAAQ,YAAY;AAE1B,UAAM,MAAmC;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,SAAK,wBAAwB;AAC7B,UAAM,cAAc,MAAM,KAAK,eAAe,GAAG;AAEjD,QAAI,gBAAgB,MAAM;AACxB,WAAK,wBAAwB;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,IAAc,YAAY;AACxB,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAaC,mBAAM,KAAK,iBAAiB,KAAK,OAAO,YAAY;AAAA,IACxE;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAgB,eAAe,KAAkC;AAC/DC,SAAAA,YAAY,MAAM;AAChB,WAAK,SAAS;AAAA,IAChB,CAAC;AAED,QAAI,oBAAoB,CAAC,CAAC,IAAI;AAE9B,QAAI,mBAAmB;AACrB,WAAK,wBAAwB;AAAA,IAC/B;AAEA,QAAI,KAAK,OAAO,YAAY;AAC1B,YAAM,WAAW,MAAM,KAAK,OAAO,WAAW,GAAG;AAEjD,UAAI,aAAa,OAAO;AACtBA,aAAAA,YAAY,MAAM;AAChB,eAAK,SAAS;AAAA,QAChB,CAAC;AAED;AAAA,MACF;AAEA,UAAI,OAAO,aAAa,UAAU;AAChC,4BAAoB;AACpB,eAAO,OAAO,KAAK,QAAQ;AAAA,MAC7B;AAAA,IACF;AAEA,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AAEA,QAAI,CAAC,mBAAmB;AACtB,UAAI,IAAI,SAAS;AACf,aAAK,QAAQ,QAAQ,IAAI,KAAK,IAAI,KAAK;AAAA,MACzC,OAAO;AACL,aAAK,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK;AAAA,MACtC;AAAA,IACF;AAEA,QAAI,KAAK,eAAe;AACtBA,WAAAA,YAAY,MAAM;AAChB,aAAK,SAAS;AAAA,MAChB,CAAC;AAED,WAAK,OAAO,YAAY,KAAK,gBAAiB,IAAI;AAAA,IACpD;AAEA,WAAO;AAAA,EACT;AAAA,EAEU,iBAAiB;AACzBA,SAAAA,YAAY,MAAM;AAChB,WAAK,SAAS;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB;AAAA,EAEvB,iBAAiB,OAAO,mBAA4B;AAC1D,QAAI,KAAK,sBAAsB;AAC7B,WAAK,uBAAuB;AAE5B,UAAI,CAAC,gBAAgB;AACnB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB;AAElB,UAAI,KAAK,uBAAuB;AAC9B,aAAK,wBAAwB;AAC7B,YAAI,KAAK,WAAW,aAAa,KAAK,gBAAgB;AACpDA,eAAAA,YAAY,MAAM;AAChB,iBAAK,SAAS;AAAA,UAChB,CAAC;AACD,eAAK,OAAO,YAAY,KAAK,gBAAgB,IAAI;AAAA,QACnD;AACA;AAAA,MACF;AAIA,UAAI,KAAK,WAAW,aAAa,KAAK,WAAW,kBAAkB;AACjEA,aAAAA,YAAY,MAAM;AAChB,eAAK,SAAS;AAAA,QAChB,CAAC;AAAA,MACH;AAEA,YAAM,MAAmC;AAAA,QACvC,KAAK,KAAK,eAAgB;AAAA,QAC1B,QAAQ,KAAK,eAAgB;AAAA,QAC7B,OAAO,KAAK,QAAQ,SAAS;AAAA,QAC7B,OAAO,KAAK,MAAM;AAAA,QAClB,yBAAyB;AAAA,MAAA;AAG3B,YAAM,KAAK,eAAe,GAAG;AAAA,IAC/B,OAAO;AACL,WAAK,wBAAwB;AAE7B,YAAM,cAAc,KAAK,eAAA;AAEzB,UAAI,aAAa;AACf,aAAK,OAAO,aAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAY,qBAAqB;AAC/B,WAAO,KAAK,OAAO,cAAc,YAAY,MAAM;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU;AACR,SAAK,cAAc;AACnB,SAAK,WAAA;AACL,SAAK,WAAW;AAAA,EAClB;AACF;AAEO,MAAM,cAAc,CAMzB,MACA,WACG,IAAI,MAAwD,MAAM,MAAM;ACtpB7E,MAAMT,gBAA2D;AAAA,EAC/D,CAACC,eAAU,YAAY,cAAc,aAAa;AAAA,EAClD,CAACC,KAAAA,WAAW,SAAS,QAAQ;AAC/B;AAOO,MAAM,WAEb;AAAA,EAGE,YACE,QACQ,aACR;AADQ,SAAA,cAAA;AAER,SAAK,SAAS;AAEdC,WAAAA,gBAAgB,MAAMH,aAAW;AAAA,EACnC;AAAA,EALU;AAAA,EAJV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,IAAI,WAAoB;AACtB,UAAM,SAAS,OAAO,OAAO,KAAK,MAAM;AACxC,WAAO,OAAO;AAAA,MACZ,CAAC,UACC,MAAM,YACL,uBAAuB,SAAS,MAAM;AAAA,IAAA;AAAA,EAE7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,aAAyC;AAC3C,WAAQ,KAAK,eACX,OAAO,OAAO,KAAK,MAAM,EAAE;AAAA,MACzB,CAAC,UAAU,aAAa,SAAS,MAAM;AAAA,IAAA;AAAA,EAE7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,cAAuB;AACzB,QAAI,KAAK,WAAY,QAAO;AAE5B,eAAW,aAAa,KAAK,QAAQ;AACnC,YAAM,QAAQ,KAAK,OAAO,SAAS;AACnC,UAAI,iBAAiB,cAAc,MAAM,aAAa;AACpD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAa;AACnB,QAAI,KAAK,cAAc,UAAU,KAAK,YAAY;AAChD,WAAK,WAAW,KAAK,GAAG,IAAI;AAC5B;AAAA,IACF;AAEA,eAAW,aAAa,KAAK,QAAQ;AACnC,YAAM,QAAQ,KAAK,OAAO,SAAS;AACnC,UAAI,iBAAiB,cAAc,MAAM,aAAa;AACpD,cAAM,KAAK,GAAG,IAAI;AAClB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,cAAQ;AAAA,QACN;AAAA,MAAA;AAAA,IAIJ,OAAO;AACL,cAAQ,KAAK,yCAAyC;AAAA,IACxD;AAAA,EACF;AACF;AAOO,MAAM,cAAc,CACzB,QACA,eACG,IAAI,WAA8B,QAAQ,UAAU;ACxGzD,MAAMA,gBAAuD;AAAA,EAC3D,CAACC,KAAAA,SAAS,QAAQ,UAAU;AAC9B;AAOO,MAAM,OAAmD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAgD;AAC1D,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO,WAAW,YAAY,MAAM;AACnD,SAAK,QAAQ,OAAO,eAAe,YAAY,MAAM;AAErDE,WAAAA,gBAAgB,MAAMH,aAAW;AAAA,EACnC;AAAA,EAEA,IAAI,WAAW;AACb,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,SAAS,KAAa,SAAiC;AACrD,UAAM,QACH,SAAS,cAAc,YAAY,IAAA,EAAM,aACtC,EAAE,GAAG,KAAK,MAAM,MAAM,GAAG,SAAS,MAAA,IAClC,EAAE,GAAG,SAAS,MAAA;AAEpB,UAAM,eAAeO,oBAAAA,kBAAkB,KAAK;AAC5C,UAAM,gBAAgB,GAAG,GAAG,GAAG,YAAY;AAE3C,QAAI,SAAS,SAAS;AACpB,WAAK,QAAQ,QAAQ,eAAe,SAAS,KAAK;AAAA,IACpD,OAAO;AACL,WAAK,QAAQ,KAAK,eAAe,SAAS,KAAK;AAAA,IACjD;AAAA,EACF;AACF;AAEO,MAAM,eAAe,CAC1B,WACG,IAAI,OAAO,MAAM;ACzDf,MAAM,gBAAgB,CAAC,UAC5B,SAAS,cAAc;ACUzB,MAAM,cAA6D;AAAA,EACjE,CAACL,KAAAA,YAAY,QAAQ;AAAA,EACrB,CAACA,KAAAA,WAAW,KAAK,UAAU,OAAO,eAAe,eAAe;AAAA,EAChE,CAACD,eAAU,YAAY,aAAa,WAAW;AAAA,EAC/C,CAACS,aAAQ,kBAAkB,QAAQ,SAAS,SAAS;AACvD;AAOO,MAAM,aAEb;AAAA,EA0BE,YAAsB,SAA6C,IAAI;AAAjD,SAAA,SAAA;AACpB,SAAK,QAAQ,OAAO,eAAe,YAAY,MAAM;AACrD,SAAK,SAASC,OAAAA,aAAa,OAAO,eAAe,IAAI,KAAK;AAC1D,SAAK,cAAc,OAAO;AAC1B,SAAK,oBAAoB;AACzB,SAAK,gBAAgB,KAAK,cAAc,IAAI;AAC5C,SAAK,SAAS,KAAK,gBAAgB,WAAW;AAE9CR,WAAAA,gBAAgB,MAAM,WAAW;AAEjC,QAAI,KAAK,OAAO,aAAa,SAAS;AACpC,WAAK,cAAc;AAAA,IACrB,OAAO;AACL,WAAK,WAAWC,KAAAA;AAAAA,QACd,MAAM,KAAK,cAAc,IAAI;AAAA,QAC7BM,KAAAA,OAAO,CAAC,kBAAkB;AACxB,eAAK,gBAAgB;AAErB,cACE,KAAK,qBACL,KAAK,WAAW,aAChB,KAAK,WAAW,WAChB;AACA;AAAA,UACF;AAEA,cAAI,KAAK,eAAe;AACtB,gBAAI,KAAK,WAAW,UAAU;AAC5B;AAAA,YACF;AACA,iBAAK,KAAK,eAAe;AAAA,cACvB,QAAQ,KAAK,UAAU;AAAA,cACvB,GAAG,KAAK,OAAO,oBAAoB,IAAI;AAAA,YAAA,CACxC;AAAA,UACH,OAAO;AACL,gBAAI,KAAK,WAAW,YAAY,KAAK,WAAW,WAAW;AACzD;AAAA,YACF;AACA,iBAAK,KAAK,eAAA;AAAA,UACZ;AAAA,QACF,CAAC;AAAA,QACD,EAAE,QAAQ,KAAK,OAAO,aAAa,iBAAiB,KAAA;AAAA,MAAK;AAAA,IAE7D;AAEA,QAAI,KAAK,WAAW,UAAU;AAC5B,WAAK,OAAO,YAAY,KAAK,QAAQ,IAAI;AAAA,IAC3C;AAAA,EACF;AAAA,EAhDsB;AAAA,EAzBd;AAAA,EACA;AAAA,EAER;AAAA,EACA;AAAA,EAEU;AAAA,EAQF;AAAA,EAEA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA,EAKR;AAAA;AAAA;AAAA;AAAA,EAuDA,IAAI,WAAW;AACb,WACE,CAAC,KAAK,eACN,KAAK,WAAW,YAChB,KAAK,kBAAkB;AAAA,EAE3B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAAY;AACd,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAAY;AACd,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,eACE,aACA;AACA,SAAK,cAAc;AAAA,EACrB;AAAA,EAUA,MAAM,QAAQ,MAAa;AACzB,UAAM,SAAU,KAAK,CAAC,KAAK;AAC3B,UAAM,QAAuC,KAAK,CAAC;AAEnD,SAAK,oBAAoB;AAEzB,SAAK,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IAAA;AAGV,UAAM,KAAK,eAAe,KAAK,GAAG;AAElC,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ;AACZ,SAAK,oBAAoB;AACzB,UAAM,SAAS,MAAM,KAAK,eAAA;AAC1B,SAAK,oBAAoB;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,KAAsB;AACjDD,SAAAA,YAAY,MAAM;AAChB,WAAK,MAAM;AACX,WAAK,SAAS;AAAA,IAChB,CAAC;AAED,QAAK,MAAM,KAAK,OAAO,aAAa,IAAI,QAAQ,IAAI,MAAO,OAAO;AAChEA,WAAAA,YAAY,MAAM;AAChB,aAAK,SAAS;AACd,aAAK,MAAM;AAAA,MACb,CAAC;AACD;AAAA,IACF;AAEA,QAAK,MAAM,KAAK,OAAO,OAAO,IAAI,QAAQ,IAAI,MAAO,OAAO;AAC1DA,WAAAA,YAAY,MAAM;AAChB,aAAK,SAAS;AACd,aAAK,MAAM;AAAA,MACb,CAAC;AACD;AAAA,IACF;AAEAA,SAAAA,YAAY,MAAM;AAChB,UAAI,IAAI,OAAO,OAAO;AACpB,aAAK,MAAM,OAAO,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO;AAAA,MACtD;AAEA,WAAK,MAAM;AACX,WAAK,SAAS,IAAI;AAClB,WAAK,SAAS;AACd,WAAK,OAAO,YAAY,KAAK,QAAS,IAAI;AAAA,IAC5C,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,iBAAiB;AAC7B,QAAI,KAAK,WAAW,UAAU;AAC5B,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,KAAK;AAExBA,SAAAA,YAAY,MAAM;AAChB,WAAK,SAAS;AAAA,IAChB,CAAC;AAED,QAAK,MAAM,KAAK,OAAO,cAAA,MAAqB,OAAO;AACjDA,WAAAA,YAAY,MAAM;AAChB,aAAK,SAAS;AAAA,MAChB,CAAC;AACD;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,QAAQ,IAAI,MAAM,OAAO;AACvCA,WAAAA,YAAY,MAAM;AAChB,aAAK,SAAS;AAAA,MAChB,CAAC;AACD;AAAA,IACF;AAEAA,SAAAA,YAAY,MAAM;AAChB,WAAK,SAAS;AACd,WAAK,SAAS;AAAA,IAChB,CAAC;AAED,SAAK,OAAO,aAAA;AAEZ,WAAO;AAAA,EACT;AAAA,EAEA,UAAU;AACR,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,WAAA;AAAA,EACP;AACF;AAEO,MAAM,qBAAqB,CAGhC,WACG,IAAI,aAAsB,MAAM;;;;;;;;;;;;;;;;;"}
package/index.d.ts CHANGED
@@ -9,6 +9,7 @@ interface VirtualOpenExtraParams extends Omit<RouteNavigateParams, 'state' | 'me
9
9
  }
10
10
  interface AbstractVirtualRoute<TParams extends AnyObject | EmptyObject = EmptyObject> {
11
11
  isOpened: boolean;
12
+ isOpening: boolean;
12
13
  params: TParams | null;
13
14
  /**
14
15
  * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#open)
@@ -348,6 +349,10 @@ declare class Route<TPath extends string, TInputParams extends InputPathParams<T
348
349
  protected get parsedPathData(): ParsedPathData<TPath> | null;
349
350
  /**
350
351
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)
352
+ *
353
+ * Also true in the short gap after history already matches this route but
354
+ * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every
355
+ * route looks closed for one tick and RouteViewGroup unmounts the page.
351
356
  */
352
357
  get isOpening(): boolean;
353
358
  /**
package/index.js CHANGED
@@ -152,9 +152,19 @@ class Route {
152
152
  }
153
153
  /**
154
154
  * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#isopening)
155
+ *
156
+ * Also true in the short gap after history already matches this route but
157
+ * `confirmOpening` has not started yet (e.g. browser Back) — otherwise every
158
+ * route looks closed for one tick and RouteViewGroup unmounts the page.
155
159
  */
156
160
  get isOpening() {
157
- return this.status === "opening";
161
+ if (this.status === "opening") {
162
+ return true;
163
+ }
164
+ if (this.isDestroyed || !this.isPathMatched || this.params === null || this.status === "open-confirmed" || this.status === "open-rejected") {
165
+ return false;
166
+ }
167
+ return this.status === "closed" || this.status === "unknown";
158
168
  }
159
169
  /**
160
170
  * Matched path segment for current URL.
@@ -408,6 +418,11 @@ class Route {
408
418
  }
409
419
  return;
410
420
  }
421
+ if (this.status !== "opening" && this.status !== "open-confirmed") {
422
+ runInAction(() => {
423
+ this.status = "opening";
424
+ });
425
+ }
411
426
  const trx = {
412
427
  url: this.parsedPathData.path,
413
428
  params: this.parsedPathData.params,
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.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/utils/is-route-entity.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 { 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 TParentRoute extends Route<any, any, any, any> | null = null,\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: TParentRoute;\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\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 TParentRoute\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 as unknown as TParentRoute);\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.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 get isOpening() {\n return this.status === 'opening';\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 let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\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 >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\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 return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\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<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\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 }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\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,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\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 ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\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(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\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 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 runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\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 this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\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 }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(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 type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } 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<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\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 /**\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 }\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 ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\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.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 this.config.afterOpen?.(this.params!, this);\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 }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["annotations"],"mappings":"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"}
1
+ {"version":3,"file":"index.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/utils/is-route-entity.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 { 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 TParentRoute extends Route<any, any, any, any> | null = null,\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: TParentRoute;\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\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 TParentRoute\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 as unknown as TParentRoute);\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.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 let params: TOutputParams | null =\n (this.parsedPathData?.params as unknown as Maybe<TOutputParams>) ?? null;\n\n if (this.config.params) {\n const result = this.config.params(\n this.parsedPathData.params,\n this.config.meta,\n );\n if (result) {\n params = result;\n } else {\n return null;\n }\n }\n\n return params;\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 >(\n pathDeclaration: TExtendedPath,\n config?: Omit<\n RouteConfiguration<\n `${TPath}${TExtendedPath}`,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n any\n >,\n 'parent'\n >,\n ) {\n type ExtendedRoutePath = `${TPath}${TExtendedPath}`;\n type ParentRoute = this;\n const { index, params, exact, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\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 return Object.entries(params).reduce((acc, [key, value]) => {\n if (value != null) {\n acc[key] = Array.isArray(value) ? value.map(String) : String(value);\n }\n return acc;\n }, {} as ParamData);\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<AnyObject>,\n mergeQueryOrParams?: boolean | CreatedUrlOutputParams,\n ]\n : [\n params: TInputParams,\n query?: Maybe<AnyObject>,\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 }\n : (rawQuery ?? {});\n\n this._compiler ??= compile(this.tokenData);\n\n const defaultUrlCreateParams: UrlCreateParams<TInputParams> = {\n baseUrl: this.baseUrl,\n params: params as TInputParams,\n query,\n };\n const urlCreateParams: UrlCreateParams<TInputParams> =\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,\n ]\n : [params: TInputParams, navigateParams?: RouteNavigateParams]\n ): Promise<void>;\n open(\n ...args: IsPartial<TInputParams> extends true\n ? [\n params?: TInputParams | null | undefined,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n : [\n params: TInputParams,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ]\n ): Promise<void>;\n open(url: string, navigateParams?: RouteNavigateParams): Promise<void>;\n open(\n url: string,\n replace?: RouteNavigateParams['replace'],\n query?: RouteNavigateParams['query'],\n ): Promise<void>;\n\n /**\n * Navigates to this route.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#open)\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 ? ({ replace: args[1], query: args[2] } as RouteNavigateParams)\n : ((args[1] ?? {}) as RouteNavigateParams);\n let url: string;\n let params: Maybe<InputPathParams<TPath>>;\n\n const mergeQuery = rawMergeQuery ?? this.isAbleToMergeQuery;\n const query = mergeQuery ? { ...this.query.data, ...rawQuery } : rawQuery;\n\n if (typeof args[0] === 'string') {\n url = args[0];\n } else {\n params = args[0] as InputPathParams<TPath>;\n url = this.createUrl(args[0], query);\n }\n\n const state = rawState ?? null;\n\n const trx: NavigationTrx<TInputParams> = {\n url,\n params: params as TInputParams,\n replace,\n state,\n query,\n };\n\n this.ignoreOpenByPathMatch = true;\n const isConfirmed = await this.confirmOpening(trx);\n\n if (isConfirmed !== true) {\n this.ignoreOpenByPathMatch = false;\n }\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(trx: NavigationTrx<TInputParams>) {\n runInAction(() => {\n this.status = 'opening';\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 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 runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n this.config.afterOpen?.(this.parsedPathData!, this);\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 this.config.afterOpen?.(this.parsedPathData, this);\n }\n return;\n }\n\n // Sync before any await — closes the Back gap where isOpened/isOpening\n // were both false until confirmOpening's first runInAction ran.\n if (this.status !== 'opening' && this.status !== 'open-confirmed') {\n runInAction(() => {\n this.status = 'opening';\n });\n }\n\n const trx: NavigationTrx<TInputParams> = {\n url: this.parsedPathData!.path,\n params: this.parsedPathData!.params as TInputParams,\n state: this.history.location.state,\n query: this.query.data,\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 }\n}\n\nexport const createRoute = <\n TPath extends string,\n TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>,\n TOutputParams extends AnyObject = ParsedPathParams<TPath>,\n TParentRoute extends Route<any, any, any, any> | null = null,\n>(\n path: TPath,\n config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>,\n) => new Route<TPath, TInputParams, TOutputParams, TParentRoute>(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 type { AnyRouteEntity } from '../route-group/index.js';\n\nexport const isRouteEntity = (route: any): route is AnyRouteEntity =>\n route && 'isOpened' in route;\n","import { action, computed, observable, reaction, runInAction } 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<TParams extends AnyObject | EmptyObject = EmptyObject>\n implements AbstractVirtualRoute<TParams>\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 /**\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 }\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 ? [params?: Maybe<TParams>, extraParams?: VirtualOpenExtraParams]\n : [params: TParams, extraParams?: VirtualOpenExtraParams]\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.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 this.config.afterOpen?.(this.params!, this);\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 }\n}\n\nexport const createVirtualRoute = <\n TParams extends AnyObject | EmptyObject = EmptyObject,\n>(\n config?: VirtualRouteConfiguration<TParams>,\n) => new VirtualRoute<TParams>(config);\n"],"names":["annotations"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx-route",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "keywords": [
5
5
  "mobx",
6
6
  "react",
package/react.cjs CHANGED
@@ -88,7 +88,8 @@ function RouteViewBase(props) {
88
88
  if (!("route" in props)) {
89
89
  return typeof props.children === "function" ? props.children() : props.children;
90
90
  }
91
- if (!props.route.isOpened) {
91
+ const isOpening = "isOpening" in props.route && Boolean(props.route.isOpening);
92
+ if (!props.route.isOpened && !isOpening) {
92
93
  return props.fallback ?? null;
93
94
  }
94
95
  Component = props.view;
@@ -121,15 +122,15 @@ const RouteViewGroup = mobxReactLite.observer(
121
122
  mobxRoute.isRouteEntity(childNode.props?.route);
122
123
  if (isRouteChild) {
123
124
  const route = childNode.props.route;
124
- if (route.isOpened) {
125
+ if (route.isOpened || route.isOpening) {
125
126
  activeChildRouteNode = childNode;
126
- if (!useLastOpened) {
127
- break;
128
- }
129
- } else {
130
127
  if (route.isOpening) {
131
128
  hasRoutesInOpening = true;
132
129
  }
130
+ if (!useLastOpened && route.isOpened) {
131
+ break;
132
+ }
133
+ } else {
133
134
  lastInactiveChildNode = childNode;
134
135
  }
135
136
  } else {
package/react.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n if (!props.route.isOpened) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n if (route.isOpened) {\n activeChildRouteNode = childNode;\n if (!useLastOpened) {\n break;\n }\n } else {\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["observer","forwardRef","useRef","isShallowEqual","useMemo","navigateParams","routeConfig","href","parseSearchString","query","buildSearchString","isValidElement","cloneElement","jsx","isRouteEntity","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"react.cjs","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n const isOpening =\n 'isOpening' in props.route &&\n Boolean((props.route as { isOpening?: boolean }).isOpening);\n\n if (!props.route.isOpened && !isOpening) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n // Keep the matched/opening route selected during confirmOpening and the\n // pre-reaction Back gap (isOpening covers path-matched + not confirmed).\n if (route.isOpened || route.isOpening) {\n activeChildRouteNode = childNode;\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n if (!useLastOpened && route.isOpened) {\n break;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["observer","forwardRef","useRef","isShallowEqual","useMemo","navigateParams","routeConfig","href","parseSearchString","query","buildSearchString","isValidElement","cloneElement","jsx","isRouteEntity","useEffect"],"mappings":"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"}
package/react.js CHANGED
@@ -86,7 +86,8 @@ function RouteViewBase(props) {
86
86
  if (!("route" in props)) {
87
87
  return typeof props.children === "function" ? props.children() : props.children;
88
88
  }
89
- if (!props.route.isOpened) {
89
+ const isOpening = "isOpening" in props.route && Boolean(props.route.isOpening);
90
+ if (!props.route.isOpened && !isOpening) {
90
91
  return props.fallback ?? null;
91
92
  }
92
93
  Component = props.view;
@@ -119,15 +120,15 @@ const RouteViewGroup = observer(
119
120
  isRouteEntity(childNode.props?.route);
120
121
  if (isRouteChild) {
121
122
  const route = childNode.props.route;
122
- if (route.isOpened) {
123
+ if (route.isOpened || route.isOpening) {
123
124
  activeChildRouteNode = childNode;
124
- if (!useLastOpened) {
125
- break;
126
- }
127
- } else {
128
125
  if (route.isOpening) {
129
126
  hasRoutesInOpening = true;
130
127
  }
128
+ if (!useLastOpened && route.isOpened) {
129
+ break;
130
+ }
131
+ } else {
131
132
  lastInactiveChildNode = childNode;
132
133
  }
133
134
  } else {
package/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n if (!props.route.isOpened) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n if (route.isOpened) {\n activeChildRouteNode = childNode;\n if (!useLastOpened) {\n break;\n }\n } else {\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["navigateParams","href","query"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","sources":["../src/react/components/link.tsx","../src/react/components/route-view.tsx","../src/react/components/route-view-group.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n buildSearchString,\n type InputPathParams,\n parseSearchString,\n type RouteNavigateParams,\n routeConfig,\n} from 'mobx-route';\nimport {\n type AnchorHTMLAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n type MouseEvent,\n useMemo,\n useRef,\n} from 'react';\nimport { isShallowEqual } from 'yummies/data';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ninterface LinkAnchorProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {\n asChild?: boolean;\n}\n\ntype LinkPathRouteProps<TRoute extends AnyRoute> = {\n to: TRoute;\n} & (IsPartial<InputPathParams<TRoute['pathDeclaration']>> extends true\n ? {\n params?: InputPathParams<TRoute['pathDeclaration']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['pathDeclaration']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: Maybe<string>;\n };\n\nexport type LinkProps<TRoute extends AnyRoute> = LinkAnchorProps &\n RouteNavigateParams &\n (LinkPathRouteProps<TRoute> | LinkSimpleRouteProps);\n\ntype LinkComponentType = <TRoute extends AnyRoute>(\n props: LinkProps<TRoute>,\n) => React.ReactNode;\n\nexport const Link = observer(\n forwardRef<\n HTMLAnchorElement,\n LinkAnchorProps &\n RouteNavigateParams & {\n params?: any;\n to: string | AnyRoute;\n href: string;\n }\n >((props, ref) => {\n const {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n //\n ...outerAnchorProps\n } = props;\n\n const isExternalNavigation =\n outerAnchorProps.target === '_blank' ||\n outerAnchorProps.target === 'blank';\n const queryDataRef = useRef<RouteNavigateParams['query']>(query);\n\n if (!isShallowEqual(queryDataRef.current, query)) {\n queryDataRef.current = query;\n }\n\n const { href, navigateParams } = useMemo(() => {\n const navigateParams: RouteNavigateParams = {\n mergeQuery,\n query,\n replace,\n state,\n };\n\n const cfg = routeConfig.get();\n\n let href: string = '';\n\n if (outerHref) {\n href = outerHref;\n } else if (to) {\n if (typeof to === 'string') {\n const isNeedToMergeQuery =\n navigateParams.mergeQuery ?? cfg.mergeQuery;\n\n const [path, ...querySegments] = to.split('?');\n\n const existedQuery = parseSearchString(querySegments.join('?'));\n\n const query = {\n ...(isNeedToMergeQuery ? cfg.queryParams.data : {}),\n ...existedQuery,\n ...navigateParams.query,\n };\n\n href = `${path}${buildSearchString(query)}`;\n } else {\n href = to.createUrl(\n params,\n navigateParams.query,\n navigateParams.mergeQuery,\n );\n }\n }\n\n return {\n href: cfg.formatLinkHref?.(href) ?? href,\n navigateParams,\n };\n }, [mergeQuery, replace, state, outerHref, to, queryDataRef.current]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (\n isExternalNavigation ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n\n outerAnchorProps.onClick?.(event);\n\n if (\n !event.defaultPrevented &&\n !href.startsWith('https://') &&\n !href.startsWith('http://')\n ) {\n event.preventDefault();\n\n if (navigateParams.replace) {\n routeConfig.get().history.replace(href, navigateParams.state);\n } else {\n routeConfig.get().history.push(href, navigateParams.state);\n }\n }\n };\n\n const anchorProps = {\n ...outerAnchorProps,\n href,\n onClick: handleClick,\n rel:\n outerAnchorProps.rel ??\n (isExternalNavigation ? 'noopener noreferrer' : undefined),\n };\n\n return asChild && isValidElement(children) ? (\n cloneElement(children, anchorProps)\n ) : (\n <a {...anchorProps} ref={ref}>\n {children}\n </a>\n );\n }),\n) as unknown as LinkComponentType;\n","import { observer } from 'mobx-react-lite';\nimport type {\n AnyAbstractRouteEntity,\n AnyRoute,\n AnyVirtualRoute,\n} from 'mobx-route';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\nexport interface RouteViewConfigWithRoute<\n TRoute extends AnyAbstractRouteEntity,\n> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n let Component: React.ComponentType<any> | undefined;\n\n if (!('route' in props)) {\n return typeof props.children === 'function'\n ? props.children()\n : props.children;\n }\n\n const isOpening =\n 'isOpening' in props.route &&\n Boolean((props.route as { isOpening?: boolean }).isOpening);\n\n if (!props.route.isOpened && !isOpening) {\n return props.fallback ?? null;\n }\n\n Component = props.view;\n\n const params: any = 'params' in props.route ? props.route.params : {};\n\n if (Component) {\n return <Component params={params}>{props.children}</Component>;\n }\n\n if (typeof props.children === 'function') {\n return props.children(params, props.route);\n }\n\n return props.children;\n}\n\nexport const RouteView = observer(RouteViewBase) as RouteViewBaseComponent;\n","import { observer } from 'mobx-react-lite';\nimport {\n type AnyRoute,\n type AnyRouteEntity,\n buildSearchString,\n isRouteEntity,\n type RouteNavigateParams,\n type RouteParams,\n routeConfig,\n} from 'mobx-route';\nimport { isValidElement, useEffect } from 'react';\nimport type { IsPartial, Maybe } from 'yummies/types';\n\ntype LayoutComponent =\n | React.ComponentType<{ children?: React.ReactNode }>\n | React.ComponentType<{ children: React.ReactNode }>;\n\ninterface BaseProps extends RouteNavigateParams {\n children: React.ReactNode;\n layout?: LayoutComponent;\n useLastOpened?: boolean;\n}\n\ntype PropsWithDefaultRoute<TRoute extends AnyRouteEntity> = BaseProps & {\n otherwise?: TRoute;\n} & (IsPartial<RouteParams<TRoute>> extends true\n ? {\n params?: Maybe<RouteParams<TRoute>>;\n }\n : {\n params: RouteParams<TRoute>;\n });\n\ntype PropsWithDefaultUrl = BaseProps & {\n otherwise?: string;\n};\n\nexport type RouteViewGroupProps<TRoute extends AnyRouteEntity> =\n | PropsWithDefaultRoute<TRoute>\n | PropsWithDefaultUrl;\n\ntype RouteViewGroupComponent = <TRoute extends AnyRouteEntity>(\n props: RouteViewGroupProps<TRoute>,\n) => React.ReactNode;\n\nexport const RouteViewGroup = observer(\n <TRoute extends AnyRouteEntity>({\n children,\n layout: Layout,\n otherwise: otherwiseNavigation,\n useLastOpened,\n // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildRouteNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n let hasRoutesInOpening = false;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n const isRouteChild =\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route);\n\n if (isRouteChild) {\n const route = (childNode.props as any).route as AnyRoute;\n\n // Keep the matched/opening route selected during confirmOpening and the\n // pre-reaction Back gap (isOpening covers path-matched + not confirmed).\n if (route.isOpened || route.isOpening) {\n activeChildRouteNode = childNode;\n if (route.isOpening) {\n hasRoutesInOpening = true;\n }\n if (!useLastOpened && route.isOpened) {\n break;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildRouteNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {\n if (typeof otherwiseNavigation === 'string') {\n const history = routeConfig.get().history;\n const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;\n\n if (navigateParams.replace) {\n history.replace(url, navigateParams.state);\n } else {\n history.push(url, navigateParams.state);\n }\n } else if (!otherwiseNavigation.isOpened) {\n otherwiseNavigation.open(params, navigateParams);\n }\n }\n }, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildRouteNode) {\n return null;\n }\n\n const resultNodeToRender =\n activeChildRouteNode ?? lastInactiveChildNode ?? null;\n\n if (Layout) {\n return <Layout>{resultNodeToRender}</Layout>;\n }\n\n return resultNodeToRender;\n },\n) as unknown as RouteViewGroupComponent;\n"],"names":["navigateParams","href","query"],"mappings":"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"}