mobx-route 0.26.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +5 -5
- package/index.cjs.map +1 -1
- package/index.d.ts +11 -6
- package/index.js +5 -5
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/react.cjs.map +1 -1
- package/react.d.ts +3 -0
- package/react.js.map +1 -1
package/index.cjs
CHANGED
|
@@ -380,7 +380,7 @@ class RouteGroup {
|
|
|
380
380
|
/**
|
|
381
381
|
* Returns true if at least one route in the group is open.
|
|
382
382
|
*
|
|
383
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
383
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)
|
|
384
384
|
*/
|
|
385
385
|
get isOpened() {
|
|
386
386
|
const routes = Object.values(this.routes);
|
|
@@ -391,7 +391,7 @@ class RouteGroup {
|
|
|
391
391
|
/**
|
|
392
392
|
* First found index route.
|
|
393
393
|
*
|
|
394
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
394
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)
|
|
395
395
|
*/
|
|
396
396
|
get indexRoute() {
|
|
397
397
|
return this._indexRoute ?? Object.values(this.routes).find(
|
|
@@ -401,7 +401,7 @@ class RouteGroup {
|
|
|
401
401
|
/**
|
|
402
402
|
* Main navigation method for the group.
|
|
403
403
|
*
|
|
404
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
404
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)
|
|
405
405
|
*/
|
|
406
406
|
open(...args) {
|
|
407
407
|
let lastGroupRoute;
|
|
@@ -424,7 +424,7 @@ class RouteGroup {
|
|
|
424
424
|
}
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
|
-
const
|
|
427
|
+
const groupRoutes = (routes, indexRoute) => new RouteGroup(routes, indexRoute);
|
|
428
428
|
const annotations$1 = [
|
|
429
429
|
[mobx.computed.struct, "location"]
|
|
430
430
|
];
|
|
@@ -627,9 +627,9 @@ exports.RouteGroup = RouteGroup;
|
|
|
627
627
|
exports.Router = Router;
|
|
628
628
|
exports.VirtualRoute = VirtualRoute;
|
|
629
629
|
exports.createRoute = createRoute;
|
|
630
|
-
exports.createRouteGroup = createRouteGroup;
|
|
631
630
|
exports.createRouter = createRouter;
|
|
632
631
|
exports.createVirtualRoute = createVirtualRoute;
|
|
632
|
+
exports.groupRoutes = groupRoutes;
|
|
633
633
|
exports.isRouteEntity = isRouteEntity;
|
|
634
634
|
exports.routeConfig = routeConfig;
|
|
635
635
|
Object.keys(mobxLocationHistory).forEach((k) => {
|
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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\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 protected abortController: AbortController;\n protected history: History;\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 * 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 children: AnyRoute[] = [];\n\n constructor(\n public pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.abortController = new LinkedAbortController(config.abortSignal);\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\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 reaction(() => this.isPathMatched, this.checkPathMatch, {\n signal: this.abortController.signal,\n fireImmediately: true,\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 protected get parsedPathData(): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n 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 (!this.history.location.pathname.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 /**\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 * 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.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 // biome-ignore lint/correctness/noUnusedVariables: this is need to extract unused fields\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 addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\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 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 console.error('Error while compiling route path', e);\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.abortController.signal.aborted) {\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 destroy() {\n this.abortController.abort();\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'],\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/RouteGroup.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/RouteGroup.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/RouteGroup.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 * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/RouteGroup.html#open)\n */\n open(...args: any[]) {\n let lastGroupRoute: RouteGroup<any> | undefined;\n\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) {\n lastGroupRoute = route;\n }\n }\n\n if (lastGroupRoute) {\n lastGroupRoute.open(...args);\n } else if (process.env.NODE_ENV !== 'production') {\n console.warn(\n \"RouteGroup doesn't have index route. open() method doesn't work.\",\n );\n }\n }\n}\n\nexport const createRouteGroup = <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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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'],\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 query: IQueryParams;\n params: TParams | null;\n\n protected abortController: AbortController;\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.abortController = new LinkedAbortController(config.abortSignal);\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 this.abortController.signal.addEventListener(\n 'abort',\n action(() => {\n this.status = 'unknown';\n }),\n );\n\n 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 // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutomatedOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmClosing();\n }\n }),\n { signal: this.abortController.signal, fireImmediately: true },\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 this.status === 'opened' && this.isOuterOpened !== false;\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 return true;\n }\n\n destroy() {\n this.abortController.abort();\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","LinkedAbortController","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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\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 protected abortController: AbortController;\n protected history: History;\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 * 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 children: AnyRoute[] = [];\n\n constructor(\n public pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.abortController = new LinkedAbortController(config.abortSignal);\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\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 reaction(() => this.isPathMatched, this.checkPathMatch, {\n signal: this.abortController.signal,\n fireImmediately: true,\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 protected get parsedPathData(): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n 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 (!this.history.location.pathname.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 /**\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 * 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.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 // biome-ignore lint/correctness/noUnusedVariables: this is need to extract unused fields\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 addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\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 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 console.error('Error while compiling route path', e);\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.abortController.signal.aborted) {\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 destroy() {\n this.abortController.abort();\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'],\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 * 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 let lastGroupRoute: RouteGroup<any> | undefined;\n\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) {\n lastGroupRoute = route;\n }\n }\n\n if (lastGroupRoute) {\n lastGroupRoute.open(...args);\n } else if (process.env.NODE_ENV !== 'production') {\n console.warn(\n \"RouteGroup doesn't have index route. open() method doesn't work.\",\n );\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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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'],\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 query: IQueryParams;\n params: TParams | null;\n\n protected abortController: AbortController;\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.abortController = new LinkedAbortController(config.abortSignal);\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 this.abortController.signal.addEventListener(\n 'abort',\n action(() => {\n this.status = 'unknown';\n }),\n );\n\n 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 // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutomatedOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmClosing();\n }\n }),\n { signal: this.abortController.signal, fireImmediately: true },\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 this.status === 'opened' && this.isOuterOpened !== false;\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 return true;\n }\n\n destroy() {\n this.abortController.abort();\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","LinkedAbortController","applyObservable","reaction","match","compile","buildSearchString","parse","runInAction","action","callFunction"],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -126,7 +126,7 @@ declare const createVirtualRoute: <TParams extends AnyObject | EmptyObject = Emp
|
|
|
126
126
|
/**
|
|
127
127
|
* Class for grouping related routes and managing their state.
|
|
128
128
|
*
|
|
129
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
129
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)
|
|
130
130
|
*/
|
|
131
131
|
declare class RouteGroup<TRoutesCollection extends RoutesCollection> implements AbstractRouteGroup<TRoutesCollection> {
|
|
132
132
|
private _indexRoute?;
|
|
@@ -135,23 +135,28 @@ declare class RouteGroup<TRoutesCollection extends RoutesCollection> implements
|
|
|
135
135
|
/**
|
|
136
136
|
* Returns true if at least one route in the group is open.
|
|
137
137
|
*
|
|
138
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
138
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)
|
|
139
139
|
*/
|
|
140
140
|
get isOpened(): boolean;
|
|
141
141
|
/**
|
|
142
142
|
* First found index route.
|
|
143
143
|
*
|
|
144
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
144
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)
|
|
145
145
|
*/
|
|
146
146
|
get indexRoute(): AnyRouteEntity | undefined;
|
|
147
147
|
/**
|
|
148
148
|
* Main navigation method for the group.
|
|
149
149
|
*
|
|
150
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
150
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)
|
|
151
151
|
*/
|
|
152
152
|
open(...args: any[]): void;
|
|
153
153
|
}
|
|
154
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Helper for creating route groups.
|
|
156
|
+
*
|
|
157
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html)
|
|
158
|
+
*/
|
|
159
|
+
declare const groupRoutes: <TRoutesCollection extends RoutesCollection>(routes: TRoutesCollection, indexRoute?: AnyRouteEntity) => RouteGroup<TRoutesCollection>;
|
|
155
160
|
|
|
156
161
|
type AnyRouteGroup = RouteGroup<RoutesCollection>;
|
|
157
162
|
type AnyRouteEntity = AnyRoute | AnyRouteGroup | AnyVirtualRoute;
|
|
@@ -418,5 +423,5 @@ declare const createRouter: <TRoutesCollection extends RoutesCollection>(config:
|
|
|
418
423
|
|
|
419
424
|
declare const isRouteEntity: (route: any) => route is AnyRouteEntity;
|
|
420
425
|
|
|
421
|
-
export { Route, RouteGroup, Router, VirtualRoute, createRoute,
|
|
426
|
+
export { Route, RouteGroup, Router, VirtualRoute, createRoute, createRouter, createVirtualRoute, groupRoutes, isRouteEntity, routeConfig };
|
|
422
427
|
export type { AbstractRouteGroup, AbstractVirtualRoute, AnyAbstractRoute, AnyAbstractRouteEntity, AnyRoute, AnyRouteEntity, AnyRouteGroup, AnyRouter, AnyVirtualRoute, BeforeOpenFeedback, CreatedUrlOutputParams, InferInputParams, InferParams, InferPath, InputPathParam, InputPathParams, NavigationTrx, ParsedPathData, ParsedPathParam, ParsedPathParams, PathToObject, RouteConfiguration, RouteGlobalConfig, RouteNavigateParams, RouteParams, RouterConfiguration, RouterNavigateOptions, RoutesArrayCollection, RoutesCollection, RoutesObjectCollection, UrlCreateParams, UrlCreateParamsFn, VirtualOpenExtraParams, VirtualRouteConfiguration, VirtualRouteTrx };
|
package/index.js
CHANGED
|
@@ -379,7 +379,7 @@ class RouteGroup {
|
|
|
379
379
|
/**
|
|
380
380
|
* Returns true if at least one route in the group is open.
|
|
381
381
|
*
|
|
382
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
382
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#isopened)
|
|
383
383
|
*/
|
|
384
384
|
get isOpened() {
|
|
385
385
|
const routes = Object.values(this.routes);
|
|
@@ -390,7 +390,7 @@ class RouteGroup {
|
|
|
390
390
|
/**
|
|
391
391
|
* First found index route.
|
|
392
392
|
*
|
|
393
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
393
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#indexroute)
|
|
394
394
|
*/
|
|
395
395
|
get indexRoute() {
|
|
396
396
|
return this._indexRoute ?? Object.values(this.routes).find(
|
|
@@ -400,7 +400,7 @@ class RouteGroup {
|
|
|
400
400
|
/**
|
|
401
401
|
* Main navigation method for the group.
|
|
402
402
|
*
|
|
403
|
-
* [**Documentation**](https://js2me.github.io/mobx-route/core/
|
|
403
|
+
* [**Documentation**](https://js2me.github.io/mobx-route/core/groupRoutes.html#open)
|
|
404
404
|
*/
|
|
405
405
|
open(...args) {
|
|
406
406
|
let lastGroupRoute;
|
|
@@ -423,7 +423,7 @@ class RouteGroup {
|
|
|
423
423
|
}
|
|
424
424
|
}
|
|
425
425
|
}
|
|
426
|
-
const
|
|
426
|
+
const groupRoutes = (routes, indexRoute) => new RouteGroup(routes, indexRoute);
|
|
427
427
|
const annotations$1 = [
|
|
428
428
|
[computed.struct, "location"]
|
|
429
429
|
];
|
|
@@ -627,9 +627,9 @@ export {
|
|
|
627
627
|
Router,
|
|
628
628
|
VirtualRoute,
|
|
629
629
|
createRoute,
|
|
630
|
-
createRouteGroup,
|
|
631
630
|
createRouter,
|
|
632
631
|
createVirtualRoute,
|
|
632
|
+
groupRoutes,
|
|
633
633
|
isRouteEntity,
|
|
634
634
|
routeConfig
|
|
635
635
|
};
|
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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\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 protected abortController: AbortController;\n protected history: History;\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 * 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 children: AnyRoute[] = [];\n\n constructor(\n public pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.abortController = new LinkedAbortController(config.abortSignal);\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\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 reaction(() => this.isPathMatched, this.checkPathMatch, {\n signal: this.abortController.signal,\n fireImmediately: true,\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 protected get parsedPathData(): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n 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 (!this.history.location.pathname.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 /**\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 * 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.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 // biome-ignore lint/correctness/noUnusedVariables: this is need to extract unused fields\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 addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\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 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 console.error('Error while compiling route path', e);\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.abortController.signal.aborted) {\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 destroy() {\n this.abortController.abort();\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'],\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/RouteGroup.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/RouteGroup.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/RouteGroup.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 * Main navigation method for the group.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/RouteGroup.html#open)\n */\n open(...args: any[]) {\n let lastGroupRoute: RouteGroup<any> | undefined;\n\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) {\n lastGroupRoute = route;\n }\n }\n\n if (lastGroupRoute) {\n lastGroupRoute.open(...args);\n } else if (process.env.NODE_ENV !== 'production') {\n console.warn(\n \"RouteGroup doesn't have index route. open() method doesn't work.\",\n );\n }\n }\n}\n\nexport const createRouteGroup = <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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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'],\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 query: IQueryParams;\n params: TParams | null;\n\n protected abortController: AbortController;\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.abortController = new LinkedAbortController(config.abortSignal);\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 this.abortController.signal.addEventListener(\n 'abort',\n action(() => {\n this.status = 'unknown';\n }),\n );\n\n 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 // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutomatedOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmClosing();\n }\n }),\n { signal: this.abortController.signal, fireImmediately: true },\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 this.status === 'opened' && this.isOuterOpened !== false;\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 return true;\n }\n\n destroy() {\n this.abortController.abort();\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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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\nconst annotations: ObservableAnnotationsArray<Route<any, any, any, any>> = [\n [\n computed,\n 'isPathMatched',\n 'isOpened',\n 'isOpening',\n 'path',\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 protected abortController: AbortController;\n protected history: History;\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 * 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 children: AnyRoute[] = [];\n\n constructor(\n public pathDeclaration: TPath,\n protected config: RouteConfiguration<\n TPath,\n TInputParams,\n TOutputParams,\n TParentRoute\n > = {},\n ) {\n this.abortController = new LinkedAbortController(config.abortSignal);\n this.history = config.history ?? routeConfig.get().history;\n this.query = config.queryParams ?? routeConfig.get().queryParams;\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 reaction(() => this.isPathMatched, this.checkPathMatch, {\n signal: this.abortController.signal,\n fireImmediately: true,\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 protected get parsedPathData(): ParsedPathData<TPath> | null {\n let pathnameToCheck: string;\n\n 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 (!this.history.location.pathname.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 /**\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 * 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.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 // biome-ignore lint/correctness/noUnusedVariables: this is need to extract unused fields\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 addChildren(...routes: AnyRoute[]) {\n this.children.push(...routes);\n }\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 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 console.error('Error while compiling route path', e);\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.abortController.signal.aborted) {\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 destroy() {\n this.abortController.abort();\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'],\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 * 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 let lastGroupRoute: RouteGroup<any> | undefined;\n\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) {\n lastGroupRoute = route;\n }\n }\n\n if (lastGroupRoute) {\n lastGroupRoute.open(...args);\n } else if (process.env.NODE_ENV !== 'production') {\n console.warn(\n \"RouteGroup doesn't have index route. open() method doesn't work.\",\n );\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 { LinkedAbortController } from 'linked-abort-controller';\nimport { 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'],\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 query: IQueryParams;\n params: TParams | null;\n\n protected abortController: AbortController;\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.abortController = new LinkedAbortController(config.abortSignal);\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 this.abortController.signal.addEventListener(\n 'abort',\n action(() => {\n this.status = 'unknown';\n }),\n );\n\n 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 // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmOpening({\n params: this.params ?? null,\n ...this.config.getAutomatedOpenParams?.(this),\n });\n } else {\n if (this.status === 'closed' || this.status === 'unknown') {\n return;\n }\n // biome-ignore lint/nursery/noFloatingPromises: <explanation>\n this.confirmClosing();\n }\n }),\n { signal: this.abortController.signal, fireImmediately: true },\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 this.status === 'opened' && this.isOuterOpened !== false;\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 return true;\n }\n\n destroy() {\n this.abortController.abort();\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": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"mobx",
|
|
6
6
|
"react",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"linked-abort-controller": "^1.1.1",
|
|
26
|
-
"mobx-location-history": "^9.
|
|
26
|
+
"mobx-location-history": "^9.3.0",
|
|
27
27
|
"path-to-regexp": "^8.3.0",
|
|
28
28
|
"react-simple-loadable": "^3.1.0",
|
|
29
29
|
"yummies": "^7.0.1"
|
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';\nimport { type LoadableConfig, loadable } from 'react-simple-loadable';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\ntype LoadViewFn<TRoute extends AnyAbstractRouteEntity> = (\n route: TRoute,\n) => Promise<RouteViewComponent<TRoute>>;\n\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n loadView?: LoadViewFn<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 const loadViewFn = props.loadView as\n | (LoadViewFn<TRoute> & { _loadableComponent: any })\n | undefined;\n\n if (loadViewFn) {\n if (!loadViewFn._loadableComponent) {\n loadViewFn._loadableComponent = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n cache: false,\n });\n }\n Component = loadViewFn._loadableComponent;\n } else {\n Component = props.view;\n }\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","loadable","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';\nimport { type LoadableConfig, loadable } from 'react-simple-loadable';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\ntype LoadViewFn<TRoute extends AnyAbstractRouteEntity> = (\n route: TRoute,\n) => Promise<RouteViewComponent<TRoute>>;\n\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * @deprecated use your own load fn for lazy load view\n */\n loadView?: LoadViewFn<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 const loadViewFn = props.loadView as\n | (LoadViewFn<TRoute> & { _loadableComponent: any })\n | undefined;\n\n if (loadViewFn) {\n if (!loadViewFn._loadableComponent) {\n loadViewFn._loadableComponent = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n cache: false,\n });\n }\n Component = loadViewFn._loadableComponent;\n } else {\n Component = props.view;\n }\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","loadable","isRouteEntity","useEffect"],"mappings":"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"}
|
package/react.d.ts
CHANGED
|
@@ -30,6 +30,9 @@ type LoadViewFn<TRoute extends AnyAbstractRouteEntity> = (route: TRoute) => Prom
|
|
|
30
30
|
interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity> extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {
|
|
31
31
|
route: TRoute;
|
|
32
32
|
view?: RouteViewComponent<TRoute>;
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated use your own load fn for lazy load view
|
|
35
|
+
*/
|
|
33
36
|
loadView?: LoadViewFn<TRoute>;
|
|
34
37
|
/**
|
|
35
38
|
* Case when route is not opened
|
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';\nimport { type LoadableConfig, loadable } from 'react-simple-loadable';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\ntype LoadViewFn<TRoute extends AnyAbstractRouteEntity> = (\n route: TRoute,\n) => Promise<RouteViewComponent<TRoute>>;\n\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n loadView?: LoadViewFn<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 const loadViewFn = props.loadView as\n | (LoadViewFn<TRoute> & { _loadableComponent: any })\n | undefined;\n\n if (loadViewFn) {\n if (!loadViewFn._loadableComponent) {\n loadViewFn._loadableComponent = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n cache: false,\n });\n }\n Component = loadViewFn._loadableComponent;\n } else {\n Component = props.view;\n }\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';\nimport { type LoadableConfig, loadable } from 'react-simple-loadable';\n\nexport type RouteViewComponent<TRoute extends AnyAbstractRouteEntity> =\n React.ComponentType<RouteViewProps<TRoute>>;\n\ninterface RouteViewConfigWithoutRoute {\n children?: React.ReactNode | (() => React.ReactNode);\n}\n\ntype LoadViewFn<TRoute extends AnyAbstractRouteEntity> = (\n route: TRoute,\n) => Promise<RouteViewComponent<TRoute>>;\n\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n /**\n * @deprecated use your own load fn for lazy load view\n */\n loadView?: LoadViewFn<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 const loadViewFn = props.loadView as\n | (LoadViewFn<TRoute> & { _loadableComponent: any })\n | undefined;\n\n if (loadViewFn) {\n if (!loadViewFn._loadableComponent) {\n loadViewFn._loadableComponent = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n cache: false,\n });\n }\n Component = loadViewFn._loadableComponent;\n } else {\n Component = props.view;\n }\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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"}
|