mobx-route 0.20.0 → 0.20.2
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 +8 -1
- package/index.cjs.map +1 -1
- package/index.d.ts +2 -0
- package/index.js +8 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/react.cjs +20 -11
- package/react.cjs.map +1 -1
- package/react.js +20 -11
- package/react.js.map +1 -1
package/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ class Route {
|
|
|
60
60
|
mobx.observable(this, "children");
|
|
61
61
|
mobx.observable.ref(this, "parent");
|
|
62
62
|
mobx.observable.ref(this, "status");
|
|
63
|
+
mobx.computed(this, "isOpening");
|
|
63
64
|
mobx.action(this, "addChildren");
|
|
64
65
|
mobx.action(this, "confirmOpening");
|
|
65
66
|
mobx.action(this, "confirmClosing");
|
|
@@ -123,6 +124,9 @@ class Route {
|
|
|
123
124
|
}
|
|
124
125
|
return parsed;
|
|
125
126
|
}
|
|
127
|
+
get isOpening() {
|
|
128
|
+
return this.status === "opening";
|
|
129
|
+
}
|
|
126
130
|
/**
|
|
127
131
|
* Matched path segment for current URL.
|
|
128
132
|
*
|
|
@@ -174,7 +178,7 @@ class Route {
|
|
|
174
178
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend-path-config-route)
|
|
175
179
|
*/
|
|
176
180
|
extend(path, config) {
|
|
177
|
-
const { index, params, ...configFromCurrentRoute } = this.config;
|
|
181
|
+
const { index, params, exact, ...configFromCurrentRoute } = this.config;
|
|
178
182
|
const extendedChild = new Route(`${this.path}${path}`, {
|
|
179
183
|
...configFromCurrentRoute,
|
|
180
184
|
...config,
|
|
@@ -284,6 +288,9 @@ class Route {
|
|
|
284
288
|
return false;
|
|
285
289
|
}
|
|
286
290
|
if (typeof feedback === "object") {
|
|
291
|
+
mobx.runInAction(() => {
|
|
292
|
+
this.status = "open-confirmed";
|
|
293
|
+
});
|
|
287
294
|
return Object.assign(trx, feedback);
|
|
288
295
|
}
|
|
289
296
|
}
|
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 type History,\n type IQueryParams,\n isObservableHistory,\n QueryParams,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nlet localHistory: History | undefined;\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update) => {\n if (localHistory && update?.history && isObservableHistory(localHistory)) {\n localHistory.destroy();\n }\n\n let history: History;\n\n if (update?.history) {\n history = update.history;\n } else {\n history = localHistory = createBrowserHistory();\n }\n\n let queryParams: IQueryParams;\n\n if (update?.history && !update.queryParams) {\n queryParams = new QueryParams({ history });\n } else {\n if (update?.queryParams) {\n queryParams = update.queryParams;\n } else {\n queryParams = new QueryParams({ history });\n }\n }\n\n return {\n ...update,\n history,\n location,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { LinkedAbortController } from 'linked-abort-controller';\nimport {\n action,\n computed,\n makeObservable,\n observable,\n reaction,\n runInAction,\n} 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 type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n IRoute,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\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> implements IRoute<TPath, TInputParams, TOutputParams>\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 skipPathMatchCheck = 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-boolean)\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-boolean)\n */\n isHash: boolean;\n\n children: AnyRoute[] = [];\n\n constructor(\n public path: 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 computed(this, 'isPathMatched');\n computed(this, 'isOpened');\n computed.struct(this, 'data');\n computed.struct(this, 'params');\n computed(this, 'currentPath');\n computed(this, 'hasOpenedChildren');\n computed(this, 'isAbleToMergeQuery');\n computed(this, 'baseUrl');\n\n observable(this, 'children');\n observable.ref(this, 'parent');\n observable.ref(this, 'status');\n action(this, 'addChildren');\n action(this, 'confirmOpening');\n action(this, 'confirmClosing');\n action(this, 'removeChildren');\n\n makeObservable(this);\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.path === '' || this.path === '/') &&\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 * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#currentpath-parsedpathname-null)\n */\n get currentPath(): 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-parsedpathparams-null)\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-boolean)\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.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-path-config-route)\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 path: 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, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\n >(`${this.path}${path}`, {\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-boolean)\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 const path = this._compiler(this.processParams(urlCreateParams.params));\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-args)\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-args)\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 const isConfirmed = await this.confirmOpening(trx);\n\n if (!isConfirmed) {\n return;\n }\n\n this.skipPathMatchCheck = true;\n\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 protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.path, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n this.status = 'opening';\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 return false;\n }\n\n if (typeof feedback === 'object') {\n return Object.assign(trx, feedback);\n }\n }\n\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n return true;\n }\n\n protected confirmClosing() {\n this.status = 'closed';\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 (this.skipPathMatchCheck) {\n // after open\n this.skipPathMatchCheck = false;\n return;\n }\n\n if (isPathMathched) {\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 };\n\n const nextTrxOrConfirmed = await this.confirmOpening(trx);\n\n if (!nextTrxOrConfirmed) {\n return;\n }\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n\n if (typeof nextTrxOrConfirmed === 'object') {\n if (nextTrxOrConfirmed.replace) {\n this.history.replace(\n nextTrxOrConfirmed.url,\n nextTrxOrConfirmed.state,\n );\n } else {\n this.history.push(nextTrxOrConfirmed.url, nextTrxOrConfirmed.state);\n }\n }\n\n return;\n } else {\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, makeObservable, observable } from 'mobx';\n\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\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 computed.struct(this, 'isOpened');\n computed.struct(this, 'indexRoute');\n observable.shallow(this, 'routes');\n makeObservable(this);\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-boolean)\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-route-undefined)\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-args-any-void)\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, makeObservable } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\n\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\n\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\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 computed.struct(this, 'location');\n\n makeObservable(this);\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 {\n action,\n computed,\n makeObservable,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\n\nimport { routeConfig } from '../config/index.js';\n\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n} from './virtual-route.types.js';\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 protected abortController: AbortController;\n query: IQueryParams;\n params: TParams | null;\n\n private isLocalOpened: boolean;\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n private reactionDisposer: Maybe<VoidFunction>;\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.isLocalOpened = this.openChecker?.(this) ?? false;\n\n observable(this, 'params');\n observable.ref(this, 'isLocalOpened');\n observable.ref(this, '_isOpened');\n computed.struct(this, 'isOpened');\n action(this, 'setOpenChecker');\n action(this, 'open');\n action(this, 'close');\n makeObservable(this);\n\n onBecomeObserved(this, 'isOpened', () => {\n if (!config.afterOpen && !config.afterClose) {\n return;\n }\n\n this.reactionDisposer = reaction(\n () => this.isOpened,\n this.processOpenedState,\n {\n signal: this.abortController.signal,\n fireImmediately: true,\n },\n );\n });\n onBecomeUnobserved(this, 'isOpened', () => {\n this.reactionDisposer?.();\n this.reactionDisposer = undefined;\n });\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened-boolean)\n */\n get isOpened() {\n const isOuterOpened = this.openChecker == null || this.openChecker(this);\n return this.isLocalOpened && isOuterOpened;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker-openchecker-void)\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-params-extraparams-query-replace-promise-void)\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] ?? {}) as unknown as TParams;\n const extraParams: Maybe<VirtualOpenExtraParams> = args[1];\n\n if (this.config.beforeOpen) {\n const beforeOpenResult = await this.config.beforeOpen(params, this);\n if (beforeOpenResult === false) {\n return;\n }\n }\n\n if (this.config.open == null) {\n runInAction(() => {\n this.isLocalOpened = true;\n });\n } else {\n const result = await this.config.open(params, this);\n // because result can return void so this is truthy for opening state\n runInAction(() => {\n this.isLocalOpened = result !== false;\n });\n }\n\n if (!this.isLocalOpened) {\n return;\n }\n\n if (extraParams?.query) {\n this.query.update(extraParams.query, extraParams.replace);\n }\n\n runInAction(() => {\n this.params = params;\n });\n\n if (!this.reactionDisposer && this.isOpened) {\n this.config.afterOpen?.(this.params!, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close-void)\n */\n close() {\n if (this.config.close == null) {\n this.isLocalOpened = false;\n } else {\n const result = this.config.close(this);\n // because result can return void so this is truthy for opening state\n this.isLocalOpened = result !== false;\n }\n\n this.params = null;\n }\n\n private firstOpenedStateCheck = true;\n private processOpenedState = (isOpened: boolean) => {\n if (this.firstOpenedStateCheck) {\n this.firstOpenedStateCheck = false;\n // ignore first 'afterClose' callback call\n if (!isOpened) {\n return;\n }\n }\n\n if (isOpened) {\n this.config.afterOpen?.(this.params!, this);\n } else {\n this.config.afterClose?.();\n }\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","QueryParams","LinkedAbortController","computed","observable","action","makeObservable","reaction","match","compile","buildSearchString","parse","runInAction","callFunction","onBecomeObserved","onBecomeUnobserved"],"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 type History,\n type IQueryParams,\n isObservableHistory,\n QueryParams,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nlet localHistory: History | undefined;\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update) => {\n if (localHistory && update?.history && isObservableHistory(localHistory)) {\n localHistory.destroy();\n }\n\n let history: History;\n\n if (update?.history) {\n history = update.history;\n } else {\n history = localHistory = createBrowserHistory();\n }\n\n let queryParams: IQueryParams;\n\n if (update?.history && !update.queryParams) {\n queryParams = new QueryParams({ history });\n } else {\n if (update?.queryParams) {\n queryParams = update.queryParams;\n } else {\n queryParams = new QueryParams({ history });\n }\n }\n\n return {\n ...update,\n history,\n location,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { LinkedAbortController } from 'linked-abort-controller';\nimport {\n action,\n computed,\n makeObservable,\n observable,\n reaction,\n runInAction,\n} 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 type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n IRoute,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\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> implements IRoute<TPath, TInputParams, TOutputParams>\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 skipPathMatchCheck = 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-boolean)\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-boolean)\n */\n isHash: boolean;\n\n children: AnyRoute[] = [];\n\n constructor(\n public path: 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 computed(this, 'isPathMatched');\n computed(this, 'isOpened');\n computed.struct(this, 'data');\n computed.struct(this, 'params');\n computed(this, 'currentPath');\n computed(this, 'hasOpenedChildren');\n computed(this, 'isAbleToMergeQuery');\n computed(this, 'baseUrl');\n\n observable(this, 'children');\n observable.ref(this, 'parent');\n observable.ref(this, 'status');\n computed(this, 'isOpening');\n action(this, 'addChildren');\n action(this, 'confirmOpening');\n action(this, 'confirmClosing');\n action(this, 'removeChildren');\n\n makeObservable(this);\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.path === '' || this.path === '/') &&\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 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#currentpath-parsedpathname-null)\n */\n get currentPath(): 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-parsedpathparams-null)\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-boolean)\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.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-path-config-route)\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 path: 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.path}${path}`, {\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-boolean)\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 const path = this._compiler(this.processParams(urlCreateParams.params));\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-args)\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-args)\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 const isConfirmed = await this.confirmOpening(trx);\n\n if (!isConfirmed) {\n return;\n }\n\n this.skipPathMatchCheck = true;\n\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 protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.path, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n this.status = 'opening';\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 return false;\n }\n\n if (typeof feedback === 'object') {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n return Object.assign(trx, feedback);\n }\n }\n\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n return true;\n }\n\n protected confirmClosing() {\n this.status = 'closed';\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 (this.skipPathMatchCheck) {\n // after open\n this.skipPathMatchCheck = false;\n return;\n }\n\n if (isPathMathched) {\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 };\n\n const nextTrxOrConfirmed = await this.confirmOpening(trx);\n\n if (!nextTrxOrConfirmed) {\n return;\n }\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n\n if (typeof nextTrxOrConfirmed === 'object') {\n if (nextTrxOrConfirmed.replace) {\n this.history.replace(\n nextTrxOrConfirmed.url,\n nextTrxOrConfirmed.state,\n );\n } else {\n this.history.push(nextTrxOrConfirmed.url, nextTrxOrConfirmed.state);\n }\n }\n\n return;\n } else {\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, makeObservable, observable } from 'mobx';\n\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\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 computed.struct(this, 'isOpened');\n computed.struct(this, 'indexRoute');\n observable.shallow(this, 'routes');\n makeObservable(this);\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-boolean)\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-route-undefined)\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-args-any-void)\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, makeObservable } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\n\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\n\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\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 computed.struct(this, 'location');\n\n makeObservable(this);\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 {\n action,\n computed,\n makeObservable,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\n\nimport { routeConfig } from '../config/index.js';\n\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n} from './virtual-route.types.js';\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 protected abortController: AbortController;\n query: IQueryParams;\n params: TParams | null;\n\n private isLocalOpened: boolean;\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n private reactionDisposer: Maybe<VoidFunction>;\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.isLocalOpened = this.openChecker?.(this) ?? false;\n\n observable(this, 'params');\n observable.ref(this, 'isLocalOpened');\n observable.ref(this, '_isOpened');\n computed.struct(this, 'isOpened');\n action(this, 'setOpenChecker');\n action(this, 'open');\n action(this, 'close');\n makeObservable(this);\n\n onBecomeObserved(this, 'isOpened', () => {\n if (!config.afterOpen && !config.afterClose) {\n return;\n }\n\n this.reactionDisposer = reaction(\n () => this.isOpened,\n this.processOpenedState,\n {\n signal: this.abortController.signal,\n fireImmediately: true,\n },\n );\n });\n onBecomeUnobserved(this, 'isOpened', () => {\n this.reactionDisposer?.();\n this.reactionDisposer = undefined;\n });\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened-boolean)\n */\n get isOpened() {\n const isOuterOpened = this.openChecker == null || this.openChecker(this);\n return this.isLocalOpened && isOuterOpened;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker-openchecker-void)\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-params-extraparams-query-replace-promise-void)\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] ?? {}) as unknown as TParams;\n const extraParams: Maybe<VirtualOpenExtraParams> = args[1];\n\n if (this.config.beforeOpen) {\n const beforeOpenResult = await this.config.beforeOpen(params, this);\n if (beforeOpenResult === false) {\n return;\n }\n }\n\n if (this.config.open == null) {\n runInAction(() => {\n this.isLocalOpened = true;\n });\n } else {\n const result = await this.config.open(params, this);\n // because result can return void so this is truthy for opening state\n runInAction(() => {\n this.isLocalOpened = result !== false;\n });\n }\n\n if (!this.isLocalOpened) {\n return;\n }\n\n if (extraParams?.query) {\n this.query.update(extraParams.query, extraParams.replace);\n }\n\n runInAction(() => {\n this.params = params;\n });\n\n if (!this.reactionDisposer && this.isOpened) {\n this.config.afterOpen?.(this.params!, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close-void)\n */\n close() {\n if (this.config.close == null) {\n this.isLocalOpened = false;\n } else {\n const result = this.config.close(this);\n // because result can return void so this is truthy for opening state\n this.isLocalOpened = result !== false;\n }\n\n this.params = null;\n }\n\n private firstOpenedStateCheck = true;\n private processOpenedState = (isOpened: boolean) => {\n if (this.firstOpenedStateCheck) {\n this.firstOpenedStateCheck = false;\n // ignore first 'afterClose' callback call\n if (!isOpened) {\n return;\n }\n }\n\n if (isOpened) {\n this.config.afterOpen?.(this.params!, this);\n } else {\n this.config.afterClose?.();\n }\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","QueryParams","LinkedAbortController","computed","observable","action","makeObservable","reaction","match","compile","buildSearchString","parse","runInAction","callFunction","onBecomeObserved","onBecomeUnobserved"],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -212,6 +212,7 @@ interface RouteConfiguration<TPath extends string, TInputParams extends InputPat
|
|
|
212
212
|
type AnyRoute = IRoute;
|
|
213
213
|
interface IRoute<TPath extends string = string, TInputParams extends InputPathParams<TPath> = InputPathParams<TPath>, TOutputParams extends AnyObject = ParsedPathParams<TPath>> {
|
|
214
214
|
isOpened: boolean;
|
|
215
|
+
isOpening: boolean;
|
|
215
216
|
path: TPath;
|
|
216
217
|
/**
|
|
217
218
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#hasopenedchildren-boolean)
|
|
@@ -308,6 +309,7 @@ declare class Route<TPath extends string, TInputParams extends InputPathParams<T
|
|
|
308
309
|
constructor(path: TPath, config?: RouteConfiguration<TPath, TInputParams, TOutputParams, TParentRoute>);
|
|
309
310
|
protected get baseUrl(): string | undefined;
|
|
310
311
|
protected get parsedPathData(): ParsedPathData<TPath> | null;
|
|
312
|
+
get isOpening(): boolean;
|
|
311
313
|
/**
|
|
312
314
|
* Matched path segment for current URL.
|
|
313
315
|
*
|
package/index.js
CHANGED
|
@@ -59,6 +59,7 @@ class Route {
|
|
|
59
59
|
observable(this, "children");
|
|
60
60
|
observable.ref(this, "parent");
|
|
61
61
|
observable.ref(this, "status");
|
|
62
|
+
computed(this, "isOpening");
|
|
62
63
|
action(this, "addChildren");
|
|
63
64
|
action(this, "confirmOpening");
|
|
64
65
|
action(this, "confirmClosing");
|
|
@@ -122,6 +123,9 @@ class Route {
|
|
|
122
123
|
}
|
|
123
124
|
return parsed;
|
|
124
125
|
}
|
|
126
|
+
get isOpening() {
|
|
127
|
+
return this.status === "opening";
|
|
128
|
+
}
|
|
125
129
|
/**
|
|
126
130
|
* Matched path segment for current URL.
|
|
127
131
|
*
|
|
@@ -173,7 +177,7 @@ class Route {
|
|
|
173
177
|
* [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#extend-path-config-route)
|
|
174
178
|
*/
|
|
175
179
|
extend(path, config) {
|
|
176
|
-
const { index, params, ...configFromCurrentRoute } = this.config;
|
|
180
|
+
const { index, params, exact, ...configFromCurrentRoute } = this.config;
|
|
177
181
|
const extendedChild = new Route(`${this.path}${path}`, {
|
|
178
182
|
...configFromCurrentRoute,
|
|
179
183
|
...config,
|
|
@@ -283,6 +287,9 @@ class Route {
|
|
|
283
287
|
return false;
|
|
284
288
|
}
|
|
285
289
|
if (typeof feedback === "object") {
|
|
290
|
+
runInAction(() => {
|
|
291
|
+
this.status = "open-confirmed";
|
|
292
|
+
});
|
|
286
293
|
return Object.assign(trx, feedback);
|
|
287
294
|
}
|
|
288
295
|
}
|
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 type History,\n type IQueryParams,\n isObservableHistory,\n QueryParams,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nlet localHistory: History | undefined;\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update) => {\n if (localHistory && update?.history && isObservableHistory(localHistory)) {\n localHistory.destroy();\n }\n\n let history: History;\n\n if (update?.history) {\n history = update.history;\n } else {\n history = localHistory = createBrowserHistory();\n }\n\n let queryParams: IQueryParams;\n\n if (update?.history && !update.queryParams) {\n queryParams = new QueryParams({ history });\n } else {\n if (update?.queryParams) {\n queryParams = update.queryParams;\n } else {\n queryParams = new QueryParams({ history });\n }\n }\n\n return {\n ...update,\n history,\n location,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { LinkedAbortController } from 'linked-abort-controller';\nimport {\n action,\n computed,\n makeObservable,\n observable,\n reaction,\n runInAction,\n} 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 type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n IRoute,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\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> implements IRoute<TPath, TInputParams, TOutputParams>\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 skipPathMatchCheck = 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-boolean)\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-boolean)\n */\n isHash: boolean;\n\n children: AnyRoute[] = [];\n\n constructor(\n public path: 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 computed(this, 'isPathMatched');\n computed(this, 'isOpened');\n computed.struct(this, 'data');\n computed.struct(this, 'params');\n computed(this, 'currentPath');\n computed(this, 'hasOpenedChildren');\n computed(this, 'isAbleToMergeQuery');\n computed(this, 'baseUrl');\n\n observable(this, 'children');\n observable.ref(this, 'parent');\n observable.ref(this, 'status');\n action(this, 'addChildren');\n action(this, 'confirmOpening');\n action(this, 'confirmClosing');\n action(this, 'removeChildren');\n\n makeObservable(this);\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.path === '' || this.path === '/') &&\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 * Matched path segment for current URL.\n *\n * [**Documentation**](https://js2me.github.io/mobx-route/core/Route.html#currentpath-parsedpathname-null)\n */\n get currentPath(): 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-parsedpathparams-null)\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-boolean)\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.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-path-config-route)\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 path: 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, ...configFromCurrentRoute } = this.config;\n\n const extendedChild = new Route<\n ExtendedRoutePath,\n TInputParams & TExtendedInputParams,\n TExtendedOutputParams,\n ParentRoute\n >(`${this.path}${path}`, {\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-boolean)\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 const path = this._compiler(this.processParams(urlCreateParams.params));\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-args)\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-args)\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 const isConfirmed = await this.confirmOpening(trx);\n\n if (!isConfirmed) {\n return;\n }\n\n this.skipPathMatchCheck = true;\n\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 protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.path, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n this.status = 'opening';\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 return false;\n }\n\n if (typeof feedback === 'object') {\n return Object.assign(trx, feedback);\n }\n }\n\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n return true;\n }\n\n protected confirmClosing() {\n this.status = 'closed';\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 (this.skipPathMatchCheck) {\n // after open\n this.skipPathMatchCheck = false;\n return;\n }\n\n if (isPathMathched) {\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 };\n\n const nextTrxOrConfirmed = await this.confirmOpening(trx);\n\n if (!nextTrxOrConfirmed) {\n return;\n }\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n\n if (typeof nextTrxOrConfirmed === 'object') {\n if (nextTrxOrConfirmed.replace) {\n this.history.replace(\n nextTrxOrConfirmed.url,\n nextTrxOrConfirmed.state,\n );\n } else {\n this.history.push(nextTrxOrConfirmed.url, nextTrxOrConfirmed.state);\n }\n }\n\n return;\n } else {\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, makeObservable, observable } from 'mobx';\n\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\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 computed.struct(this, 'isOpened');\n computed.struct(this, 'indexRoute');\n observable.shallow(this, 'routes');\n makeObservable(this);\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-boolean)\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-route-undefined)\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-args-any-void)\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, makeObservable } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\n\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\n\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\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 computed.struct(this, 'location');\n\n makeObservable(this);\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 {\n action,\n computed,\n makeObservable,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\n\nimport { routeConfig } from '../config/index.js';\n\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n} from './virtual-route.types.js';\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 protected abortController: AbortController;\n query: IQueryParams;\n params: TParams | null;\n\n private isLocalOpened: boolean;\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n private reactionDisposer: Maybe<VoidFunction>;\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.isLocalOpened = this.openChecker?.(this) ?? false;\n\n observable(this, 'params');\n observable.ref(this, 'isLocalOpened');\n observable.ref(this, '_isOpened');\n computed.struct(this, 'isOpened');\n action(this, 'setOpenChecker');\n action(this, 'open');\n action(this, 'close');\n makeObservable(this);\n\n onBecomeObserved(this, 'isOpened', () => {\n if (!config.afterOpen && !config.afterClose) {\n return;\n }\n\n this.reactionDisposer = reaction(\n () => this.isOpened,\n this.processOpenedState,\n {\n signal: this.abortController.signal,\n fireImmediately: true,\n },\n );\n });\n onBecomeUnobserved(this, 'isOpened', () => {\n this.reactionDisposer?.();\n this.reactionDisposer = undefined;\n });\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened-boolean)\n */\n get isOpened() {\n const isOuterOpened = this.openChecker == null || this.openChecker(this);\n return this.isLocalOpened && isOuterOpened;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker-openchecker-void)\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-params-extraparams-query-replace-promise-void)\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] ?? {}) as unknown as TParams;\n const extraParams: Maybe<VirtualOpenExtraParams> = args[1];\n\n if (this.config.beforeOpen) {\n const beforeOpenResult = await this.config.beforeOpen(params, this);\n if (beforeOpenResult === false) {\n return;\n }\n }\n\n if (this.config.open == null) {\n runInAction(() => {\n this.isLocalOpened = true;\n });\n } else {\n const result = await this.config.open(params, this);\n // because result can return void so this is truthy for opening state\n runInAction(() => {\n this.isLocalOpened = result !== false;\n });\n }\n\n if (!this.isLocalOpened) {\n return;\n }\n\n if (extraParams?.query) {\n this.query.update(extraParams.query, extraParams.replace);\n }\n\n runInAction(() => {\n this.params = params;\n });\n\n if (!this.reactionDisposer && this.isOpened) {\n this.config.afterOpen?.(this.params!, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close-void)\n */\n close() {\n if (this.config.close == null) {\n this.isLocalOpened = false;\n } else {\n const result = this.config.close(this);\n // because result can return void so this is truthy for opening state\n this.isLocalOpened = result !== false;\n }\n\n this.params = null;\n }\n\n private firstOpenedStateCheck = true;\n private processOpenedState = (isOpened: boolean) => {\n if (this.firstOpenedStateCheck) {\n this.firstOpenedStateCheck = false;\n // ignore first 'afterClose' callback call\n if (!isOpened) {\n return;\n }\n }\n\n if (isOpened) {\n this.config.afterOpen?.(this.params!, this);\n } else {\n this.config.afterClose?.();\n }\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":[],"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 type History,\n type IQueryParams,\n isObservableHistory,\n QueryParams,\n} from 'mobx-location-history';\nimport { createGlobalDynamicConfig } from 'yummies/complex';\n\nimport type { RouteGlobalConfig } from './config.types.js';\n\nlet localHistory: History | undefined;\n\nexport const routeConfig = createGlobalDynamicConfig<RouteGlobalConfig>(\n (update) => {\n if (localHistory && update?.history && isObservableHistory(localHistory)) {\n localHistory.destroy();\n }\n\n let history: History;\n\n if (update?.history) {\n history = update.history;\n } else {\n history = localHistory = createBrowserHistory();\n }\n\n let queryParams: IQueryParams;\n\n if (update?.history && !update.queryParams) {\n queryParams = new QueryParams({ history });\n } else {\n if (update?.queryParams) {\n queryParams = update.queryParams;\n } else {\n queryParams = new QueryParams({ history });\n }\n }\n\n return {\n ...update,\n history,\n location,\n queryParams,\n };\n },\n Symbol.for('MOBX_ROUTE_CONFIG'),\n);\n","import { LinkedAbortController } from 'linked-abort-controller';\nimport {\n action,\n computed,\n makeObservable,\n observable,\n reaction,\n runInAction,\n} 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 type { AnyObject, IsPartial, Maybe } from 'yummies/types';\nimport { routeConfig } from '../config/index.js';\nimport type {\n AnyRoute,\n CreatedUrlOutputParams,\n InputPathParams,\n IRoute,\n NavigationTrx,\n ParsedPathData,\n ParsedPathParams,\n RouteConfiguration,\n RouteNavigateParams,\n UrlCreateParams,\n} from './route.types.js';\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> implements IRoute<TPath, TInputParams, TOutputParams>\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 skipPathMatchCheck = 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-boolean)\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-boolean)\n */\n isHash: boolean;\n\n children: AnyRoute[] = [];\n\n constructor(\n public path: 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 computed(this, 'isPathMatched');\n computed(this, 'isOpened');\n computed.struct(this, 'data');\n computed.struct(this, 'params');\n computed(this, 'currentPath');\n computed(this, 'hasOpenedChildren');\n computed(this, 'isAbleToMergeQuery');\n computed(this, 'baseUrl');\n\n observable(this, 'children');\n observable.ref(this, 'parent');\n observable.ref(this, 'status');\n computed(this, 'isOpening');\n action(this, 'addChildren');\n action(this, 'confirmOpening');\n action(this, 'confirmClosing');\n action(this, 'removeChildren');\n\n makeObservable(this);\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.path === '' || this.path === '/') &&\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 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#currentpath-parsedpathname-null)\n */\n get currentPath(): 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-parsedpathparams-null)\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-boolean)\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.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-path-config-route)\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 path: 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.path}${path}`, {\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-boolean)\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 const path = this._compiler(this.processParams(urlCreateParams.params));\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-args)\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-args)\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 const isConfirmed = await this.confirmOpening(trx);\n\n if (!isConfirmed) {\n return;\n }\n\n this.skipPathMatchCheck = true;\n\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 protected get tokenData() {\n if (!this._tokenData) {\n this._tokenData = parse(this.path, this.config.parseOptions);\n }\n return this._tokenData;\n }\n\n protected async confirmOpening(trx: NavigationTrx<TInputParams>) {\n this.status = 'opening';\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 return false;\n }\n\n if (typeof feedback === 'object') {\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n return Object.assign(trx, feedback);\n }\n }\n\n runInAction(() => {\n this.status = 'open-confirmed';\n });\n\n return true;\n }\n\n protected confirmClosing() {\n this.status = 'closed';\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 (this.skipPathMatchCheck) {\n // after open\n this.skipPathMatchCheck = false;\n return;\n }\n\n if (isPathMathched) {\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 };\n\n const nextTrxOrConfirmed = await this.confirmOpening(trx);\n\n if (!nextTrxOrConfirmed) {\n return;\n }\n\n this.config.afterOpen?.(this.parsedPathData!, this);\n\n if (typeof nextTrxOrConfirmed === 'object') {\n if (nextTrxOrConfirmed.replace) {\n this.history.replace(\n nextTrxOrConfirmed.url,\n nextTrxOrConfirmed.state,\n );\n } else {\n this.history.push(nextTrxOrConfirmed.url, nextTrxOrConfirmed.state);\n }\n }\n\n return;\n } else {\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, makeObservable, observable } from 'mobx';\n\nimport type {\n AbstractRouteGroup,\n AnyRouteEntity,\n RoutesCollection,\n} from './route-group.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\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 computed.struct(this, 'isOpened');\n computed.struct(this, 'indexRoute');\n observable.shallow(this, 'routes');\n makeObservable(this);\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-boolean)\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-route-undefined)\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-args-any-void)\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, makeObservable } from 'mobx';\nimport {\n buildSearchString,\n type History,\n type IQueryParams,\n} from 'mobx-location-history';\n\nimport { routeConfig } from '../config/index.js';\nimport type { RoutesCollection } from '../route-group/index.js';\n\nimport type {\n RouterConfiguration,\n RouterNavigateOptions,\n} from './router.types.js';\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 computed.struct(this, 'location');\n\n makeObservable(this);\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 {\n action,\n computed,\n makeObservable,\n observable,\n onBecomeObserved,\n onBecomeUnobserved,\n reaction,\n runInAction,\n} from 'mobx';\nimport type { IQueryParams } from 'mobx-location-history';\nimport { callFunction } from 'yummies/common';\nimport type { AnyObject, EmptyObject, IsPartial, Maybe } from 'yummies/types';\n\nimport { routeConfig } from '../config/index.js';\n\nimport type {\n AbstractVirtualRoute,\n VirtualOpenExtraParams,\n VirtualRouteConfiguration,\n} from './virtual-route.types.js';\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 protected abortController: AbortController;\n query: IQueryParams;\n params: TParams | null;\n\n private isLocalOpened: boolean;\n\n private openChecker: Maybe<VirtualRouteConfiguration<TParams>['checkOpened']>;\n private reactionDisposer: Maybe<VoidFunction>;\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.isLocalOpened = this.openChecker?.(this) ?? false;\n\n observable(this, 'params');\n observable.ref(this, 'isLocalOpened');\n observable.ref(this, '_isOpened');\n computed.struct(this, 'isOpened');\n action(this, 'setOpenChecker');\n action(this, 'open');\n action(this, 'close');\n makeObservable(this);\n\n onBecomeObserved(this, 'isOpened', () => {\n if (!config.afterOpen && !config.afterClose) {\n return;\n }\n\n this.reactionDisposer = reaction(\n () => this.isOpened,\n this.processOpenedState,\n {\n signal: this.abortController.signal,\n fireImmediately: true,\n },\n );\n });\n onBecomeUnobserved(this, 'isOpened', () => {\n this.reactionDisposer?.();\n this.reactionDisposer = undefined;\n });\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#isopened-boolean)\n */\n get isOpened() {\n const isOuterOpened = this.openChecker == null || this.openChecker(this);\n return this.isLocalOpened && isOuterOpened;\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#setopenchecker-openchecker-void)\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-params-extraparams-query-replace-promise-void)\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] ?? {}) as unknown as TParams;\n const extraParams: Maybe<VirtualOpenExtraParams> = args[1];\n\n if (this.config.beforeOpen) {\n const beforeOpenResult = await this.config.beforeOpen(params, this);\n if (beforeOpenResult === false) {\n return;\n }\n }\n\n if (this.config.open == null) {\n runInAction(() => {\n this.isLocalOpened = true;\n });\n } else {\n const result = await this.config.open(params, this);\n // because result can return void so this is truthy for opening state\n runInAction(() => {\n this.isLocalOpened = result !== false;\n });\n }\n\n if (!this.isLocalOpened) {\n return;\n }\n\n if (extraParams?.query) {\n this.query.update(extraParams.query, extraParams.replace);\n }\n\n runInAction(() => {\n this.params = params;\n });\n\n if (!this.reactionDisposer && this.isOpened) {\n this.config.afterOpen?.(this.params!, this);\n }\n }\n\n /**\n * [**Documentation**](https://js2me.github.io/mobx-route/core/VirtualRoute.html#close-void)\n */\n close() {\n if (this.config.close == null) {\n this.isLocalOpened = false;\n } else {\n const result = this.config.close(this);\n // because result can return void so this is truthy for opening state\n this.isLocalOpened = result !== false;\n }\n\n this.params = null;\n }\n\n private firstOpenedStateCheck = true;\n private processOpenedState = (isOpened: boolean) => {\n if (this.firstOpenedStateCheck) {\n this.firstOpenedStateCheck = false;\n // ignore first 'afterClose' callback call\n if (!isOpened) {\n return;\n }\n }\n\n if (isOpened) {\n this.config.afterOpen?.(this.params!, this);\n } else {\n this.config.afterClose?.();\n }\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":[],"mappings":"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"}
|
package/package.json
CHANGED
package/react.cjs
CHANGED
|
@@ -125,22 +125,31 @@ const RouteViewGroup = mobxReactLite.observer(
|
|
|
125
125
|
params,
|
|
126
126
|
...navigateParams
|
|
127
127
|
}) => {
|
|
128
|
-
let
|
|
128
|
+
let activeChildRouteNode = null;
|
|
129
129
|
let lastInactiveChildNode = null;
|
|
130
|
+
let hasRoutesInOpening = false;
|
|
130
131
|
const childNodes = Array.isArray(children) ? children : [children];
|
|
131
132
|
for (const childNode of childNodes) {
|
|
132
|
-
|
|
133
|
-
mobxRoute.isRouteEntity(childNode.props?.route)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
const isRouteChild = react.isValidElement(childNode) && // @ts-expect-error redundand checks better to wrap in this directive
|
|
134
|
+
mobxRoute.isRouteEntity(childNode.props?.route);
|
|
135
|
+
if (isRouteChild) {
|
|
136
|
+
const route = childNode.props.route;
|
|
137
|
+
if (route.isOpened) {
|
|
138
|
+
activeChildRouteNode = childNode;
|
|
139
|
+
break;
|
|
140
|
+
} else {
|
|
141
|
+
if (route.isOpening) {
|
|
142
|
+
hasRoutesInOpening = true;
|
|
143
|
+
}
|
|
144
|
+
lastInactiveChildNode = childNode;
|
|
145
|
+
}
|
|
137
146
|
} else {
|
|
138
147
|
lastInactiveChildNode = childNode;
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
|
-
const hasActiveChildNode = !!
|
|
150
|
+
const hasActiveChildNode = !!activeChildRouteNode;
|
|
142
151
|
react.useEffect(() => {
|
|
143
|
-
if (!hasActiveChildNode && otherwiseNavigation) {
|
|
152
|
+
if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {
|
|
144
153
|
if (typeof otherwiseNavigation === "string") {
|
|
145
154
|
const history = mobxRoute.routeConfig.get().history;
|
|
146
155
|
const url = `${otherwiseNavigation}${mobxRoute.buildSearchString(navigateParams.query || {})}`;
|
|
@@ -153,11 +162,11 @@ const RouteViewGroup = mobxReactLite.observer(
|
|
|
153
162
|
otherwiseNavigation.open(params, navigateParams);
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
|
-
}, [hasActiveChildNode, otherwiseNavigation]);
|
|
157
|
-
if (otherwiseNavigation && !
|
|
165
|
+
}, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);
|
|
166
|
+
if (otherwiseNavigation && !activeChildRouteNode) {
|
|
158
167
|
return null;
|
|
159
168
|
}
|
|
160
|
-
const resultNodeToRender =
|
|
169
|
+
const resultNodeToRender = activeChildRouteNode ?? lastInactiveChildNode ?? null;
|
|
161
170
|
if (Layout) {
|
|
162
171
|
return /* @__PURE__ */ jsxRuntime.jsx(Layout, { children: resultNodeToRender });
|
|
163
172
|
}
|
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 } 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['path']>> extends true\n ? {\n params?: InputPathParams<TRoute['path']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['path']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: 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 >(\n (\n {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n ...outerAnchorProps\n },\n ref,\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 {\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, 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 (!event.defaultPrevented) {\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 ),\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 { useRef } from 'react';\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\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n loadView?: (route: TRoute) => Promise<RouteViewComponent<TRoute>>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n // @ts-expect-error redundand pass first argument\n const lazyViewComponentRef = useRef<React.ComponentType<any>>();\n\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 if (props.loadView) {\n if (!lazyViewComponentRef.current) {\n lazyViewComponentRef.current = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n });\n }\n Component = lazyViewComponentRef.current;\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 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}\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 // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n if (\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n childNode.props.route.isOpened\n ) {\n activeChildNode = childNode;\n break;\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && 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, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildNode) {\n return null;\n }\n\n const resultNodeToRender = activeChildNode ?? 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 } 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['path']>> extends true\n ? {\n params?: InputPathParams<TRoute['path']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['path']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: 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 >(\n (\n {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n ...outerAnchorProps\n },\n ref,\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 {\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, 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 (!event.defaultPrevented) {\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 ),\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 { useRef } from 'react';\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\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n loadView?: (route: TRoute) => Promise<RouteViewComponent<TRoute>>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n // @ts-expect-error redundand pass first argument\n const lazyViewComponentRef = useRef<React.ComponentType<any>>();\n\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 if (props.loadView) {\n if (!lazyViewComponentRef.current) {\n lazyViewComponentRef.current = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n });\n }\n Component = lazyViewComponentRef.current;\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}\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 // @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 break;\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.js
CHANGED
|
@@ -123,22 +123,31 @@ const RouteViewGroup = observer(
|
|
|
123
123
|
params,
|
|
124
124
|
...navigateParams
|
|
125
125
|
}) => {
|
|
126
|
-
let
|
|
126
|
+
let activeChildRouteNode = null;
|
|
127
127
|
let lastInactiveChildNode = null;
|
|
128
|
+
let hasRoutesInOpening = false;
|
|
128
129
|
const childNodes = Array.isArray(children) ? children : [children];
|
|
129
130
|
for (const childNode of childNodes) {
|
|
130
|
-
|
|
131
|
-
isRouteEntity(childNode.props?.route)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
const isRouteChild = isValidElement(childNode) && // @ts-expect-error redundand checks better to wrap in this directive
|
|
132
|
+
isRouteEntity(childNode.props?.route);
|
|
133
|
+
if (isRouteChild) {
|
|
134
|
+
const route = childNode.props.route;
|
|
135
|
+
if (route.isOpened) {
|
|
136
|
+
activeChildRouteNode = childNode;
|
|
137
|
+
break;
|
|
138
|
+
} else {
|
|
139
|
+
if (route.isOpening) {
|
|
140
|
+
hasRoutesInOpening = true;
|
|
141
|
+
}
|
|
142
|
+
lastInactiveChildNode = childNode;
|
|
143
|
+
}
|
|
135
144
|
} else {
|
|
136
145
|
lastInactiveChildNode = childNode;
|
|
137
146
|
}
|
|
138
147
|
}
|
|
139
|
-
const hasActiveChildNode = !!
|
|
148
|
+
const hasActiveChildNode = !!activeChildRouteNode;
|
|
140
149
|
useEffect(() => {
|
|
141
|
-
if (!hasActiveChildNode && otherwiseNavigation) {
|
|
150
|
+
if (!hasActiveChildNode && !hasRoutesInOpening && otherwiseNavigation) {
|
|
142
151
|
if (typeof otherwiseNavigation === "string") {
|
|
143
152
|
const history = routeConfig.get().history;
|
|
144
153
|
const url = `${otherwiseNavigation}${buildSearchString(navigateParams.query || {})}`;
|
|
@@ -151,11 +160,11 @@ const RouteViewGroup = observer(
|
|
|
151
160
|
otherwiseNavigation.open(params, navigateParams);
|
|
152
161
|
}
|
|
153
162
|
}
|
|
154
|
-
}, [hasActiveChildNode, otherwiseNavigation]);
|
|
155
|
-
if (otherwiseNavigation && !
|
|
163
|
+
}, [hasActiveChildNode, hasRoutesInOpening, otherwiseNavigation]);
|
|
164
|
+
if (otherwiseNavigation && !activeChildRouteNode) {
|
|
156
165
|
return null;
|
|
157
166
|
}
|
|
158
|
-
const resultNodeToRender =
|
|
167
|
+
const resultNodeToRender = activeChildRouteNode ?? lastInactiveChildNode ?? null;
|
|
159
168
|
if (Layout) {
|
|
160
169
|
return /* @__PURE__ */ jsx(Layout, { children: resultNodeToRender });
|
|
161
170
|
}
|
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 } 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['path']>> extends true\n ? {\n params?: InputPathParams<TRoute['path']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['path']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: 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 >(\n (\n {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n ...outerAnchorProps\n },\n ref,\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 {\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, 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 (!event.defaultPrevented) {\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 ),\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 { useRef } from 'react';\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\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n loadView?: (route: TRoute) => Promise<RouteViewComponent<TRoute>>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n // @ts-expect-error redundand pass first argument\n const lazyViewComponentRef = useRef<React.ComponentType<any>>();\n\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 if (props.loadView) {\n if (!lazyViewComponentRef.current) {\n lazyViewComponentRef.current = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n });\n }\n Component = lazyViewComponentRef.current;\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 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}\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 // @ts-expect-error\n params,\n ...navigateParams\n }: RouteViewGroupProps<TRoute>) => {\n let activeChildNode: React.ReactNode = null;\n let lastInactiveChildNode: React.ReactNode = null;\n\n const childNodes: React.ReactNode[] = Array.isArray(children)\n ? children\n : [children];\n\n for (const childNode of childNodes) {\n if (\n isValidElement(childNode) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n isRouteEntity(childNode.props?.route) &&\n // @ts-expect-error redundand checks better to wrap in this directive\n childNode.props.route.isOpened\n ) {\n activeChildNode = childNode;\n break;\n } else {\n lastInactiveChildNode = childNode;\n }\n }\n\n const hasActiveChildNode = !!activeChildNode;\n\n useEffect(() => {\n if (!hasActiveChildNode && 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, otherwiseNavigation]);\n\n if (otherwiseNavigation && !activeChildNode) {\n return null;\n }\n\n const resultNodeToRender = activeChildNode ?? 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 } 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['path']>> extends true\n ? {\n params?: InputPathParams<TRoute['path']> | null | undefined;\n }\n : { params: InputPathParams<TRoute['path']> });\n\ntype LinkSimpleRouteProps =\n | {\n to: string;\n }\n | {\n href: 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 >(\n (\n {\n to,\n href: outerHref,\n mergeQuery,\n asChild,\n children,\n params,\n // route navigate params\n query,\n replace,\n state,\n ...outerAnchorProps\n },\n ref,\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 {\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, 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 (!event.defaultPrevented) {\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 ),\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 { useRef } from 'react';\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\nexport interface RouteViewConfigWithRoute<TRoute extends AnyAbstractRouteEntity>\n extends Pick<LoadableConfig, 'loading' | 'preload' | 'throwOnError'> {\n route: TRoute;\n view?: RouteViewComponent<TRoute>;\n loadView?: (route: TRoute) => Promise<RouteViewComponent<TRoute>>;\n /**\n * Case when route is not opened\n */\n fallback?: React.ReactNode;\n children?:\n | React.ReactNode\n | ((\n params: RouteViewProps<TRoute>['params'],\n route: TRoute,\n ) => React.ReactNode);\n}\n\nexport type RouteViewConfig<TRoute extends AnyAbstractRouteEntity> =\n | RouteViewConfigWithRoute<TRoute>\n | RouteViewConfigWithoutRoute;\n\nexport type RouteViewProps<TRoute extends AnyAbstractRouteEntity> = {\n children?: React.ReactNode;\n params: TRoute extends AnyRoute\n ? Exclude<TRoute['params'], null | undefined>\n : TRoute extends AnyVirtualRoute\n ? TRoute['params']\n : never;\n};\n\ntype RouteViewBaseComponent = <TRoute extends AnyAbstractRouteEntity>(\n props: RouteViewConfig<TRoute>,\n) => React.ReactNode;\n\nfunction RouteViewBase<TRoute extends AnyAbstractRouteEntity>(\n props: Readonly<RouteViewConfig<TRoute>>,\n): React.ReactNode {\n // @ts-expect-error redundand pass first argument\n const lazyViewComponentRef = useRef<React.ComponentType<any>>();\n\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 if (props.loadView) {\n if (!lazyViewComponentRef.current) {\n lazyViewComponentRef.current = loadable({\n load: () => props.loadView!(props.route),\n loading: props.loading,\n preload: props.preload,\n throwOnError: props.throwOnError,\n });\n }\n Component = lazyViewComponentRef.current;\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}\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 // @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 break;\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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"}
|